mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-10-30 03:27:44 +00:00 
			
		
		
		
	Migrate inference to next solver
This commit is contained in:
		
							parent
							
								
									2b2d9d8f88
								
							
						
					
					
						commit
						d1288f6353
					
				
					 90 changed files with 4560 additions and 4904 deletions
				
			
		|  | @ -18,7 +18,7 @@ use base_db::salsa; | |||
| use either::Either; | ||||
| use hir_def::{ | ||||
|     AdtId, AssocItemId, CallableDefId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId, | ||||
|     ItemContainerId, LocalFieldId, Lookup, ModuleDefId, StructId, TraitId, VariantId, | ||||
|     LocalFieldId, ModuleDefId, StructId, TraitId, VariantId, | ||||
|     expr_store::{ | ||||
|         Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, HygieneId, | ||||
|         lower::ExprCollector, | ||||
|  | @ -36,9 +36,10 @@ use hir_expand::{ | |||
|     mod_path::{ModPath, PathKind, path}, | ||||
|     name::{AsName, Name}, | ||||
| }; | ||||
| use hir_ty::next_solver::GenericArgs; | ||||
| use hir_ty::{ | ||||
|     Adjustment, AliasTy, InferenceResult, Interner, LifetimeElisionKind, ProjectionTy, | ||||
|     Substitution, ToChalk, TraitEnvironment, Ty, TyExt, TyKind, TyLoweringContext, | ||||
|     Substitution, ToChalk, TraitEnvironment, Ty, TyKind, TyLoweringContext, | ||||
|     diagnostics::{ | ||||
|         InsideUnsafeBlock, record_literal_missing_fields, record_pattern_missing_fields, | ||||
|         unsafe_operations, | ||||
|  | @ -67,16 +68,16 @@ use triomphe::Arc; | |||
| pub(crate) struct SourceAnalyzer<'db> { | ||||
|     pub(crate) file_id: HirFileId, | ||||
|     pub(crate) resolver: Resolver<'db>, | ||||
|     pub(crate) body_or_sig: Option<BodyOrSig>, | ||||
|     pub(crate) body_or_sig: Option<BodyOrSig<'db>>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub(crate) enum BodyOrSig { | ||||
| pub(crate) enum BodyOrSig<'db> { | ||||
|     Body { | ||||
|         def: DefWithBodyId, | ||||
|         body: Arc<Body>, | ||||
|         source_map: Arc<BodySourceMap>, | ||||
|         infer: Option<Arc<InferenceResult>>, | ||||
|         infer: Option<Arc<InferenceResult<'db>>>, | ||||
|     }, | ||||
|     // To be folded into body once it is considered one
 | ||||
|     VariantFields { | ||||
|  | @ -116,7 +117,7 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         def: DefWithBodyId, | ||||
|         node @ InFile { file_id, .. }: InFile<&SyntaxNode>, | ||||
|         offset: Option<TextSize>, | ||||
|         infer: Option<Arc<InferenceResult>>, | ||||
|         infer: Option<Arc<InferenceResult<'db>>>, | ||||
|     ) -> SourceAnalyzer<'db> { | ||||
|         let (body, source_map) = db.body_with_source_map(def); | ||||
|         let scopes = db.expr_scopes(def); | ||||
|  | @ -182,7 +183,9 @@ impl<'db> SourceAnalyzer<'db> { | |||
|     } | ||||
| 
 | ||||
|     // FIXME: Remove this
 | ||||
|     fn body_(&self) -> Option<(DefWithBodyId, &Body, &BodySourceMap, Option<&InferenceResult>)> { | ||||
|     fn body_( | ||||
|         &self, | ||||
|     ) -> Option<(DefWithBodyId, &Body, &BodySourceMap, Option<&InferenceResult<'db>>)> { | ||||
|         self.body_or_sig.as_ref().and_then(|it| match it { | ||||
|             BodyOrSig::Body { def, body, source_map, infer } => { | ||||
|                 Some((*def, &**body, &**source_map, infer.as_deref())) | ||||
|  | @ -191,7 +194,7 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     fn infer(&self) -> Option<&InferenceResult> { | ||||
|     fn infer(&self) -> Option<&InferenceResult<'db>> { | ||||
|         self.body_or_sig.as_ref().and_then(|it| match it { | ||||
|             BodyOrSig::Sig { .. } => None, | ||||
|             BodyOrSig::VariantFields { .. } => None, | ||||
|  | @ -250,7 +253,7 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         if let Pat::Bind { id, .. } = self.store()?[pat_id.as_pat()?] { Some(id) } else { None } | ||||
|     } | ||||
| 
 | ||||
|     pub(crate) fn expr_adjustments(&self, expr: &ast::Expr) -> Option<&[Adjustment]> { | ||||
|     pub(crate) fn expr_adjustments(&self, expr: &ast::Expr) -> Option<&[Adjustment<'db>]> { | ||||
|         // It is safe to omit destructuring assignments here because they have no adjustments (neither
 | ||||
|         // expressions nor patterns).
 | ||||
|         let expr_id = self.expr_id(expr.clone())?.as_expr()?; | ||||
|  | @ -288,9 +291,11 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         let coerced = expr_id | ||||
|             .as_expr() | ||||
|             .and_then(|expr_id| infer.expr_adjustment(expr_id)) | ||||
|             .and_then(|adjusts| adjusts.last().map(|adjust| adjust.target.clone())); | ||||
|         let ty = infer[expr_id].clone(); | ||||
|         let mk_ty = |ty| Type::new_with_resolver(db, &self.resolver, ty); | ||||
|             .and_then(|adjusts| adjusts.last().map(|adjust| adjust.target)); | ||||
|         let ty = infer[expr_id]; | ||||
|         let mk_ty = |ty: hir_ty::next_solver::Ty<'_>| { | ||||
|             Type::new_with_resolver(db, &self.resolver, ty.to_chalk(DbInterner::conjure())) | ||||
|         }; | ||||
|         Some((mk_ty(ty), coerced.map(mk_ty))) | ||||
|     } | ||||
| 
 | ||||
|  | @ -311,8 +316,10 @@ impl<'db> SourceAnalyzer<'db> { | |||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         let ty = infer[expr_or_pat_id].clone(); | ||||
|         let mk_ty = |ty| Type::new_with_resolver(db, &self.resolver, ty); | ||||
|         let ty = infer[expr_or_pat_id]; | ||||
|         let mk_ty = |ty: hir_ty::next_solver::Ty<'db>| { | ||||
|             Type::new_with_resolver(db, &self.resolver, ty.to_chalk(DbInterner::conjure())) | ||||
|         }; | ||||
|         Some((mk_ty(ty), coerced.map(mk_ty))) | ||||
|     } | ||||
| 
 | ||||
|  | @ -323,8 +330,10 @@ impl<'db> SourceAnalyzer<'db> { | |||
|     ) -> Option<Type<'db>> { | ||||
|         let binding_id = self.binding_id_of_pat(pat)?; | ||||
|         let infer = self.infer()?; | ||||
|         let ty = infer[binding_id].clone(); | ||||
|         let mk_ty = |ty| Type::new_with_resolver(db, &self.resolver, ty); | ||||
|         let ty = infer[binding_id]; | ||||
|         let mk_ty = |ty: hir_ty::next_solver::Ty<'db>| { | ||||
|             Type::new_with_resolver(db, &self.resolver, ty.to_chalk(DbInterner::conjure())) | ||||
|         }; | ||||
|         Some(mk_ty(ty)) | ||||
|     } | ||||
| 
 | ||||
|  | @ -334,8 +343,8 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         _param: &ast::SelfParam, | ||||
|     ) -> Option<Type<'db>> { | ||||
|         let binding = self.body()?.self_param?; | ||||
|         let ty = self.infer()?[binding].clone(); | ||||
|         Some(Type::new_with_resolver(db, &self.resolver, ty)) | ||||
|         let ty = self.infer()?[binding]; | ||||
|         Some(Type::new_with_resolver(db, &self.resolver, ty.to_chalk(DbInterner::conjure()))) | ||||
|     } | ||||
| 
 | ||||
|     pub(crate) fn binding_mode_of_pat( | ||||
|  | @ -347,8 +356,10 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         let infer = self.infer()?; | ||||
|         infer.binding_mode(id.as_pat()?).map(|bm| match bm { | ||||
|             hir_ty::BindingMode::Move => BindingMode::Move, | ||||
|             hir_ty::BindingMode::Ref(hir_ty::Mutability::Mut) => BindingMode::Ref(Mutability::Mut), | ||||
|             hir_ty::BindingMode::Ref(hir_ty::Mutability::Not) => { | ||||
|             hir_ty::BindingMode::Ref(hir_ty::next_solver::Mutability::Mut) => { | ||||
|                 BindingMode::Ref(Mutability::Mut) | ||||
|             } | ||||
|             hir_ty::BindingMode::Ref(hir_ty::next_solver::Mutability::Not) => { | ||||
|                 BindingMode::Ref(Mutability::Shared) | ||||
|             } | ||||
|         }) | ||||
|  | @ -364,7 +375,9 @@ impl<'db> SourceAnalyzer<'db> { | |||
|             infer | ||||
|                 .pat_adjustment(pat_id.as_pat()?)? | ||||
|                 .iter() | ||||
|                 .map(|ty| Type::new_with_resolver(db, &self.resolver, ty.clone())) | ||||
|                 .map(|ty| { | ||||
|                     Type::new_with_resolver(db, &self.resolver, ty.to_chalk(DbInterner::conjure())) | ||||
|                 }) | ||||
|                 .collect(), | ||||
|         ) | ||||
|     } | ||||
|  | @ -375,9 +388,8 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         call: &ast::MethodCallExpr, | ||||
|     ) -> Option<Callable<'db>> { | ||||
|         let expr_id = self.expr_id(call.clone().into())?.as_expr()?; | ||||
|         let (func, substs) = self.infer()?.method_resolution(expr_id)?; | ||||
|         let (func, args) = self.infer()?.method_resolution(expr_id)?; | ||||
|         let interner = DbInterner::new_with(db, None, None); | ||||
|         let args: hir_ty::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner); | ||||
|         let ty = db.value_ty(func.into())?.instantiate(interner, args); | ||||
|         let ty = Type::new_with_resolver(db, &self.resolver, ty.to_chalk(interner)); | ||||
|         let mut res = ty.as_callable(db)?; | ||||
|  | @ -403,13 +415,18 @@ impl<'db> SourceAnalyzer<'db> { | |||
|     ) -> Option<(Either<Function, Field>, Option<GenericSubstitution<'db>>)> { | ||||
|         let expr_id = self.expr_id(call.clone().into())?.as_expr()?; | ||||
|         let inference_result = self.infer()?; | ||||
|         let interner = DbInterner::new_with(db, None, None); | ||||
|         match inference_result.method_resolution(expr_id) { | ||||
|             Some((f_in_trait, substs)) => { | ||||
|                 let (fn_, subst) = | ||||
|                     self.resolve_impl_method_or_trait_def_with_subst(db, f_in_trait, substs); | ||||
|                 Some(( | ||||
|                     Either::Left(fn_.into()), | ||||
|                     Some(GenericSubstitution::new(fn_.into(), subst, self.trait_environment(db))), | ||||
|                     Some(GenericSubstitution::new( | ||||
|                         fn_.into(), | ||||
|                         subst.to_chalk(interner), | ||||
|                         self.trait_environment(db), | ||||
|                     )), | ||||
|                 )) | ||||
|             } | ||||
|             None => { | ||||
|  | @ -443,7 +460,7 @@ impl<'db> SourceAnalyzer<'db> { | |||
|     fn field_subst( | ||||
|         &self, | ||||
|         field_expr: ExprId, | ||||
|         infer: &InferenceResult, | ||||
|         infer: &InferenceResult<'db>, | ||||
|         db: &'db dyn HirDatabase, | ||||
|     ) -> Option<GenericSubstitution<'db>> { | ||||
|         let body = self.store()?; | ||||
|  | @ -451,7 +468,7 @@ impl<'db> SourceAnalyzer<'db> { | |||
|             let (adt, subst) = infer.type_of_expr_with_adjust(object_expr)?.as_adt()?; | ||||
|             return Some(GenericSubstitution::new( | ||||
|                 adt.into(), | ||||
|                 subst.clone(), | ||||
|                 subst.to_chalk(DbInterner::conjure()), | ||||
|                 self.trait_environment(db), | ||||
|             )); | ||||
|         } | ||||
|  | @ -467,6 +484,7 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         let (def, ..) = self.body_()?; | ||||
|         let expr_id = self.expr_id(field.clone().into())?.as_expr()?; | ||||
|         let inference_result = self.infer()?; | ||||
|         let interner = DbInterner::new_with(db, None, None); | ||||
|         match inference_result.field_resolution(expr_id) { | ||||
|             Some(field) => match field { | ||||
|                 Either::Left(field) => Some(( | ||||
|  | @ -486,7 +504,11 @@ impl<'db> SourceAnalyzer<'db> { | |||
|                 let (f, subst) = self.resolve_impl_method_or_trait_def_with_subst(db, f, substs); | ||||
|                 ( | ||||
|                     Either::Right(f.into()), | ||||
|                     Some(GenericSubstitution::new(f.into(), subst, self.trait_environment(db))), | ||||
|                     Some(GenericSubstitution::new( | ||||
|                         f.into(), | ||||
|                         subst.to_chalk(interner), | ||||
|                         self.trait_environment(db), | ||||
|                     )), | ||||
|                 ) | ||||
|             }), | ||||
|         } | ||||
|  | @ -560,11 +582,11 @@ impl<'db> SourceAnalyzer<'db> { | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         let future_trait = LangItem::Future.resolve_trait(db, self.resolver.krate())?; | ||||
|         let poll_fn = LangItem::FuturePoll.resolve_function(db, self.resolver.krate())?; | ||||
|         // HACK: subst for `poll()` coincides with that for `Future` because `poll()` itself
 | ||||
|         // doesn't have any generic parameters, so we skip building another subst for `poll()`.
 | ||||
|         let substs = hir_ty::TyBuilder::subst_for_def(db, future_trait, None).push(ty).build(); | ||||
|         let interner = DbInterner::new_with(db, None, None); | ||||
|         let substs = GenericArgs::new_from_iter(interner, [ty.to_nextsolver(interner).into()]); | ||||
|         Some(self.resolve_impl_method_or_trait_def(db, poll_fn, substs)) | ||||
|     } | ||||
| 
 | ||||
|  | @ -573,7 +595,7 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         db: &'db dyn HirDatabase, | ||||
|         prefix_expr: &ast::PrefixExpr, | ||||
|     ) -> Option<FunctionId> { | ||||
|         let (op_trait, op_fn) = match prefix_expr.op_kind()? { | ||||
|         let (_op_trait, op_fn) = match prefix_expr.op_kind()? { | ||||
|             ast::UnaryOp::Deref => { | ||||
|                 // This can be either `Deref::deref` or `DerefMut::deref_mut`.
 | ||||
|                 // Since deref kind is inferenced and stored in `InferenceResult.method_resolution`,
 | ||||
|  | @ -603,9 +625,10 @@ impl<'db> SourceAnalyzer<'db> { | |||
| 
 | ||||
|         let ty = self.ty_of_expr(prefix_expr.expr()?)?; | ||||
| 
 | ||||
|         let interner = DbInterner::new_with(db, None, None); | ||||
|         // HACK: subst for all methods coincides with that for their trait because the methods
 | ||||
|         // don't have any generic parameters, so we skip building another subst for the methods.
 | ||||
|         let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None).push(ty.clone()).build(); | ||||
|         let substs = GenericArgs::new_from_iter(interner, [ty.to_nextsolver(interner).into()]); | ||||
| 
 | ||||
|         Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs)) | ||||
|     } | ||||
|  | @ -618,27 +641,28 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         let base_ty = self.ty_of_expr(index_expr.base()?)?; | ||||
|         let index_ty = self.ty_of_expr(index_expr.index()?)?; | ||||
| 
 | ||||
|         let (index_trait, index_fn) = | ||||
|         let (_index_trait, index_fn) = | ||||
|             self.lang_trait_fn(db, LangItem::Index, &Name::new_symbol_root(sym::index))?; | ||||
|         let (op_trait, op_fn) = self | ||||
|         let op_fn = self | ||||
|             .infer() | ||||
|             .and_then(|infer| { | ||||
|                 let expr = self.expr_id(index_expr.clone().into())?.as_expr()?; | ||||
|                 let (func, _) = infer.method_resolution(expr)?; | ||||
|                 let (index_mut_trait, index_mut_fn) = self.lang_trait_fn( | ||||
|                 let (_index_mut_trait, index_mut_fn) = self.lang_trait_fn( | ||||
|                     db, | ||||
|                     LangItem::IndexMut, | ||||
|                     &Name::new_symbol_root(sym::index_mut), | ||||
|                 )?; | ||||
|                 if func == index_mut_fn { Some((index_mut_trait, index_mut_fn)) } else { None } | ||||
|                 if func == index_mut_fn { Some(index_mut_fn) } else { None } | ||||
|             }) | ||||
|             .unwrap_or((index_trait, index_fn)); | ||||
|             .unwrap_or(index_fn); | ||||
|         // HACK: subst for all methods coincides with that for their trait because the methods
 | ||||
|         // don't have any generic parameters, so we skip building another subst for the methods.
 | ||||
|         let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None) | ||||
|             .push(base_ty.clone()) | ||||
|             .push(index_ty.clone()) | ||||
|             .build(); | ||||
|         let interner = DbInterner::new_with(db, None, None); | ||||
|         let substs = GenericArgs::new_from_iter( | ||||
|             interner, | ||||
|             [base_ty.to_nextsolver(interner).into(), index_ty.to_nextsolver(interner).into()], | ||||
|         ); | ||||
|         Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs)) | ||||
|     } | ||||
| 
 | ||||
|  | @ -651,14 +675,15 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         let lhs = self.ty_of_expr(binop_expr.lhs()?)?; | ||||
|         let rhs = self.ty_of_expr(binop_expr.rhs()?)?; | ||||
| 
 | ||||
|         let (op_trait, op_fn) = lang_items_for_bin_op(op) | ||||
|         let (_op_trait, op_fn) = lang_items_for_bin_op(op) | ||||
|             .and_then(|(name, lang_item)| self.lang_trait_fn(db, lang_item, &name))?; | ||||
|         // HACK: subst for `index()` coincides with that for `Index` because `index()` itself
 | ||||
|         // doesn't have any generic parameters, so we skip building another subst for `index()`.
 | ||||
|         let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None) | ||||
|             .push(lhs.clone()) | ||||
|             .push(rhs.clone()) | ||||
|             .build(); | ||||
|         let interner = DbInterner::new_with(db, None, None); | ||||
|         let substs = GenericArgs::new_from_iter( | ||||
|             interner, | ||||
|             [lhs.to_nextsolver(interner).into(), rhs.to_nextsolver(interner).into()], | ||||
|         ); | ||||
| 
 | ||||
|         Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs)) | ||||
|     } | ||||
|  | @ -671,13 +696,10 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         let ty = self.ty_of_expr(try_expr.expr()?)?; | ||||
| 
 | ||||
|         let op_fn = LangItem::TryTraitBranch.resolve_function(db, self.resolver.krate())?; | ||||
|         let op_trait = match op_fn.lookup(db).container { | ||||
|             ItemContainerId::TraitId(id) => id, | ||||
|             _ => return None, | ||||
|         }; | ||||
|         // HACK: subst for `branch()` coincides with that for `Try` because `branch()` itself
 | ||||
|         // doesn't have any generic parameters, so we skip building another subst for `branch()`.
 | ||||
|         let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None).push(ty.clone()).build(); | ||||
|         let interner = DbInterner::new_with(db, None, None); | ||||
|         let substs = GenericArgs::new_from_iter(interner, [ty.to_nextsolver(interner).into()]); | ||||
| 
 | ||||
|         Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs)) | ||||
|     } | ||||
|  | @ -690,6 +712,7 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         let record_expr = ast::RecordExpr::cast(field.syntax().parent().and_then(|p| p.parent())?)?; | ||||
|         let expr = ast::Expr::from(record_expr); | ||||
|         let expr_id = self.store_sm()?.node_expr(InFile::new(self.file_id, &expr))?; | ||||
|         let interner = DbInterner::new_with(db, None, None); | ||||
| 
 | ||||
