Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/lib.rs')
| -rw-r--r-- | crates/hir/src/lib.rs | 336 |
1 files changed, 179 insertions, 157 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 2146e4db77..a50a736ccd 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -48,11 +48,11 @@ use arrayvec::ArrayVec; use base_db::{CrateDisplayName, CrateOrigin, LangCrateOrigin}; use either::Either; use hir_def::{ - AdtId, AssocItemId, AssocItemLoc, CallableDefId, ConstId, ConstParamId, CrateRootModuleId, - DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, GenericDefId, - GenericParamId, HasModule, ImplId, InternedModuleId, ItemContainerId, LifetimeParamId, - LocalFieldId, Lookup, MacroExpander, MacroId, StaticId, StructId, SyntheticSyntax, TupleId, - TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, + AdtId, AssocItemId, AssocItemLoc, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, + EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, GenericDefId, GenericParamId, + HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, MacroExpander, + MacroId, StaticId, StructId, SyntheticSyntax, TupleId, TypeAliasId, TypeOrConstParamId, + TypeParamId, UnionId, attrs::AttrFlags, expr_store::{ExpressionStoreDiagnostics, ExpressionStoreSourceMap}, hir::{ @@ -76,7 +76,7 @@ use hir_expand::{ AstId, MacroCallKind, RenderedExpandError, ValueResult, proc_macro::ProcMacroKind, }; use hir_ty::{ - GenericPredicates, InferenceResult, TraitEnvironment, TyDefId, TyLoweringDiagnostic, + GenericPredicates, InferenceResult, ParamEnvAndCrate, TyDefId, TyLoweringDiagnostic, ValueTyDefId, all_super_traits, autoderef, check_orphan_rules, consteval::try_const_usize, db::{InternedClosureId, InternedCoroutineId}, @@ -89,7 +89,7 @@ use hir_ty::{ mir::{MutBorrowKind, interpret_mir}, next_solver::{ AliasTy, ClauseKind, ConstKind, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, - PolyFnSig, Region, SolverDefId, Ty, TyKind, TypingMode, + ParamEnv, PolyFnSig, Region, SolverDefId, Ty, TyKind, TypingMode, infer::{DbInternerInferExt, InferCtxt}, }, traits::{self, is_inherent_impl_coherent, structurally_normalize_ty}, @@ -117,8 +117,8 @@ pub use crate::{ diagnostics::*, has_source::HasSource, semantics::{ - PathResolution, PathResolutionPerNs, Semantics, SemanticsImpl, SemanticsScope, TypeInfo, - VisibleTraits, + LintAttr, PathResolution, PathResolutionPerNs, Semantics, SemanticsImpl, SemanticsScope, + TypeInfo, VisibleTraits, }, }; @@ -258,13 +258,13 @@ impl Crate { .flatten() } - pub fn root_module(self) -> Module { - Module { id: CrateRootModuleId::from(self.id).into() } + pub fn root_module(self, db: &dyn HirDatabase) -> Module { + Module { id: crate_def_map(db, self.id).root_module_id() } } pub fn modules(self, db: &dyn HirDatabase) -> Vec<Module> { let def_map = crate_def_map(db, self.id); - def_map.modules().map(|(id, _)| def_map.module_id(id).into()).collect() + def_map.modules().map(|(id, _)| id.into()).collect() } pub fn root_file(self, db: &dyn HirDatabase) -> FileId { @@ -520,7 +520,7 @@ impl ModuleDef { impl HasCrate for ModuleDef { fn krate(&self, db: &dyn HirDatabase) -> Crate { match self.module(db) { - Some(module) => module.krate(), + Some(module) => module.krate(db), None => Crate::core(db).unwrap_or_else(|| db.all_crates()[0].into()), } } @@ -550,29 +550,29 @@ impl Module { } /// Returns the crate this module is part of. - pub fn krate(self) -> Crate { - Crate { id: self.id.krate() } + pub fn krate(self, db: &dyn HirDatabase) -> Crate { + Crate { id: self.id.krate(db) } } /// Topmost parent of this module. Every module has a `crate_root`, but some /// might be missing `krate`. This can happen if a module's file is not included /// in the module tree of any target in `Cargo.toml`. pub fn crate_root(self, db: &dyn HirDatabase) -> Module { - let def_map = crate_def_map(db, self.id.krate()); - Module { id: def_map.crate_root().into() } + let def_map = crate_def_map(db, self.id.krate(db)); + Module { id: def_map.crate_root(db) } } - pub fn is_crate_root(self) -> bool { - DefMap::ROOT == self.id.local_id + pub fn is_crate_root(self, db: &dyn HirDatabase) -> bool { + self.crate_root(db) == self } /// Iterates over all child modules. pub fn children(self, db: &dyn HirDatabase) -> impl Iterator<Item = Module> { let def_map = self.id.def_map(db); - let children = def_map[self.id.local_id] + let children = def_map[self.id] .children .values() - .map(|module_id| Module { id: def_map.module_id(*module_id) }) + .map(|module_id| Module { id: *module_id }) .collect::<Vec<_>>(); children.into_iter() } @@ -580,14 +580,14 @@ impl Module { /// Finds a parent module. pub fn parent(self, db: &dyn HirDatabase) -> Option<Module> { let def_map = self.id.def_map(db); - let parent_id = def_map.containing_module(self.id.local_id)?; + let parent_id = def_map.containing_module(self.id)?; Some(Module { id: parent_id }) } /// Finds nearest non-block ancestor `Module` (`self` included). pub fn nearest_non_block_module(self, db: &dyn HirDatabase) -> Module { let mut id = self.id; - while id.is_block_module() { + while id.is_block_module(db) { id = id.containing_module(db).expect("block without parent module"); } Module { id } @@ -609,7 +609,7 @@ impl Module { db: &dyn HirDatabase, visible_from: Option<Module>, ) -> Vec<(Name, ScopeDef)> { - self.id.def_map(db)[self.id.local_id] + self.id.def_map(db)[self.id] .scope .entries() .filter_map(|(name, def)| { @@ -646,19 +646,19 @@ impl Module { style_lints: bool, ) { let _p = tracing::info_span!("diagnostics", name = ?self.name(db)).entered(); - let edition = self.id.krate().data(db).edition; + let edition = self.id.krate(db).data(db).edition; let def_map = self.id.def_map(db); for diag in def_map.diagnostics() { - if diag.in_module != self.id.local_id { + if diag.in_module != self.id { // FIXME: This is accidentally quadratic. continue; } emit_def_diagnostic(db, acc, diag, edition, def_map.krate()); } - if !self.id.is_block_module() { + if !self.id.is_block_module(db) { // These are reported by the body of block modules - let scope = &def_map[self.id.local_id].scope; + let scope = &def_map[self.id].scope; scope.all_macro_calls().for_each(|it| macro_call_diagnostics(db, it, acc)); } @@ -666,7 +666,7 @@ impl Module { match def { ModuleDef::Module(m) => { // Only add diagnostics from inline modules - if def_map[m.id.local_id].origin.is_inline() { + if def_map[m.id].origin.is_inline() { m.diagnostics(db, acc, style_lints) } acc.extend(def.diagnostics(db, style_lints)) @@ -765,7 +765,7 @@ impl Module { } self.legacy_macros(db).into_iter().for_each(|m| emit_macro_def_diagnostics(db, acc, m)); - let interner = DbInterner::new_with(db, self.id.krate()); + let interner = DbInterner::new_with(db, self.id.krate(db)); let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); let mut impl_assoc_items_scratch = vec![]; @@ -790,7 +790,7 @@ impl Module { let ast_id_map = db.ast_id_map(file_id); for diag in impl_def.id.impl_items_with_diagnostics(db).1.iter() { - emit_def_diagnostic(db, acc, diag, edition, loc.container.krate()); + emit_def_diagnostic(db, acc, diag, edition, loc.container.krate(db)); } if impl_signature.target_trait.is_none() @@ -939,7 +939,7 @@ impl Module { pub fn declarations(self, db: &dyn HirDatabase) -> Vec<ModuleDef> { let def_map = self.id.def_map(db); - let scope = &def_map[self.id.local_id].scope; + let scope = &def_map[self.id].scope; scope .declarations() .map(ModuleDef::from) @@ -949,13 +949,13 @@ impl Module { pub fn legacy_macros(self, db: &dyn HirDatabase) -> Vec<Macro> { let def_map = self.id.def_map(db); - let scope = &def_map[self.id.local_id].scope; + let scope = &def_map[self.id].scope; scope.legacy_macros().flat_map(|(_, it)| it).map(|&it| it.into()).collect() } pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec<Impl> { let def_map = self.id.def_map(db); - def_map[self.id.local_id].scope.impls().map(Impl::from).collect() + def_map[self.id].scope.impls().map(Impl::from).collect() } /// Finds a path that can be used to refer to the given item from within @@ -990,7 +990,7 @@ impl Module { #[inline] pub fn doc_keyword(self, db: &dyn HirDatabase) -> Option<Symbol> { - AttrFlags::doc_keyword(db, InternedModuleId::new(db, self.id)) + AttrFlags::doc_keyword(db, self.id) } /// Whether it has `#[path = "..."]` attribute. @@ -1196,7 +1196,7 @@ fn precise_macro_call_location( impl HasVisibility for Module { fn visibility(&self, db: &dyn HirDatabase) -> Visibility { let def_map = self.id.def_map(db); - let module_data = &def_map[self.id.local_id]; + let module_data = &def_map[self.id]; module_data.visibility } } @@ -1245,7 +1245,7 @@ impl TupleField { .get(self.index as usize) .copied() .unwrap_or_else(|| Ty::new_error(interner, ErrorGuaranteed)); - Type { env: db.trait_environment_for_body(self.owner), ty } + Type { env: body_param_env_from_has_crate(db, self.owner), ty } } } @@ -1322,13 +1322,16 @@ impl Field { pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> { db.layout_of_ty( self.ty(db).ty, - db.trait_environment(match hir_def::VariantId::from(self.parent) { - hir_def::VariantId::EnumVariantId(id) => { - GenericDefId::AdtId(id.lookup(db).parent.into()) - } - hir_def::VariantId::StructId(id) => GenericDefId::AdtId(id.into()), - hir_def::VariantId::UnionId(id) => GenericDefId::AdtId(id.into()), - }), + param_env_from_has_crate( + db, + match hir_def::VariantId::from(self.parent) { + hir_def::VariantId::EnumVariantId(id) => { + GenericDefId::AdtId(id.lookup(db).parent.into()) + } + hir_def::VariantId::StructId(id) => GenericDefId::AdtId(id.into()), + hir_def::VariantId::UnionId(id) => GenericDefId::AdtId(id.into()), + }, + ), ) .map(|layout| Layout(layout, db.target_data_layout(self.krate(db).into()).unwrap())) } @@ -1538,7 +1541,7 @@ impl Enum { pub fn variant_body_ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> { let interner = DbInterner::new_no_crate(db); Type::new_for_crate( - self.id.lookup(db).container.krate(), + self.id.lookup(db).container.krate(db), match EnumSignature::variant_body_type(db, self.id) { layout::IntegerType::Pointer(sign) => match sign { true => Ty::new_int(interner, rustc_type_ir::IntTy::Isize), @@ -1745,13 +1748,12 @@ impl Adt { } pub fn layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> { - let env = db.trait_environment(self.into()); let interner = DbInterner::new_no_crate(db); let adt_id = AdtId::from(self); let args = GenericArgs::for_item_with_defaults(interner, adt_id.into(), |_, id, _| { GenericArg::error_from_id(interner, id) }); - db.layout_of_adt(adt_id, args, env) + db.layout_of_adt(adt_id, args, param_env_from_has_crate(db, adt_id)) .map(|layout| Layout(layout, db.target_data_layout(self.krate(db).id).unwrap())) } @@ -1925,7 +1927,7 @@ impl DefWithBody { pub fn debug_mir(self, db: &dyn HirDatabase) -> String { let body = db.mir_body(self.id()); match body { - Ok(body) => body.pretty_print(db, self.module(db).krate().to_display_target(db)), + Ok(body) => body.pretty_print(db, self.module(db).krate(db).to_display_target(db)), Err(e) => format!("error:\n{e:?}"), } } @@ -1936,7 +1938,7 @@ impl DefWithBody { acc: &mut Vec<AnyDiagnostic<'db>>, style_lints: bool, ) { - let krate = self.module(db).id.krate(); + let krate = self.module(db).id.krate(db); let (body, source_map) = db.body_with_source_map(self.into()); let sig_source_map = match self { @@ -1950,7 +1952,7 @@ impl DefWithBody { }; for (_, def_map) in body.blocks(db) { - Module { id: def_map.module_id(DefMap::ROOT) }.diagnostics(db, acc, style_lints); + Module { id: def_map.root_module_id() }.diagnostics(db, acc, style_lints); } expr_store_diagnostics(db, acc, &source_map); @@ -2276,7 +2278,7 @@ impl Function { } pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec<Param<'_>> { - let environment = db.trait_environment(self.id.into()); + let environment = param_env_from_has_crate(db, self.id); // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s. let callable_sig = db.callable_item_signature(self.id.into()).instantiate_identity().skip_binder(); @@ -2285,7 +2287,7 @@ impl Function { .iter() .enumerate() .map(|(idx, ty)| { - let ty = Type { env: environment.clone(), ty }; + let ty = Type { env: environment, ty }; Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx } }) .collect() @@ -2301,7 +2303,7 @@ impl Function { } pub fn params_without_self(self, db: &dyn HirDatabase) -> Vec<Param<'_>> { - let environment = db.trait_environment(self.id.into()); + let environment = param_env_from_has_crate(db, self.id); // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s. let callable_sig = db.callable_item_signature(self.id.into()).instantiate_identity().skip_binder(); @@ -2312,7 +2314,7 @@ impl Function { .enumerate() .skip(skip) .map(|(idx, ty)| { - let ty = Type { env: environment.clone(), ty }; + let ty = Type { env: environment, ty }; Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx } }) .collect() @@ -2324,7 +2326,7 @@ impl Function { db: &'db dyn HirDatabase, generics: impl Iterator<Item = Type<'db>>, ) -> Vec<Param<'db>> { - let environment = db.trait_environment(self.id.into()); + let environment = param_env_from_has_crate(db, self.id); let interner = DbInterner::new_no_crate(db); let args = generic_args_from_tys(interner, self.id.into(), generics.map(|ty| ty.ty)); let callable_sig = @@ -2336,7 +2338,7 @@ impl Function { .enumerate() .skip(skip) .map(|(idx, ty)| { - let ty = Type { env: environment.clone(), ty }; + let ty = Type { env: environment, ty }; Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx } }) .collect() @@ -2396,7 +2398,7 @@ impl Function { /// is this a `fn main` or a function with an `export_name` of `main`? pub fn is_main(self, db: &dyn HirDatabase) -> bool { self.exported_main(db) - || self.module(db).is_crate_root() && db.function_signature(self.id).name == sym::main + || self.module(db).is_crate_root(db) && db.function_signature(self.id).name == sym::main } /// Is this a function with an `export_name` of `main`? @@ -2471,7 +2473,10 @@ impl Function { let body = db.monomorphized_mir_body( self.id.into(), GenericArgs::new_from_iter(interner, []), - db.trait_environment(self.id.into()), + ParamEnvAndCrate { + param_env: db.trait_environment(self.id.into()), + krate: self.id.module(db).krate(db), + }, )?; let (result, output) = interpret_mir(db, body, false, None)?; let mut text = match result { @@ -2613,7 +2618,7 @@ impl SelfParam { // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s. let callable_sig = db.callable_item_signature(self.func.into()).instantiate_identity().skip_binder(); - let environment = db.trait_environment(self.func.into()); + let environment = param_env_from_has_crate(db, self.func); let ty = callable_sig.inputs().as_slice()[0]; Type { env: environment, ty } } @@ -2628,7 +2633,7 @@ impl SelfParam { let args = generic_args_from_tys(interner, self.func.into(), generics.map(|ty| ty.ty)); let callable_sig = db.callable_item_signature(self.func.into()).instantiate(interner, args).skip_binder(); - let environment = db.trait_environment(self.func.into()); + let environment = param_env_from_has_crate(db, self.func); let ty = callable_sig.inputs().as_slice()[0]; Type { env: environment, ty } } @@ -2652,7 +2657,7 @@ impl ExternCrateDecl { pub fn resolved_crate(self, db: &dyn HirDatabase) -> Option<Crate> { let loc = self.id.lookup(db); - let krate = loc.container.krate(); + let krate = loc.container.krate(db); let name = self.name(db); if name == sym::self_ { Some(krate.into()) @@ -3234,8 +3239,8 @@ impl ItemInNs { /// Returns the crate defining this item (or `None` if `self` is built-in). pub fn krate(&self, db: &dyn HirDatabase) -> Option<Crate> { match self { - ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate()), - ItemInNs::Macros(id) => Some(id.module(db).krate()), + ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate(db)), + ItemInNs::Macros(id) => Some(id.module(db).krate(db)), } } @@ -3687,11 +3692,11 @@ impl GenericDef { pub struct GenericSubstitution<'db> { def: GenericDefId, subst: GenericArgs<'db>, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, } impl<'db> GenericSubstitution<'db> { - fn new(def: GenericDefId, subst: GenericArgs<'db>, env: Arc<TraitEnvironment<'db>>) -> Self { + fn new(def: GenericDefId, subst: GenericArgs<'db>, env: ParamEnvAndCrate<'db>) -> Self { Self { def, subst, env } } @@ -3737,9 +3742,7 @@ impl<'db> GenericSubstitution<'db> { .zip(type_params); container_params .chain(self_params) - .filter_map(|(ty, name)| { - Some((name?.symbol().clone(), Type { ty, env: self.env.clone() })) - }) + .filter_map(|(ty, name)| Some((name?.symbol().clone(), Type { ty, env: self.env }))) .collect() } } @@ -4320,7 +4323,7 @@ impl Impl { } pub fn all_in_module(db: &dyn HirDatabase, module: Module) -> Vec<Impl> { - module.id.def_map(db)[module.id.local_id].scope.impls().map(Into::into).collect() + module.id.def_map(db)[module.id].scope.impls().map(Into::into).collect() } /// **Note:** This is an **approximation** that strives to give the *human-perceived notion* of an "impl for type", @@ -4345,15 +4348,13 @@ impl Impl { if let Some(module) = method_resolution::simplified_type_module(db, &simplified_ty) { InherentImpls::for_each_crate_and_block( db, - module.krate(), - module.containing_block(), + module.krate(db), + module.block(db), &mut |impls| extend_with_impls(impls.for_self_ty(&simplified_ty)), ); - std::iter::successors(module.containing_block(), |block| { - block.loc(db).module.containing_block() - }) - .filter_map(|block| TraitImpls::for_block(db, block).as_deref()) - .for_each(|impls| impls.for_self_ty(&simplified_ty, &mut extend_with_impls)); + std::iter::successors(module.block(db), |block| block.loc(db).module.block(db)) + .filter_map(|block| TraitImpls::for_block(db, block).as_deref()) + .for_each(|impls| impls.for_self_ty(&simplified_ty, &mut extend_with_impls)); for &krate in &**db.all_crates() { TraitImpls::for_crate(db, krate) .for_self_ty(&simplified_ty, &mut extend_with_impls); @@ -4373,10 +4374,10 @@ impl Impl { let mut handle_impls = |impls: &TraitImpls| { impls.for_trait(trait_.id, |impls| all.extend(impls.iter().copied().map(Impl::from))); }; - for krate in module.krate().transitive_rev_deps(db) { + for krate in module.krate(db).transitive_rev_deps(db) { handle_impls(TraitImpls::for_crate(db, krate)); } - if let Some(block) = module.containing_block() + if let Some(block) = module.block(db) && let Some(impls) = TraitImpls::for_block(db, block) { handle_impls(impls); @@ -4428,7 +4429,7 @@ impl Impl { MacroCallKind::Derive { ast_id, derive_attr_index, derive_index, .. } => { let module_id = self.id.lookup(db).container; ( - crate_def_map(db, module_id.krate())[module_id.local_id] + module_id.def_map(db)[module_id] .scope .derive_macro_invoc(ast_id, derive_attr_index)?, derive_index, @@ -4459,7 +4460,7 @@ impl Impl { #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct TraitRef<'db> { - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, trait_ref: hir_ty::next_solver::TraitRef<'db>, } @@ -4469,9 +4470,7 @@ impl<'db> TraitRef<'db> { resolver: &Resolver<'_>, trait_ref: hir_ty::next_solver::TraitRef<'db>, ) -> Self { - let env = resolver - .generic_def() - .map_or_else(|| TraitEnvironment::empty(resolver.krate()), |d| db.trait_environment(d)); + let env = param_env_from_resolver(db, resolver); TraitRef { env, trait_ref } } @@ -4481,7 +4480,7 @@ impl<'db> TraitRef<'db> { pub fn self_ty(&self) -> TypeNs<'_> { let ty = self.trait_ref.self_ty(); - TypeNs { env: self.env.clone(), ty } + TypeNs { env: self.env, ty } } /// Returns `idx`-th argument of this trait reference if it is a type argument. Note that the @@ -4492,7 +4491,7 @@ impl<'db> TraitRef<'db> { .as_slice() .get(idx) .and_then(|arg| arg.ty()) - .map(|ty| TypeNs { env: self.env.clone(), ty }) + .map(|ty| TypeNs { env: self.env, ty }) } } @@ -4556,11 +4555,8 @@ impl<'db> Closure<'db> { let owner = db.lookup_intern_closure(id).0; let infer = InferenceResult::for_body(db, owner); let (captures, _) = infer.closure_info(id); - let env = db.trait_environment_for_body(owner); - captures - .iter() - .map(|capture| Type { env: env.clone(), ty: capture.ty(db, self.subst) }) - .collect() + let env = body_param_env_from_has_crate(db, owner); + captures.iter().map(|capture| Type { env, ty: capture.ty(db, self.subst) }).collect() } pub fn fn_trait(&self, db: &dyn HirDatabase) -> FnTrait { @@ -4768,7 +4764,7 @@ impl CaptureUsageSource { #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct Type<'db> { - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, ty: Ty<'db>, } @@ -4786,21 +4782,17 @@ impl<'db> Type<'db> { resolver: &Resolver<'_>, ty: Ty<'db>, ) -> Self { - let environment = resolver - .generic_def() - .map_or_else(|| TraitEnvironment::empty(resolver.krate()), |d| db.trait_environment(d)); + let environment = param_env_from_resolver(db, resolver); Type { env: environment, ty } } pub(crate) fn new_for_crate(krate: base_db::Crate, ty: Ty<'db>) -> Self { - Type { env: TraitEnvironment::empty(krate), ty } + Type { env: empty_param_env(krate), ty } } fn new(db: &'db dyn HirDatabase, lexical_env: impl HasResolver, ty: Ty<'db>) -> Self { let resolver = lexical_env.resolver(db); - let environment = resolver - .generic_def() - .map_or_else(|| TraitEnvironment::empty(resolver.krate()), |d| db.trait_environment(d)); + let environment = param_env_from_resolver(db, &resolver); Type { env: environment, ty } } @@ -4856,7 +4848,7 @@ impl<'db> Type<'db> { pub fn new_tuple(krate: base_db::Crate, tys: &[Self]) -> Self { let tys = tys.iter().map(|it| it.ty); let interner = DbInterner::conjure(); - Type { env: TraitEnvironment::empty(krate), ty: Ty::new_tup_from_iter(interner, tys) } + Type { env: empty_param_env(krate), ty: Ty::new_tup_from_iter(interner, tys) } } pub fn is_unit(&self) -> bool { @@ -5046,7 +5038,7 @@ impl<'db> Type<'db> { }) .or(lang_items.Future)?; - if !traits::implements_trait_unique(self.ty, db, self.env.clone(), trait_) { + if !traits::implements_trait_unique(self.ty, db, self.env, trait_) { return None; } @@ -5077,7 +5069,7 @@ impl<'db> Type<'db> { let Some(iterator_trait) = lang_items.Iterator else { return false; }; - traits::implements_trait_unique(self.ty, db, self.env.clone(), iterator_trait) + traits::implements_trait_unique(self.ty, db, self.env, iterator_trait) } /// Resolves the projection `<Self as IntoIterator>::IntoIter` and returns the resulting type @@ -5089,7 +5081,7 @@ impl<'db> Type<'db> { Some(into_iter_trait.id) })?; - if !traits::implements_trait_unique(self.ty, db, self.env.clone(), trait_) { + if !traits::implements_trait_unique(self.ty, db, self.env, trait_) { return None; } @@ -5110,7 +5102,7 @@ impl<'db> Type<'db> { None => return false, }; - traits::implements_trait_unique(self.ty, db, self.env.clone(), fnonce_trait) + traits::implements_trait_unique(self.ty, db, self.env, fnonce_trait) } // FIXME: Find better API that also handles const generics @@ -5121,7 +5113,7 @@ impl<'db> Type<'db> { trait_.id.into(), std::iter::once(self.ty).chain(args.iter().map(|ty| ty.ty)), ); - traits::implements_trait_unique_with_args(db, self.env.clone(), trait_.id, args) + traits::implements_trait_unique_with_args(db, self.env, trait_.id, args) } pub fn normalize_trait_assoc_type( @@ -5144,7 +5136,7 @@ impl<'db> Type<'db> { ); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); - let ty = structurally_normalize_ty(&infcx, projection, self.env.clone()); + let ty = structurally_normalize_ty(&infcx, projection, self.env.param_env); if ty.is_ty_error() { None } else { Some(self.derived(ty)) } } @@ -5166,8 +5158,7 @@ impl<'db> Type<'db> { // This will happen when it implements fn or fn mut, since we add an autoborrow adjustment TyKind::Ref(_, inner_ty, _) => return self.derived(inner_ty).as_callable(db), _ => { - let (fn_trait, sig) = - hir_ty::callable_sig_from_fn_trait(self.ty, self.env.clone(), db)?; + let (fn_trait, sig) = hir_ty::callable_sig_from_fn_trait(self.ty, self.env, db)?; return Some(Callable { ty: self.clone(), sig, @@ -5291,7 +5282,7 @@ impl<'db> Type<'db> { let interner = DbInterner::new_no_crate(db); // There should be no inference vars in types passed here let canonical = hir_ty::replace_errors_with_variables(interner, &self.ty); - autoderef(db, self.env.clone(), canonical) + autoderef(db, self.env, canonical) } // This would be nicer if it just returned an iterator, but that runs into @@ -5336,8 +5327,8 @@ impl<'db> Type<'db> { if let Some(module) = method_resolution::simplified_type_module(db, &simplified_type) { InherentImpls::for_each_crate_and_block( db, - module.krate(), - module.containing_block(), + module.krate(db), + module.block(db), &mut |impls| { handle_impls(impls.for_self_ty(&simplified_type)); }, @@ -5473,17 +5464,15 @@ impl<'db> Type<'db> { f: impl FnOnce(&MethodResolutionContext<'_, 'db>) -> R, ) -> R { let module = resolver.module(); - let interner = DbInterner::new_with(db, module.krate()); + let interner = DbInterner::new_with(db, module.krate(db)); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); let unstable_features = MethodResolutionUnstableFeatures::from_def_map(resolver.top_level_def_map()); - let environment = resolver - .generic_def() - .map_or_else(|| TraitEnvironment::empty(module.krate()), |d| db.trait_environment(d)); + let environment = param_env_from_resolver(db, resolver); let ctx = MethodResolutionContext { infcx: &infcx, resolver, - env: &environment, + param_env: environment.param_env, traits_in_scope, edition: resolver.krate().data(db).edition, unstable_features: &unstable_features, @@ -5704,7 +5693,13 @@ impl<'db> Type<'db> { .filter(|ty| matches!(ty.kind(), TyKind::Param(_))) .flat_map(|ty| { self.env - .traits_in_scope_from_clauses(ty) + .param_env + .clauses() + .iter() + .filter_map(move |pred| match pred.kind().skip_binder() { + ClauseKind::Trait(tr) if tr.self_ty() == ty => Some(tr.def_id().0), + _ => None, + }) .flat_map(|t| hir_ty::all_super_traits(db, t)) }) .map(Trait::from) @@ -5728,7 +5723,7 @@ impl<'db> Type<'db> { } fn derived(&self, ty: Ty<'db>) -> Self { - Type { env: self.env.clone(), ty } + Type { env: self.env, ty } } /// Visits every type, including generic arguments, in this type. `callback` is called with type @@ -5736,7 +5731,7 @@ impl<'db> Type<'db> { pub fn walk(&self, db: &'db dyn HirDatabase, callback: impl FnMut(Type<'db>)) { struct Visitor<'db, F> { db: &'db dyn HirDatabase, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, callback: F, visited: FxHashSet<Ty<'db>>, } @@ -5751,7 +5746,7 @@ impl<'db> Type<'db> { return; } - (self.callback)(Type { env: self.env.clone(), ty }); + (self.callback)(Type { env: self.env, ty }); if let Some(bounds) = ty.impl_trait_bounds(self.db) { bounds.visit_with(self); @@ -5761,8 +5756,7 @@ impl<'db> Type<'db> { } } - let mut visitor = - Visitor { db, env: self.env.clone(), callback, visited: FxHashSet::default() }; + let mut visitor = Visitor { db, env: self.env, callback, visited: FxHashSet::default() }; self.ty.visit_with(&mut visitor); } /// Check if type unifies with another type. @@ -5772,7 +5766,7 @@ impl<'db> Type<'db> { pub fn could_unify_with(&self, db: &'db dyn HirDatabase, other: &Type<'db>) -> bool { let interner = DbInterner::new_no_crate(db); let tys = hir_ty::replace_errors_with_variables(interner, &(self.ty, other.ty)); - hir_ty::could_unify(db, self.env.clone(), &tys) + hir_ty::could_unify(db, self.env, &tys) } /// Check if type unifies with another type eagerly making sure there are no unresolved goals. @@ -5782,13 +5776,13 @@ impl<'db> Type<'db> { pub fn could_unify_with_deeply(&self, db: &'db dyn HirDatabase, other: &Type<'db>) -> bool { let interner = DbInterner::new_no_crate(db); let tys = hir_ty::replace_errors_with_variables(interner, &(self.ty, other.ty)); - hir_ty::could_unify_deeply(db, self.env.clone(), &tys) + hir_ty::could_unify_deeply(db, self.env, &tys) } pub fn could_coerce_to(&self, db: &'db dyn HirDatabase, to: &Type<'db>) -> bool { let interner = DbInterner::new_no_crate(db); let tys = hir_ty::replace_errors_with_variables(interner, &(self.ty, to.ty)); - hir_ty::could_coerce(db, self.env.clone(), &tys) + hir_ty::could_coerce(db, self.env, &tys) } pub fn as_type_param(&self, _db: &'db dyn HirDatabase) -> Option<TypeParam> { @@ -5807,34 +5801,32 @@ impl<'db> Type<'db> { } pub fn layout(&self, db: &'db dyn HirDatabase) -> Result<Layout, LayoutError> { - db.layout_of_ty(self.ty, self.env.clone()) + db.layout_of_ty(self.ty, self.env) .map(|layout| Layout(layout, db.target_data_layout(self.env.krate).unwrap())) } pub fn drop_glue(&self, db: &'db dyn HirDatabase) -> DropGlue { let interner = DbInterner::new_with(db, self.env.krate); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); - hir_ty::drop::has_drop_glue(&infcx, self.ty, self.env.clone()) + hir_ty::drop::has_drop_glue(&infcx, self.ty, self.env.param_env) } } #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct TypeNs<'db> { - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, ty: Ty<'db>, } impl<'db> TypeNs<'db> { fn new(db: &'db dyn HirDatabase, lexical_env: impl HasResolver, ty: Ty<'db>) -> Self { let resolver = lexical_env.resolver(db); - let environment = resolver - .generic_def() - .map_or_else(|| TraitEnvironment::empty(resolver.krate()), |d| db.trait_environment(d)); + let environment = param_env_from_resolver(db, &resolver); TypeNs { env: environment, ty } } pub fn to_type(&self, _db: &'db dyn HirDatabase) -> Type<'db> { - Type { env: self.env.clone(), ty: self.ty } + Type { env: self.env, ty: self.ty } } // FIXME: Find better API that also handles const generics @@ -6146,12 +6138,12 @@ impl ScopeDef { pub fn krate(&self, db: &dyn HirDatabase) -> Option<Crate> { match self { - ScopeDef::ModuleDef(it) => it.module(db).map(|m| m.krate()), - ScopeDef::GenericParam(it) => Some(it.module(db).krate()), + ScopeDef::ModuleDef(it) => it.module(db).map(|m| m.krate(db)), + ScopeDef::GenericParam(it) => Some(it.module(db).krate(db)), ScopeDef::ImplSelfType(_) => None, - ScopeDef::AdtSelfType(it) => Some(it.module(db).krate()), - ScopeDef::Local(it) => Some(it.module(db).krate()), - ScopeDef::Label(it) => Some(it.module(db).krate()), + ScopeDef::AdtSelfType(it) => Some(it.module(db).krate(db)), + ScopeDef::Local(it) => Some(it.module(db).krate(db)), + ScopeDef::Label(it) => Some(it.module(db).krate(db)), ScopeDef::Unknown => None, } } @@ -6211,61 +6203,61 @@ pub trait HasCrate { impl<T: hir_def::HasModule> HasCrate for T { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate().into() + self.module(db).krate(db).into() } } impl HasCrate for AssocItem { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Struct { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Union { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Enum { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Field { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.parent_def(db).module(db).krate() + self.parent_def(db).module(db).krate(db) } } impl HasCrate for Variant { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Function { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Const { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for TypeAlias { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } @@ -6277,37 +6269,37 @@ impl HasCrate for Type<'_> { impl HasCrate for Macro { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Trait { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Static { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Adt { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Impl { fn krate(&self, db: &dyn HirDatabase) -> Crate { - self.module(db).krate() + self.module(db).krate(db) } } impl HasCrate for Module { - fn krate(&self, _: &dyn HirDatabase) -> Crate { - Module::krate(*self) + fn krate(&self, db: &dyn HirDatabase) -> Crate { + Module::krate(*self, db) } } @@ -6325,8 +6317,8 @@ impl HasContainer for Module { fn container(&self, db: &dyn HirDatabase) -> ItemContainer { // FIXME: handle block expressions as modules (their parent is in a different DefMap) let def_map = self.id.def_map(db); - match def_map[self.id.local_id].parent { - Some(parent_id) => ItemContainer::Module(Module { id: def_map.module_id(parent_id) }), + match def_map[self.id].parent { + Some(parent_id) => ItemContainer::Module(Module { id: parent_id }), None => ItemContainer::Crate(def_map.krate().into()), } } @@ -6485,7 +6477,7 @@ pub fn resolve_absolute_path<'a, I: Iterator<Item = Symbol> + Clone + 'a>( .filter_map(|&krate| { let segments = segments.clone(); let mut def_map = crate_def_map(db, krate); - let mut module = &def_map[DefMap::ROOT]; + let mut module = &def_map[def_map.root_module_id()]; let mut segments = segments.with_position().peekable(); while let Some((_, segment)) = segments.next_if(|&(position, _)| { !matches!(position, itertools::Position::Last | itertools::Position::Only) @@ -6499,7 +6491,7 @@ pub fn resolve_absolute_path<'a, I: Iterator<Item = Symbol> + Clone + 'a>( _ => None, })?; def_map = res.def_map(db); - module = &def_map[res.local_id]; + module = &def_map[res]; } let (_, item_name) = segments.next()?; let res = module.scope.get(&Name::new_symbol_root(item_name)); @@ -6546,5 +6538,35 @@ fn has_non_default_type_params(db: &dyn HirDatabase, generic_def: GenericDefId) }) } +fn param_env_from_resolver<'db>( + db: &'db dyn HirDatabase, + resolver: &Resolver<'_>, +) -> ParamEnvAndCrate<'db> { + ParamEnvAndCrate { + param_env: resolver + .generic_def() + .map_or_else(ParamEnv::empty, |generic_def| db.trait_environment(generic_def)), + krate: resolver.krate(), + } +} + +fn param_env_from_has_crate<'db>( + db: &'db dyn HirDatabase, + id: impl hir_def::HasModule + Into<GenericDefId> + Copy, +) -> ParamEnvAndCrate<'db> { + ParamEnvAndCrate { param_env: db.trait_environment(id.into()), krate: id.krate(db) } +} + +fn body_param_env_from_has_crate<'db>( + db: &'db dyn HirDatabase, + id: impl hir_def::HasModule + Into<DefWithBodyId> + Copy, +) -> ParamEnvAndCrate<'db> { + ParamEnvAndCrate { param_env: db.trait_environment_for_body(id.into()), krate: id.krate(db) } +} + +fn empty_param_env<'db>(krate: base_db::Crate) -> ParamEnvAndCrate<'db> { + ParamEnvAndCrate { param_env: ParamEnv::empty(), krate } +} + pub use hir_ty::next_solver; pub use hir_ty::setup_tracing; |