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 | 174 |
1 files changed, 99 insertions, 75 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 2146e4db77..2210bb79cd 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -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}, @@ -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())) } @@ -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())) } @@ -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() @@ -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(), + }, )?; 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 } } @@ -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() } } @@ -4459,7 +4462,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 +4472,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 +4482,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 +4493,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 +4557,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 +4766,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 +4784,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 +4850,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 +5040,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 +5071,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 +5083,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 +5104,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 +5115,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 +5138,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 +5160,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 +5284,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 @@ -5477,13 +5470,11 @@ impl<'db> Type<'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 +5695,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 +5725,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 +5733,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 +5748,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 +5758,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 +5768,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 +5778,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 +5803,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 @@ -6546,5 +6540,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; |