Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/source_analyzer.rs')
| -rw-r--r-- | crates/hir/src/source_analyzer.rs | 94 |
1 files changed, 54 insertions, 40 deletions
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 858426ceab..901c9e1575 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -18,7 +18,7 @@ use hir_def::{ scope::{ExprScopes, ScopeId}, }, hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat}, - lang_item::LangItem, + lang_item::LangItems, nameres::MacroSubNs, resolver::{HasResolver, Resolver, TypeNs, ValueNs, resolver_for_scope}, type_ref::{Mutability, TypeRef, TypeRefId}, @@ -29,7 +29,7 @@ use hir_expand::{ name::{AsName, Name}, }; use hir_ty::{ - Adjustment, InferenceResult, LifetimeElisionKind, TraitEnvironment, TyLoweringContext, + Adjustment, InferenceResult, LifetimeElisionKind, ParamEnvAndCrate, TyLoweringContext, diagnostics::{ InsideUnsafeBlock, record_literal_missing_fields, record_pattern_missing_fields, unsafe_operations, @@ -37,7 +37,8 @@ use hir_ty::{ lang_items::lang_items_for_bin_op, method_resolution::{self, CandidateId}, next_solver::{ - DbInterner, ErrorGuaranteed, GenericArgs, Ty, TyKind, TypingMode, infer::DbInternerInferExt, + DbInterner, ErrorGuaranteed, GenericArgs, ParamEnv, Ty, TyKind, TypingMode, + infer::DbInternerInferExt, }, traits::structurally_normalize_ty, }; @@ -78,7 +79,7 @@ pub(crate) enum BodyOrSig<'db> { def: DefWithBodyId, body: Arc<Body>, source_map: Arc<BodySourceMap>, - infer: Option<Arc<InferenceResult<'db>>>, + infer: Option<&'db InferenceResult<'db>>, }, // To be folded into body once it is considered one VariantFields { @@ -101,7 +102,7 @@ impl<'db> SourceAnalyzer<'db> { node: InFile<&SyntaxNode>, offset: Option<TextSize>, ) -> SourceAnalyzer<'db> { - Self::new_for_body_(db, def, node, offset, Some(db.infer(def))) + Self::new_for_body_(db, def, node, offset, Some(InferenceResult::for_body(db, def))) } pub(crate) fn new_for_body_no_infer( @@ -118,7 +119,7 @@ impl<'db> SourceAnalyzer<'db> { def: DefWithBodyId, node @ InFile { file_id, .. }: InFile<&SyntaxNode>, offset: Option<TextSize>, - infer: Option<Arc<InferenceResult<'db>>>, + infer: Option<&'db InferenceResult<'db>>, ) -> SourceAnalyzer<'db> { let (body, source_map) = db.body_with_source_map(def); let scopes = db.expr_scopes(def); @@ -227,10 +228,15 @@ impl<'db> SourceAnalyzer<'db> { }) } - fn trait_environment(&self, db: &'db dyn HirDatabase) -> Arc<TraitEnvironment<'db>> { - self.body_().map(|(def, ..)| def).map_or_else( - || TraitEnvironment::empty(self.resolver.krate()), - |def| db.trait_environment_for_body(def), + fn param_and<'a>(&self, param_env: ParamEnv<'a>) -> ParamEnvAndCrate<'a> { + ParamEnvAndCrate { param_env, krate: self.resolver.krate() } + } + + fn trait_environment(&self, db: &'db dyn HirDatabase) -> ParamEnvAndCrate<'db> { + self.param_and( + self.body_() + .map(|(def, ..)| def) + .map_or_else(ParamEnv::empty, |def| db.trait_environment_for_body(def)), ) } @@ -267,7 +273,7 @@ impl<'db> SourceAnalyzer<'db> { db: &'db dyn HirDatabase, ty: &ast::Type, ) -> Option<Type<'db>> { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let type_ref = self.type_id(ty)?; @@ -410,7 +416,7 @@ impl<'db> SourceAnalyzer<'db> { ) -> Option<Callable<'db>> { let expr_id = self.expr_id(call.clone().into())?.as_expr()?; let (func, args) = self.infer()?.method_resolution(expr_id)?; - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let ty = db.value_ty(func.into())?.instantiate(interner, args); let ty = Type::new_with_resolver(db, &self.resolver, ty); let mut res = ty.as_callable(db)?; @@ -589,10 +595,10 @@ impl<'db> SourceAnalyzer<'db> { } } - let poll_fn = LangItem::FuturePoll.resolve_function(db, self.resolver.krate())?; + let poll_fn = self.lang_items(db).FuturePoll?; // 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 interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let substs = GenericArgs::new_from_iter(interner, [ty.into()]); Some(self.resolve_impl_method_or_trait_def(db, poll_fn, substs)) } @@ -607,15 +613,18 @@ impl<'db> SourceAnalyzer<'db> { // This can be either `Deref::deref` or `DerefMut::deref_mut`. // Since deref kind is inferenced and stored in `InferenceResult.method_resolution`, // use that result to find out which one it is. - let (deref_trait, deref) = - self.lang_trait_fn(db, LangItem::Deref, &Name::new_symbol_root(sym::deref))?; + let (deref_trait, deref) = self.lang_trait_fn( + db, + self.lang_items(db).Deref, + &Name::new_symbol_root(sym::deref), + )?; self.infer() .and_then(|infer| { let expr = self.expr_id(prefix_expr.clone().into())?.as_expr()?; let (func, _) = infer.method_resolution(expr)?; let (deref_mut_trait, deref_mut) = self.lang_trait_fn( db, - LangItem::DerefMut, + self.lang_items(db).DerefMut, &Name::new_symbol_root(sym::deref_mut), )?; if func == deref_mut { Some((deref_mut_trait, deref_mut)) } else { None } @@ -623,16 +632,16 @@ impl<'db> SourceAnalyzer<'db> { .unwrap_or((deref_trait, deref)) } ast::UnaryOp::Not => { - self.lang_trait_fn(db, LangItem::Not, &Name::new_symbol_root(sym::not))? + self.lang_trait_fn(db, self.lang_items(db).Not, &Name::new_symbol_root(sym::not))? } ast::UnaryOp::Neg => { - self.lang_trait_fn(db, LangItem::Neg, &Name::new_symbol_root(sym::neg))? + self.lang_trait_fn(db, self.lang_items(db).Neg, &Name::new_symbol_root(sym::neg))? } }; let ty = self.ty_of_expr(prefix_expr.expr()?)?; - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); // 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 = GenericArgs::new_from_iter(interner, [ty.into()]); @@ -649,7 +658,7 @@ impl<'db> SourceAnalyzer<'db> { let index_ty = self.ty_of_expr(index_expr.index()?)?; let (_index_trait, index_fn) = - self.lang_trait_fn(db, LangItem::Index, &Name::new_symbol_root(sym::index))?; + self.lang_trait_fn(db, self.lang_items(db).Index, &Name::new_symbol_root(sym::index))?; let op_fn = self .infer() .and_then(|infer| { @@ -657,7 +666,7 @@ impl<'db> SourceAnalyzer<'db> { let (func, _) = infer.method_resolution(expr)?; let (_index_mut_trait, index_mut_fn) = self.lang_trait_fn( db, - LangItem::IndexMut, + self.lang_items(db).IndexMut, &Name::new_symbol_root(sym::index_mut), )?; if func == index_mut_fn { Some(index_mut_fn) } else { None } @@ -665,7 +674,7 @@ impl<'db> SourceAnalyzer<'db> { .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 interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let substs = GenericArgs::new_from_iter(interner, [base_ty.into(), index_ty.into()]); Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs)) } @@ -679,12 +688,13 @@ 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).and_then(|(name, lang_item)| { - self.lang_trait_fn(db, lang_item, &Name::new_symbol_root(name)) - })?; + let (_op_trait, op_fn) = + lang_items_for_bin_op(self.lang_items(db), op).and_then(|(name, lang_item)| { + self.lang_trait_fn(db, lang_item, &Name::new_symbol_root(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 interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let substs = GenericArgs::new_from_iter(interner, [lhs.into(), rhs.into()]); Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs)) @@ -697,10 +707,10 @@ impl<'db> SourceAnalyzer<'db> { ) -> Option<FunctionId> { let ty = self.ty_of_expr(try_expr.expr()?)?; - let op_fn = LangItem::TryTraitBranch.resolve_function(db, self.resolver.krate())?; + let op_fn = self.lang_items(db).TryTraitBranch?; // 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 interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let substs = GenericArgs::new_from_iter(interner, [ty.into()]); Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs)) @@ -714,7 +724,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 interner = DbInterner::new_no_crate(db); let ast_name = field.field_name()?; let local_name = ast_name.as_name(); @@ -755,7 +765,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 interner = DbInterner::new_no_crate(db); 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())?; @@ -817,13 +827,13 @@ impl<'db> SourceAnalyzer<'db> { let trait_env = container.env; - let interner = DbInterner::new_with(db, Some(trait_env.krate), trait_env.block); + let interner = DbInterner::new_with(db, trait_env.krate); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); let mut container = Either::Right(container.ty); for field_name in offset_of_expr.fields() { if let Either::Right(container) = &mut container { - *container = structurally_normalize_ty(&infcx, *container, trait_env.clone()); + *container = structurally_normalize_ty(&infcx, *container, trait_env.param_env); } let handle_variants = |variant: VariantId, subst: GenericArgs<'db>, container: &mut _| { @@ -1273,7 +1283,7 @@ impl<'db> SourceAnalyzer<'db> { variant: VariantId, missing_fields: Vec<LocalFieldId>, ) -> Vec<(Field, Type<'db>)> { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let field_types = db.field_types(variant); missing_fields @@ -1408,7 +1418,7 @@ impl<'db> SourceAnalyzer<'db> { Some(it) => it, None => return (func, substs), }; - let env = db.trait_environment_for_body(owner); + let env = self.param_and(db.trait_environment_for_body(owner)); db.lookup_impl_method(env, func, substs) } @@ -1422,19 +1432,23 @@ impl<'db> SourceAnalyzer<'db> { Some(it) => it, None => return (const_id, subs), }; - let env = db.trait_environment_for_body(owner); - let interner = DbInterner::new_with(db, Some(env.krate), env.block); + let env = self.param_and(db.trait_environment_for_body(owner)); + let interner = DbInterner::new_with(db, env.krate); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); - method_resolution::lookup_impl_const(&infcx, env, const_id, subs) + method_resolution::lookup_impl_const(&infcx, env.param_env, const_id, subs) + } + + fn lang_items<'a>(&self, db: &'a dyn HirDatabase) -> &'a LangItems { + hir_def::lang_item::lang_items(db, self.resolver.krate()) } fn lang_trait_fn( &self, db: &'db dyn HirDatabase, - lang_trait: LangItem, + lang_trait: Option<TraitId>, method_name: &Name, ) -> Option<(TraitId, FunctionId)> { - let trait_id = lang_trait.resolve_trait(db, self.resolver.krate())?; + let trait_id = lang_trait?; let fn_id = trait_id.trait_items(db).method_by_name(method_name)?; Some((trait_id, fn_id)) } |