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.rs336
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;