|         let ast_name = field.field_name()?; | ||||
|         let local_name = ast_name.as_name(); | ||||
|  | @ -713,16 +736,17 @@ impl<'db> SourceAnalyzer<'db> { | |||
|             } | ||||
|         }; | ||||
|         let (adt, subst) = self.infer()?.type_of_expr_or_pat(expr_id)?.as_adt()?; | ||||
|         let subst = subst.to_chalk(interner); | ||||
|         let variant = self.infer()?.variant_resolution_for_expr_or_pat(expr_id)?; | ||||
|         let variant_data = variant.fields(db); | ||||
|         let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? }; | ||||
|         let field_ty = | ||||
|             db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, subst); | ||||
|             db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, &subst); | ||||
|         Some(( | ||||
|             field.into(), | ||||
|             local, | ||||
|             Type::new_with_resolver(db, &self.resolver, field_ty), | ||||
|             GenericSubstitution::new(adt.into(), subst.clone(), self.trait_environment(db)), | ||||
|             GenericSubstitution::new(adt.into(), subst, self.trait_environment(db)), | ||||
|         )) | ||||
|     } | ||||
| 
 | ||||
|  | @ -731,6 +755,7 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         db: &'db dyn HirDatabase, | ||||
|         field: &ast::RecordPatField, | ||||
|     ) -> Option<(Field, Type<'db>, GenericSubstitution<'db>)> { | ||||
|         let interner = DbInterner::new_with(db, None, None); | ||||
|         let field_name = field.field_name()?.as_name(); | ||||
|         let record_pat = ast::RecordPat::cast(field.syntax().parent().and_then(|p| p.parent())?)?; | ||||
|         let pat_id = self.pat_id(&record_pat.into())?; | ||||
|  | @ -738,12 +763,13 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         let variant_data = variant.fields(db); | ||||
|         let field = FieldId { parent: variant, local_id: variant_data.field(&field_name)? }; | ||||
|         let (adt, subst) = self.infer()?[pat_id.as_pat()?].as_adt()?; | ||||
|         let subst = subst.to_chalk(interner); | ||||
|         let field_ty = | ||||
|             db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, subst); | ||||
|             db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, &subst); | ||||
|         Some(( | ||||
|             field.into(), | ||||
|             Type::new_with_resolver(db, &self.resolver, field_ty), | ||||
|             GenericSubstitution::new(adt.into(), subst.clone(), self.trait_environment(db)), | ||||
|             GenericSubstitution::new(adt.into(), subst, self.trait_environment(db)), | ||||
|         )) | ||||
|     } | ||||
| 
 | ||||
|  | @ -859,6 +885,7 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         db: &'db dyn HirDatabase, | ||||
|         path: &ast::Path, | ||||
|     ) -> Option<(PathResolution, Option<GenericSubstitution<'db>>)> { | ||||
|         let interner = DbInterner::new_with(db, None, None); | ||||
|         let parent = path.syntax().parent(); | ||||
|         let parent = || parent.clone(); | ||||
| 
 | ||||
|  | @ -874,29 +901,31 @@ impl<'db> SourceAnalyzer<'db> { | |||
|                                 None => { | ||||
|                                     let subst = GenericSubstitution::new( | ||||
|                                         f_in_trait.into(), | ||||
|                                         subs, | ||||
|                                         subs.to_chalk(interner), | ||||
|                                         self.trait_environment(db), | ||||
|                                     ); | ||||
|                                     (assoc, subst) | ||||
|                                 } | ||||
|                                 Some(func_ty) => { | ||||
|                                     if let TyKind::FnDef(_fn_def, subs) = func_ty.kind(Interner) { | ||||
|                                     if let TyKind::FnDef(_fn_def, subs) = | ||||
|                                         func_ty.to_chalk(interner).kind(Interner) | ||||
|                                     { | ||||
|                                         let (fn_, subst) = self | ||||
|                                             .resolve_impl_method_or_trait_def_with_subst( | ||||
|                                                 db, | ||||
|                                                 f_in_trait, | ||||
|                                                 subs.clone(), | ||||
|                                                 subs.to_nextsolver(interner), | ||||
|                                             ); | ||||
|                                         let subst = GenericSubstitution::new( | ||||
|                                             fn_.into(), | ||||
|                                             subst, | ||||
|                                             subst.to_chalk(interner), | ||||
|                                             self.trait_environment(db), | ||||
|                                         ); | ||||
|                                         (fn_.into(), subst) | ||||
|                                     } else { | ||||
|                                         let subst = GenericSubstitution::new( | ||||
|                                             f_in_trait.into(), | ||||
|                                             subs, | ||||
|                                             subs.to_chalk(interner), | ||||
|                                             self.trait_environment(db), | ||||
|                                         ); | ||||
|                                         (assoc, subst) | ||||
|  | @ -909,7 +938,7 @@ impl<'db> SourceAnalyzer<'db> { | |||
|                                 self.resolve_impl_const_or_trait_def_with_subst(db, const_id, subs); | ||||
|                             let subst = GenericSubstitution::new( | ||||
|                                 konst.into(), | ||||
|                                 subst, | ||||
|                                 subst.to_chalk(interner), | ||||
|                                 self.trait_environment(db), | ||||
|                             ); | ||||
|                             (konst.into(), subst) | ||||
|  | @ -918,7 +947,7 @@ impl<'db> SourceAnalyzer<'db> { | |||
|                             assoc, | ||||
|                             GenericSubstitution::new( | ||||
|                                 type_alias.into(), | ||||
|                                 subs, | ||||
|                                 subs.to_chalk(interner), | ||||
|                                 self.trait_environment(db), | ||||
|                             ), | ||||
|                         ), | ||||
|  | @ -942,7 +971,7 @@ impl<'db> SourceAnalyzer<'db> { | |||
|                                 self.resolve_impl_const_or_trait_def_with_subst(db, const_id, subs); | ||||
|                             let subst = GenericSubstitution::new( | ||||
|                                 konst.into(), | ||||
|                                 subst, | ||||
|                                 subst.to_chalk(interner), | ||||
|                                 self.trait_environment(db), | ||||
|                             ); | ||||
|                             (konst.into(), subst) | ||||
|  | @ -951,7 +980,7 @@ impl<'db> SourceAnalyzer<'db> { | |||
|                             assoc, | ||||
|                             GenericSubstitution::new( | ||||
|                                 assoc.into(), | ||||
|                                 subs, | ||||
|                                 subs.to_chalk(interner), | ||||
|                                 self.trait_environment(db), | ||||
|                             ), | ||||
|                         ), | ||||
|  | @ -1149,10 +1178,10 @@ impl<'db> SourceAnalyzer<'db> { | |||
|                 let parent = parent()?; | ||||
|                 let ty = if let Some(expr) = ast::Expr::cast(parent.clone()) { | ||||
|                     let expr_id = self.expr_id(expr)?; | ||||
|                     self.infer()?.type_of_expr_or_pat(expr_id)? | ||||
|                     self.infer()?.type_of_expr_or_pat(expr_id)?.to_chalk(interner) | ||||
|                 } else if let Some(pat) = ast::Pat::cast(parent) { | ||||
|                     let pat_id = self.pat_id(&pat)?; | ||||
|                     &self.infer()?[pat_id] | ||||
|                     self.infer()?[pat_id].to_chalk(interner) | ||||
|                 } else { | ||||
|                     return None; | ||||
|                 }; | ||||
|  | @ -1232,7 +1261,8 @@ impl<'db> SourceAnalyzer<'db> { | |||
|                 record_pattern_missing_fields(db, infer, pat_id, &body[pat_id])? | ||||
|             } | ||||
|         }; | ||||
|         let res = self.missing_fields(db, substs, variant, missing_fields); | ||||
|         let interner = DbInterner::new_with(db, None, None); | ||||
|         let res = self.missing_fields(db, &substs.to_chalk(interner), variant, missing_fields); | ||||
|         Some(res) | ||||
|     } | ||||
| 
 | ||||
|  | @ -1249,7 +1279,8 @@ impl<'db> SourceAnalyzer<'db> { | |||
| 
 | ||||
|         let (variant, missing_fields, _exhaustive) = | ||||
|             record_pattern_missing_fields(db, infer, pat_id, &body[pat_id])?; | ||||
|         let res = self.missing_fields(db, substs, variant, missing_fields); | ||||
|         let interner = DbInterner::new_with(db, None, None); | ||||
|         let res = self.missing_fields(db, &substs.to_chalk(interner), variant, missing_fields); | ||||
|         Some(res) | ||||
|     } | ||||
| 
 | ||||
|  | @ -1379,7 +1410,7 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         &self, | ||||
|         db: &'db dyn HirDatabase, | ||||
|         func: FunctionId, | ||||
|         substs: Substitution, | ||||
|         substs: GenericArgs<'db>, | ||||
|     ) -> FunctionId { | ||||
|         self.resolve_impl_method_or_trait_def_with_subst(db, func, substs).0 | ||||
|     } | ||||
|  | @ -1388,8 +1419,8 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         &self, | ||||
|         db: &'db dyn HirDatabase, | ||||
|         func: FunctionId, | ||||
|         substs: Substitution, | ||||
|     ) -> (FunctionId, Substitution) { | ||||
|         substs: GenericArgs<'db>, | ||||
|     ) -> (FunctionId, GenericArgs<'db>) { | ||||
|         let owner = match self.resolver.body_owner() { | ||||
|             Some(it) => it, | ||||
|             None => return (func, substs), | ||||
|  | @ -1402,14 +1433,19 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         &self, | ||||
|         db: &'db dyn HirDatabase, | ||||
|         const_id: ConstId, | ||||
|         subs: Substitution, | ||||
|     ) -> (ConstId, Substitution) { | ||||
|         subs: GenericArgs<'db>, | ||||
|     ) -> (ConstId, GenericArgs<'db>) { | ||||
|         let owner = match self.resolver.body_owner() { | ||||
|             Some(it) => it, | ||||
|             None => return (const_id, subs), | ||||
|         }; | ||||
|         let env = db.trait_environment_for_body(owner); | ||||
|         method_resolution::lookup_impl_const(db, env, const_id, subs) | ||||
|         method_resolution::lookup_impl_const( | ||||
|             DbInterner::new_with(db, None, None), | ||||
|             env, | ||||
|             const_id, | ||||
|             subs, | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn lang_trait_fn( | ||||
|  | @ -1423,8 +1459,10 @@ impl<'db> SourceAnalyzer<'db> { | |||
|         Some((trait_id, fn_id)) | ||||
|     } | ||||
| 
 | ||||
|     fn ty_of_expr(&self, expr: ast::Expr) -> Option<&Ty> { | ||||
|         self.infer()?.type_of_expr_or_pat(self.expr_id(expr)?) | ||||
|     fn ty_of_expr(&self, expr: ast::Expr) -> Option<Ty> { | ||||
|         self.infer()? | ||||
|             .type_of_expr_or_pat(self.expr_id(expr)?) | ||||
|             .map(|ty| ty.to_chalk(DbInterner::conjure())) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Chayim Refael Friedman
						Chayim Refael Friedman