Unnamed repository; edit this file 'description' to name the repository.
Remove `TraitEnvironment`
We don't need it anymore; `ParamEnv` is enough.
A lot of code relied on getting the crate from the `TraitEnvironment`. Some had it readily available from other sources, some changed to take a new struct `ParamEnvAndCrate`.
40 files changed, 436 insertions, 459 deletions
diff --git a/crates/hir-ty/src/autoderef.rs b/crates/hir-ty/src/autoderef.rs index 0a36c0e726..abab3bfb25 100644 --- a/crates/hir-ty/src/autoderef.rs +++ b/crates/hir-ty/src/autoderef.rs @@ -8,10 +8,9 @@ use std::fmt; use hir_def::{TraitId, TypeAliasId}; use rustc_type_ir::inherent::{IntoKind, Ty as _}; use tracing::debug; -use triomphe::Arc; use crate::{ - TraitEnvironment, + ParamEnvAndCrate, db::HirDatabase, infer::InferenceContext, next_solver::{ @@ -35,13 +34,13 @@ const AUTODEREF_RECURSION_LIMIT: usize = 20; /// detects a cycle in the deref chain. pub fn autoderef<'db>( db: &'db dyn HirDatabase, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, ty: Canonical<'db, Ty<'db>>, ) -> impl Iterator<Item = Ty<'db>> + use<'db> { let interner = DbInterner::new_with(db, env.krate); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); let (ty, _) = infcx.instantiate_canonical(&ty); - let autoderef = Autoderef::new(&infcx, &env, ty); + let autoderef = Autoderef::new(&infcx, env.param_env, ty); let mut v = Vec::new(); for (ty, _steps) in autoderef { // `ty` may contain unresolved inference variables. Since there's no chance they would be @@ -111,12 +110,12 @@ struct AutoderefTraits { // borrows it. pub(crate) trait AutoderefCtx<'db> { fn infcx(&self) -> &InferCtxt<'db>; - fn env(&self) -> &TraitEnvironment<'db>; + fn param_env(&self) -> ParamEnv<'db>; } pub(crate) struct DefaultAutoderefCtx<'a, 'db> { infcx: &'a InferCtxt<'db>, - env: &'a TraitEnvironment<'db>, + param_env: ParamEnv<'db>, } impl<'db> AutoderefCtx<'db> for DefaultAutoderefCtx<'_, 'db> { #[inline] @@ -124,8 +123,8 @@ impl<'db> AutoderefCtx<'db> for DefaultAutoderefCtx<'_, 'db> { self.infcx } #[inline] - fn env(&self) -> &TraitEnvironment<'db> { - self.env + fn param_env(&self) -> ParamEnv<'db> { + self.param_env } } @@ -136,8 +135,8 @@ impl<'db> AutoderefCtx<'db> for InferenceContextAutoderefCtx<'_, '_, 'db> { &self.0.table.infer_ctxt } #[inline] - fn env(&self) -> &TraitEnvironment<'db> { - &self.0.table.trait_env + fn param_env(&self) -> ParamEnv<'db> { + self.0.table.param_env } } @@ -201,7 +200,7 @@ where // autoderef expect this type to have been structurally normalized. if let TyKind::Alias(..) = ty.kind() { let (normalized_ty, obligations) = - structurally_normalize_ty(self.infcx(), self.env().env, ty)?; + structurally_normalize_ty(self.infcx(), self.param_env(), ty)?; self.state.obligations.extend(obligations); (AutoderefKind::Builtin, normalized_ty) } else { @@ -231,10 +230,10 @@ impl<'a, 'db> Autoderef<'a, 'db> { #[inline] pub(crate) fn new_with_tracking( infcx: &'a InferCtxt<'db>, - env: &'a TraitEnvironment<'db>, + param_env: ParamEnv<'db>, base_ty: Ty<'db>, ) -> Self { - Self::new_impl(DefaultAutoderefCtx { infcx, env }, base_ty) + Self::new_impl(DefaultAutoderefCtx { infcx, param_env }, base_ty) } } @@ -257,10 +256,10 @@ impl<'a, 'db> Autoderef<'a, 'db, usize> { #[inline] pub(crate) fn new( infcx: &'a InferCtxt<'db>, - env: &'a TraitEnvironment<'db>, + param_env: ParamEnv<'db>, base_ty: Ty<'db>, ) -> Self { - Self::new_impl(DefaultAutoderefCtx { infcx, env }, base_ty) + Self::new_impl(DefaultAutoderefCtx { infcx, param_env }, base_ty) } } @@ -292,8 +291,8 @@ where } #[inline] - fn env(&self) -> &TraitEnvironment<'db> { - self.ctx.env() + fn param_env(&self) -> ParamEnv<'db> { + self.ctx.param_env() } #[inline] @@ -339,7 +338,7 @@ where let trait_ref = TraitRef::new(interner, trait_.into(), [ty]); let obligation = - Obligation::new(interner, ObligationCause::new(), self.env().env, trait_ref); + Obligation::new(interner, ObligationCause::new(), self.param_env(), trait_ref); // We detect whether the self type implements `Deref` before trying to // structurally normalize. We use `predicate_may_hold_opaque_types_jank` // to support not-yet-defined opaque types. It will succeed for `impl Deref` @@ -351,7 +350,7 @@ where let (normalized_ty, obligations) = structurally_normalize_ty( self.infcx(), - self.env().env, + self.param_env(), Ty::new_projection(interner, trait_target.into(), [ty]), )?; debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations); diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs index 65250f94c2..012632aa55 100644 --- a/crates/hir-ty/src/consteval.rs +++ b/crates/hir-ty/src/consteval.rs @@ -5,7 +5,7 @@ mod tests; use base_db::Crate; use hir_def::{ - ConstId, EnumVariantId, GeneralConstId, StaticId, + ConstId, EnumVariantId, GeneralConstId, HasModule, StaticId, attrs::AttrFlags, expr_store::Body, hir::{Expr, ExprId}, @@ -16,14 +16,14 @@ use rustc_type_ir::inherent::IntoKind; use triomphe::Arc; use crate::{ - LifetimeElisionKind, MemoryMap, TraitEnvironment, TyLoweringContext, + LifetimeElisionKind, MemoryMap, ParamEnvAndCrate, TyLoweringContext, db::HirDatabase, display::DisplayTarget, infer::InferenceContext, mir::{MirEvalError, MirLowerError}, next_solver::{ - Const, ConstBytes, ConstKind, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, Ty, - ValueConst, + Const, ConstBytes, ConstKind, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, + ParamEnv, Ty, ValueConst, }, }; @@ -85,7 +85,7 @@ pub fn intern_const_ref<'a>( krate: Crate, ) -> Const<'a> { let interner = DbInterner::new_no_crate(db); - let layout = db.layout_of_ty(ty, TraitEnvironment::empty(krate)); + let layout = db.layout_of_ty(ty, ParamEnvAndCrate { param_env: ParamEnv::empty(), krate }); let kind = match value { LiteralConstRef::Int(i) => { // FIXME: We should handle failure of layout better. @@ -207,7 +207,7 @@ pub(crate) fn const_eval_discriminant_variant<'db>( let mir_body = db.monomorphized_mir_body( def, GenericArgs::new_from_iter(interner, []), - db.trait_environment_for_body(def), + ParamEnvAndCrate { param_env: db.trait_environment_for_body(def), krate: def.krate(db) }, )?; let c = interpret_mir(db, mir_body, false, None)?.0?; let c = if is_signed { @@ -259,7 +259,7 @@ pub(crate) fn const_eval_cycle_result<'db>( _: &'db dyn HirDatabase, _: ConstId, _: GenericArgs<'db>, - _: Option<Arc<TraitEnvironment<'db>>>, + _: Option<ParamEnvAndCrate<'db>>, ) -> Result<Const<'db>, ConstEvalError<'db>> { Err(ConstEvalError::MirLowerError(MirLowerError::Loop)) } @@ -282,9 +282,13 @@ pub(crate) fn const_eval_query<'db>( db: &'db dyn HirDatabase, def: ConstId, subst: GenericArgs<'db>, - trait_env: Option<Arc<TraitEnvironment<'db>>>, + trait_env: Option<ParamEnvAndCrate<'db>>, ) -> Result<Const<'db>, ConstEvalError<'db>> { - let body = db.monomorphized_mir_body(def.into(), subst, db.trait_environment(def.into()))?; + let body = db.monomorphized_mir_body( + def.into(), + subst, + ParamEnvAndCrate { param_env: db.trait_environment(def.into()), krate: def.krate(db) }, + )?; let c = interpret_mir(db, body, false, trait_env)?.0?; Ok(c) } @@ -297,7 +301,10 @@ pub(crate) fn const_eval_static_query<'db>( let body = db.monomorphized_mir_body( def.into(), GenericArgs::new_from_iter(interner, []), - db.trait_environment_for_body(def.into()), + ParamEnvAndCrate { + param_env: db.trait_environment_for_body(def.into()), + krate: def.krate(db), + }, )?; let c = interpret_mir(db, body, false, None)?.0?; Ok(c) diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs index df058711a6..f9523e7168 100644 --- a/crates/hir-ty/src/db.rs +++ b/crates/hir-ty/src/db.rs @@ -12,13 +12,16 @@ use salsa::plumbing::AsId; use triomphe::Arc; use crate::{ - ImplTraitId, TraitEnvironment, TyDefId, ValueTyDefId, + ImplTraitId, TyDefId, ValueTyDefId, consteval::ConstEvalError, dyn_compatibility::DynCompatibilityViolation, layout::{Layout, LayoutError}, lower::{Diagnostics, GenericDefaults}, mir::{BorrowckResult, MirBody, MirLowerError}, - next_solver::{Const, EarlyBinder, GenericArgs, PolyFnSig, TraitRef, Ty, VariancesOf}, + next_solver::{ + Const, EarlyBinder, GenericArgs, ParamEnv, PolyFnSig, TraitRef, Ty, VariancesOf, + }, + traits::ParamEnvAndCrate, }; #[query_group::query_group] @@ -46,7 +49,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { &'db self, def: DefWithBodyId, subst: GenericArgs<'db>, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, ) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>>; #[salsa::invoke(crate::mir::monomorphized_mir_body_for_closure_query)] @@ -54,7 +57,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { &'db self, def: InternedClosureId, subst: GenericArgs<'db>, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, ) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>>; #[salsa::invoke(crate::mir::borrowck_query)] @@ -70,7 +73,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { &'db self, def: ConstId, subst: GenericArgs<'db>, - trait_env: Option<Arc<TraitEnvironment<'db>>>, + trait_env: Option<ParamEnvAndCrate<'db>>, ) -> Result<Const<'db>, ConstEvalError<'db>>; #[salsa::invoke(crate::consteval::const_eval_static_query)] @@ -88,7 +91,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { #[salsa::transparent] fn lookup_impl_method<'db>( &'db self, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, func: FunctionId, fn_subst: GenericArgs<'db>, ) -> (FunctionId, GenericArgs<'db>); @@ -101,7 +104,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { &'db self, def: AdtId, args: GenericArgs<'db>, - trait_env: Arc<TraitEnvironment<'db>>, + trait_env: ParamEnvAndCrate<'db>, ) -> Result<Arc<Layout>, LayoutError>; #[salsa::invoke(crate::layout::layout_of_ty_query)] @@ -109,7 +112,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { fn layout_of_ty<'db>( &'db self, ty: Ty<'db>, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, ) -> Result<Arc<Layout>, LayoutError>; #[salsa::invoke(crate::layout::target_data_layout_query)] @@ -186,11 +189,10 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { #[salsa::invoke(crate::lower::trait_environment_for_body_query)] #[salsa::transparent] - fn trait_environment_for_body<'db>(&'db self, def: DefWithBodyId) - -> Arc<TraitEnvironment<'db>>; + fn trait_environment_for_body<'db>(&'db self, def: DefWithBodyId) -> ParamEnv<'db>; #[salsa::invoke(crate::lower::trait_environment_query)] - fn trait_environment<'db>(&'db self, def: GenericDefId) -> Arc<TraitEnvironment<'db>>; + fn trait_environment<'db>(&'db self, def: GenericDefId) -> ParamEnv<'db>; #[salsa::invoke(crate::lower::generic_defaults_with_diagnostics_query)] #[salsa::cycle(cycle_result = crate::lower::generic_defaults_with_diagnostics_cycle_result)] diff --git a/crates/hir-ty/src/diagnostics/expr.rs b/crates/hir-ty/src/diagnostics/expr.rs index ffbcea4d25..0de7fab8d1 100644 --- a/crates/hir-ty/src/diagnostics/expr.rs +++ b/crates/hir-ty/src/diagnostics/expr.rs @@ -25,7 +25,7 @@ use triomphe::Arc; use typed_arena::Arena; use crate::{ - Adjust, InferenceResult, TraitEnvironment, + Adjust, InferenceResult, db::HirDatabase, diagnostics::match_check::{ self, @@ -33,7 +33,7 @@ use crate::{ }, display::{DisplayTarget, HirDisplay}, next_solver::{ - DbInterner, Ty, TyKind, TypingMode, + DbInterner, ParamEnv, Ty, TyKind, TypingMode, infer::{DbInternerInferExt, InferCtxt}, }, }; @@ -79,7 +79,7 @@ impl BodyValidationDiagnostic { let infer = InferenceResult::for_body(db, owner); let body = db.body(owner); let env = db.trait_environment_for_body(owner); - let interner = DbInterner::new_with(db, env.krate); + let interner = DbInterner::new_with(db, owner.krate(db)); let infcx = interner.infer_ctxt().build(TypingMode::typeck_for_body(interner, owner.into())); let mut validator = ExprValidator { @@ -100,7 +100,7 @@ struct ExprValidator<'db> { owner: DefWithBodyId, body: Arc<Body>, infer: &'db InferenceResult<'db>, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnv<'db>, diagnostics: Vec<BodyValidationDiagnostic>, validate_lints: bool, infcx: InferCtxt<'db>, @@ -210,7 +210,7 @@ impl<'db> ExprValidator<'db> { return; } - let cx = MatchCheckCtx::new(self.owner.module(self.db()), &self.infcx, self.env.clone()); + let cx = MatchCheckCtx::new(self.owner.module(self.db()), &self.infcx, self.env); let pattern_arena = Arena::new(); let mut m_arms = Vec::with_capacity(arms.len()); @@ -332,7 +332,7 @@ impl<'db> ExprValidator<'db> { return; }; let pattern_arena = Arena::new(); - let cx = MatchCheckCtx::new(self.owner.module(self.db()), &self.infcx, self.env.clone()); + let cx = MatchCheckCtx::new(self.owner.module(self.db()), &self.infcx, self.env); for stmt in &**statements { let &Statement::Let { pat, initializer, else_branch: None, .. } = stmt else { continue; diff --git a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index c70c6b6119..e7ee7c62b9 100644 --- a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -14,14 +14,12 @@ use rustc_pattern_analysis::{ use rustc_type_ir::inherent::{AdtDef, IntoKind, SliceLike}; use smallvec::{SmallVec, smallvec}; use stdx::never; -use triomphe::Arc; use crate::{ - TraitEnvironment, db::HirDatabase, inhabitedness::{is_enum_variant_uninhabited_from, is_ty_uninhabited_from}, next_solver::{ - Ty, TyKind, + ParamEnv, Ty, TyKind, infer::{InferCtxt, traits::ObligationCause}, }, }; @@ -76,16 +74,12 @@ pub(crate) struct MatchCheckCtx<'a, 'db> { module: ModuleId, pub(crate) db: &'db dyn HirDatabase, exhaustive_patterns: bool, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnv<'db>, infcx: &'a InferCtxt<'db>, } impl<'a, 'db> MatchCheckCtx<'a, 'db> { - pub(crate) fn new( - module: ModuleId, - infcx: &'a InferCtxt<'db>, - env: Arc<TraitEnvironment<'db>>, - ) -> Self { + pub(crate) fn new(module: ModuleId, infcx: &'a InferCtxt<'db>, env: ParamEnv<'db>) -> Self { let db = infcx.interner.db; let def_map = module.crate_def_map(db); let exhaustive_patterns = def_map.is_unstable_feature_enabled(&sym::exhaustive_patterns); @@ -114,7 +108,7 @@ impl<'a, 'db> MatchCheckCtx<'a, 'db> { } fn is_uninhabited(&self, ty: Ty<'db>) -> bool { - is_ty_uninhabited_from(self.infcx, ty, self.module, self.env.clone()) + is_ty_uninhabited_from(self.infcx, ty, self.module, self.env) } /// Returns whether the given ADT is from another crate declared `#[non_exhaustive]`. @@ -159,7 +153,7 @@ impl<'a, 'db> MatchCheckCtx<'a, 'db> { let ty = field_tys[fid].instantiate(self.infcx.interner, substs); let ty = self .infcx - .at(&ObligationCause::dummy(), self.env.env) + .at(&ObligationCause::dummy(), self.env) .deeply_normalize(ty) .unwrap_or(ty); (fid, ty) @@ -446,11 +440,7 @@ impl<'a, 'db> PatCx for MatchCheckCtx<'a, 'db> { let mut variants = IndexVec::with_capacity(enum_data.variants.len()); for &(variant, _, _) in enum_data.variants.iter() { let is_uninhabited = is_enum_variant_uninhabited_from( - cx.infcx, - variant, - subst, - cx.module, - self.env.clone(), + cx.infcx, variant, subst, cx.module, self.env, ); let visibility = if is_uninhabited { VariantVisibility::Empty diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index c76b8dc5f0..490bf9e81c 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -44,10 +44,9 @@ use rustc_type_ir::{ use smallvec::SmallVec; use span::Edition; use stdx::never; -use triomphe::Arc; use crate::{ - CallableDefId, FnAbi, ImplTraitId, InferenceResult, MemoryMap, TraitEnvironment, consteval, + CallableDefId, FnAbi, ImplTraitId, InferenceResult, MemoryMap, ParamEnvAndCrate, consteval, db::{HirDatabase, InternedClosure, InternedCoroutine}, generics::generics, layout::Layout, @@ -55,8 +54,8 @@ use crate::{ mir::pad16, next_solver::{ AliasTy, Clause, ClauseKind, Const, ConstKind, DbInterner, EarlyBinder, - ExistentialPredicate, FnSig, GenericArg, GenericArgs, PolyFnSig, Region, SolverDefId, Term, - TraitRef, Ty, TyKind, TypingMode, + ExistentialPredicate, FnSig, GenericArg, GenericArgs, ParamEnv, PolyFnSig, Region, + SolverDefId, Term, TraitRef, Ty, TyKind, TypingMode, abi::Safety, infer::{DbInternerInferExt, traits::ObligationCause}, }, @@ -716,10 +715,10 @@ fn render_const_scalar<'db>( memory_map: &MemoryMap<'db>, ty: Ty<'db>, ) -> Result<(), HirDisplayError> { - let trait_env = TraitEnvironment::empty(f.krate()); + let param_env = ParamEnv::empty(); let infcx = f.interner.infer_ctxt().build(TypingMode::PostAnalysis); - let ty = infcx.at(&ObligationCause::new(), trait_env.env).deeply_normalize(ty).unwrap_or(ty); - render_const_scalar_inner(f, b, memory_map, ty, trait_env) + let ty = infcx.at(&ObligationCause::new(), param_env).deeply_normalize(ty).unwrap_or(ty); + render_const_scalar_inner(f, b, memory_map, ty, param_env) } fn render_const_scalar_inner<'db>( @@ -727,9 +726,10 @@ fn render_const_scalar_inner<'db>( b: &[u8], memory_map: &MemoryMap<'db>, ty: Ty<'db>, - trait_env: Arc<TraitEnvironment<'db>>, + param_env: ParamEnv<'db>, ) -> Result<(), HirDisplayError> { use TyKind; + let param_env = ParamEnvAndCrate { param_env, krate: f.krate() }; match ty.kind() { TyKind::Bool => write!(f, "{}", b[0] != 0), TyKind::Char => { @@ -792,7 +792,7 @@ fn render_const_scalar_inner<'db>( TyKind::Slice(ty) => { let addr = usize::from_le_bytes(b[0..b.len() / 2].try_into().unwrap()); let count = usize::from_le_bytes(b[b.len() / 2..].try_into().unwrap()); - let Ok(layout) = f.db.layout_of_ty(ty, trait_env) else { + let Ok(layout) = f.db.layout_of_ty(ty, param_env) else { return f.write_str("<layout-error>"); }; let size_one = layout.size.bytes_usize(); @@ -826,7 +826,7 @@ fn render_const_scalar_inner<'db>( let Ok(t) = memory_map.vtable_ty(ty_id) else { return f.write_str("<ty-missing-in-vtable-map>"); }; - let Ok(layout) = f.db.layout_of_ty(t, trait_env) else { + let Ok(layout) = f.db.layout_of_ty(t, param_env) else { return f.write_str("<layout-error>"); }; let size = layout.size.bytes_usize(); @@ -856,7 +856,7 @@ fn render_const_scalar_inner<'db>( return f.write_str("<layout-error>"); } }); - let Ok(layout) = f.db.layout_of_ty(t, trait_env) else { + let Ok(layout) = f.db.layout_of_ty(t, param_env) else { return f.write_str("<layout-error>"); }; let size = layout.size.bytes_usize(); @@ -868,7 +868,7 @@ fn render_const_scalar_inner<'db>( } }, TyKind::Tuple(tys) => { - let Ok(layout) = f.db.layout_of_ty(ty, trait_env.clone()) else { + let Ok(layout) = f.db.layout_of_ty(ty, param_env) else { return f.write_str("<layout-error>"); }; f.write_str("(")?; @@ -880,7 +880,7 @@ fn render_const_scalar_inner<'db>( f.write_str(", ")?; } let offset = layout.fields.offset(id).bytes_usize(); - let Ok(layout) = f.db.layout_of_ty(ty, trait_env.clone()) else { + let Ok(layout) = f.db.layout_of_ty(ty, param_env) else { f.write_str("<layout-error>")?; continue; }; @@ -891,7 +891,7 @@ fn render_const_scalar_inner<'db>( } TyKind::Adt(def, args) => { let def = def.def_id().0; - let Ok(layout) = f.db.layout_of_adt(def, args, trait_env.clone()) else { + let Ok(layout) = f.db.layout_of_adt(def, args, param_env) else { return f.write_str("<layout-error>"); }; match def { @@ -914,7 +914,7 @@ fn render_const_scalar_inner<'db>( write!(f, "{}", f.db.union_signature(u).name.display(f.db, f.edition())) } hir_def::AdtId::EnumId(e) => { - let Ok(target_data_layout) = f.db.target_data_layout(trait_env.krate) else { + let Ok(target_data_layout) = f.db.target_data_layout(f.krate()) else { return f.write_str("<target-layout-not-available>"); }; let Some((var_id, var_layout)) = @@ -954,7 +954,7 @@ fn render_const_scalar_inner<'db>( let Some(len) = consteval::try_const_usize(f.db, len) else { return f.write_str("<unknown-array-len>"); }; - let Ok(layout) = f.db.layout_of_ty(ty, trait_env) else { + let Ok(layout) = f.db.layout_of_ty(ty, param_env) else { return f.write_str("<layout-error>"); }; let size_one = layout.size.bytes_usize(); @@ -995,18 +995,19 @@ fn render_variant_after_name<'db>( data: &VariantFields, f: &mut HirFormatter<'_, 'db>, field_types: &ArenaMap<LocalFieldId, EarlyBinder<'db, Ty<'db>>>, - trait_env: Arc<TraitEnvironment<'db>>, + param_env: ParamEnv<'db>, layout: &Layout, args: GenericArgs<'db>, b: &[u8], memory_map: &MemoryMap<'db>, ) -> Result<(), HirDisplayError> { + let param_env = ParamEnvAndCrate { param_env, krate: f.krate() }; match data.shape { FieldsShape::Record | FieldsShape::Tuple => { let render_field = |f: &mut HirFormatter<'_, 'db>, id: LocalFieldId| { let offset = layout.fields.offset(u32::from(id.into_raw()) as usize).bytes_usize(); let ty = field_types[id].instantiate(f.interner, args); - let Ok(layout) = f.db.layout_of_ty(ty, trait_env.clone()) else { + let Ok(layout) = f.db.layout_of_ty(ty, param_env) else { return f.write_str("<layout-error>"); }; let size = layout.size.bytes_usize(); diff --git a/crates/hir-ty/src/drop.rs b/crates/hir-ty/src/drop.rs index d76de4b8ca..def3c44927 100644 --- a/crates/hir-ty/src/drop.rs +++ b/crates/hir-ty/src/drop.rs @@ -4,13 +4,12 @@ use hir_def::{AdtId, signatures::StructFlags}; use rustc_hash::FxHashSet; use rustc_type_ir::inherent::{AdtDef, IntoKind, SliceLike}; use stdx::never; -use triomphe::Arc; use crate::{ - InferenceResult, TraitEnvironment, consteval, + InferenceResult, consteval, method_resolution::TraitImpls, next_solver::{ - DbInterner, SimplifiedType, Ty, TyKind, + DbInterner, ParamEnv, SimplifiedType, Ty, TyKind, infer::{InferCtxt, traits::ObligationCause}, obligation_ctxt::ObligationCtxt, }, @@ -47,22 +46,18 @@ pub enum DropGlue { HasDropGlue, } -pub fn has_drop_glue<'db>( - infcx: &InferCtxt<'db>, - ty: Ty<'db>, - env: Arc<TraitEnvironment<'db>>, -) -> DropGlue { +pub fn has_drop_glue<'db>(infcx: &InferCtxt<'db>, ty: Ty<'db>, env: ParamEnv<'db>) -> DropGlue { has_drop_glue_impl(infcx, ty, env, &mut FxHashSet::default()) } fn has_drop_glue_impl<'db>( infcx: &InferCtxt<'db>, ty: Ty<'db>, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnv<'db>, visited: &mut FxHashSet<Ty<'db>>, ) -> DropGlue { let mut ocx = ObligationCtxt::new(infcx); - let ty = ocx.structurally_normalize_ty(&ObligationCause::dummy(), env.env, ty).unwrap_or(ty); + let ty = ocx.structurally_normalize_ty(&ObligationCause::dummy(), env, ty).unwrap_or(ty); if !visited.insert(ty) { // Recursive type. @@ -91,7 +86,7 @@ fn has_drop_glue_impl<'db>( has_drop_glue_impl( infcx, field_ty.instantiate(infcx.interner, subst), - env.clone(), + env, visited, ) }) @@ -111,7 +106,7 @@ fn has_drop_glue_impl<'db>( has_drop_glue_impl( infcx, field_ty.instantiate(infcx.interner, subst), - env.clone(), + env, visited, ) }) @@ -124,7 +119,7 @@ fn has_drop_glue_impl<'db>( } TyKind::Tuple(tys) => tys .iter() - .map(|ty| has_drop_glue_impl(infcx, ty, env.clone(), visited)) + .map(|ty| has_drop_glue_impl(infcx, ty, env, visited)) .max() .unwrap_or(DropGlue::None), TyKind::Array(ty, len) => { @@ -142,9 +137,7 @@ fn has_drop_glue_impl<'db>( let env = db.trait_environment_for_body(owner); captures .iter() - .map(|capture| { - has_drop_glue_impl(infcx, capture.ty(db, subst), env.clone(), visited) - }) + .map(|capture| has_drop_glue_impl(infcx, capture.ty(db, subst), env, visited)) .max() .unwrap_or(DropGlue::None) } @@ -169,14 +162,14 @@ fn has_drop_glue_impl<'db>( | TyKind::Placeholder(..) => DropGlue::None, TyKind::Dynamic(..) => DropGlue::HasDropGlue, TyKind::Alias(..) => { - if infcx.type_is_copy_modulo_regions(env.env, ty) { + if infcx.type_is_copy_modulo_regions(env, ty) { DropGlue::None } else { DropGlue::HasDropGlue } } TyKind::Param(_) => { - if infcx.type_is_copy_modulo_regions(env.env, ty) { + if infcx.type_is_copy_modulo_regions(env, ty) { DropGlue::None } else { DropGlue::DependOnParams diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index ab173799bc..cafe032969 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -944,7 +944,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { resolver: Resolver<'db>, ) -> Self { let trait_env = db.trait_environment_for_body(owner); - let table = unify::InferenceTable::new(db, trait_env, Some(owner)); + let table = unify::InferenceTable::new(db, trait_env, resolver.krate(), Some(owner)); let types = InternedStandardTypes::new(table.interner()); InferenceContext { result: InferenceResult::new(types.error), diff --git a/crates/hir-ty/src/infer/autoderef.rs b/crates/hir-ty/src/infer/autoderef.rs index 1af102af23..b54a6cdee2 100644 --- a/crates/hir-ty/src/infer/autoderef.rs +++ b/crates/hir-ty/src/infer/autoderef.rs @@ -16,11 +16,11 @@ use crate::{ impl<'db> InferenceTable<'db> { pub(crate) fn autoderef(&self, base_ty: Ty<'db>) -> Autoderef<'_, 'db, usize> { - Autoderef::new(&self.infer_ctxt, &self.trait_env, base_ty) + Autoderef::new(&self.infer_ctxt, self.param_env, base_ty) } pub(crate) fn autoderef_with_tracking(&self, base_ty: Ty<'db>) -> Autoderef<'_, 'db> { - Autoderef::new_with_tracking(&self.infer_ctxt, &self.trait_env, base_ty) + Autoderef::new_with_tracking(&self.infer_ctxt, self.param_env, base_ty) } } diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs index 89ebd2b21d..14b0c9076c 100644 --- a/crates/hir-ty/src/infer/closure.rs +++ b/crates/hir-ty/src/infer/closure.rs @@ -367,7 +367,7 @@ impl<'db> InferenceContext<'_, 'db> { _ = self .table .infer_ctxt - .at(&ObligationCause::new(), self.table.trait_env.env) + .at(&ObligationCause::new(), self.table.param_env) .eq(inferred_fnptr_sig, generalized_fnptr_sig) .map(|infer_ok| self.table.register_infer_ok(infer_ok)); @@ -749,19 +749,18 @@ impl<'db> InferenceContext<'_, 'db> { { // Check that E' = S'. let cause = ObligationCause::new(); - let InferOk { value: (), obligations } = table - .infer_ctxt - .at(&cause, table.trait_env.env) - .eq(expected_ty, supplied_ty)?; + let InferOk { value: (), obligations } = + table.infer_ctxt.at(&cause, table.param_env).eq(expected_ty, supplied_ty)?; all_obligations.extend(obligations); } let supplied_output_ty = supplied_sig.output(); let cause = ObligationCause::new(); - let InferOk { value: (), obligations } = table - .infer_ctxt - .at(&cause, table.trait_env.env) - .eq(expected_sigs.liberated_sig.output(), supplied_output_ty)?; + let InferOk { value: (), obligations } = + table + .infer_ctxt + .at(&cause, table.param_env) + .eq(expected_sigs.liberated_sig.output(), supplied_output_ty)?; all_obligations.extend(obligations); let inputs = supplied_sig diff --git a/crates/hir-ty/src/infer/coerce.rs b/crates/hir-ty/src/infer/coerce.rs index df24148920..77c7155550 100644 --- a/crates/hir-ty/src/infer/coerce.rs +++ b/crates/hir-ty/src/infer/coerce.rs @@ -50,10 +50,9 @@ use rustc_type_ir::{ }; use smallvec::{SmallVec, smallvec}; use tracing::{debug, instrument}; -use triomphe::Arc; use crate::{ - Adjust, Adjustment, AutoBorrow, PointerCast, TargetFeatures, TraitEnvironment, + Adjust, Adjustment, AutoBorrow, ParamEnvAndCrate, PointerCast, TargetFeatures, autoderef::Autoderef, db::{HirDatabase, InternedClosureId}, infer::{ @@ -62,7 +61,7 @@ use crate::{ next_solver::{ Binder, BoundConst, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, CallableIdWrapper, Canonical, ClauseKind, CoercePredicate, Const, ConstKind, DbInterner, ErrorGuaranteed, - GenericArgs, PolyFnSig, PredicateKind, Region, RegionKind, TraitRef, Ty, TyKind, + GenericArgs, ParamEnv, PolyFnSig, PredicateKind, Region, RegionKind, TraitRef, Ty, TyKind, TypingMode, infer::{ DbInternerInferExt, InferCtxt, InferOk, InferResult, @@ -77,7 +76,7 @@ use crate::{ trait CoerceDelegate<'db> { fn infcx(&self) -> &InferCtxt<'db>; - fn env(&self) -> &TraitEnvironment<'db>; + fn param_env(&self) -> ParamEnv<'db>; fn target_features(&self) -> (&TargetFeatures<'db>, TargetFeatureIsSafeInTarget); fn set_diverging(&mut self, diverging_ty: Ty<'db>); @@ -137,8 +136,8 @@ where } #[inline] - fn env(&self) -> &TraitEnvironment<'db> { - self.delegate.env() + fn param_env(&self) -> ParamEnv<'db> { + self.delegate.param_env() } #[inline] @@ -169,7 +168,7 @@ where fn unify_raw(&self, a: Ty<'db>, b: Ty<'db>) -> InferResult<'db, Ty<'db>> { debug!("unify(a: {:?}, b: {:?}, use_lub: {})", a, b, self.use_lub); self.infcx().commit_if_ok(|_| { - let at = self.infcx().at(&self.cause, self.env().env); + let at = self.infcx().at(&self.cause, self.param_env()); let res = if self.use_lub { at.lub(b, a) @@ -329,7 +328,7 @@ where obligations.push(Obligation::new( self.interner(), self.cause.clone(), - self.env().env, + self.param_env(), Binder::dummy(PredicateKind::Coerce(CoercePredicate { a: source_ty, b: target_ty, @@ -381,7 +380,7 @@ where let mut first_error = None; let mut r_borrow_var = None; - let mut autoderef = Autoderef::new_with_tracking(self.infcx(), self.env(), a); + let mut autoderef = Autoderef::new_with_tracking(self.infcx(), self.param_env(), a); let mut found = None; for (referent_ty, autoderefs) in autoderef.by_ref() { @@ -684,7 +683,7 @@ where let mut queue: SmallVec<[PredicateObligation<'db>; 4]> = smallvec![Obligation::new( self.interner(), cause, - self.env().env, + self.param_env(), TraitRef::new( self.interner(), coerce_unsized_did.into(), @@ -975,8 +974,8 @@ impl<'db> CoerceDelegate<'db> for InferenceCoercionDelegate<'_, '_, 'db> { &self.0.table.infer_ctxt } #[inline] - fn env(&self) -> &TraitEnvironment<'db> { - &self.0.table.trait_env + fn param_env(&self) -> ParamEnv<'db> { + self.0.table.param_env } #[inline] @@ -1104,12 +1103,8 @@ impl<'db> InferenceContext<'_, 'db> { match self.table.commit_if_ok(|table| { // We need to eagerly handle nested obligations due to lazy norm. let mut ocx = ObligationCtxt::new(&table.infer_ctxt); - let value = ocx.lub( - &ObligationCause::new(), - table.trait_env.env, - prev_ty, - new_ty, - )?; + let value = + ocx.lub(&ObligationCause::new(), table.param_env, prev_ty, new_ty)?; if ocx.try_evaluate_obligations().is_empty() { Ok(InferOk { value, obligations: ocx.into_pending_obligations() }) } else { @@ -1152,7 +1147,7 @@ impl<'db> InferenceContext<'_, 'db> { let sig = self .table .infer_ctxt - .at(&ObligationCause::new(), self.table.trait_env.env) + .at(&ObligationCause::new(), self.table.param_env) .lub(a_sig, b_sig) .map(|ok| self.table.register_infer_ok(ok))?; @@ -1231,7 +1226,7 @@ impl<'db> InferenceContext<'_, 'db> { .commit_if_ok(|table| { table .infer_ctxt - .at(&ObligationCause::new(), table.trait_env.env) + .at(&ObligationCause::new(), table.param_env) .lub(prev_ty, new_ty) }) .unwrap_err()) @@ -1483,7 +1478,7 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> { // // Another example is `break` with no argument expression. assert!(expression_ty.is_unit(), "if let hack without unit type"); - icx.table.infer_ctxt.at(cause, icx.table.trait_env.env).eq(expected, found).map( + icx.table.infer_ctxt.at(cause, icx.table.param_env).eq(expected, found).map( |infer_ok| { icx.table.register_infer_ok(infer_ok); expression_ty @@ -1540,7 +1535,7 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> { pub fn could_coerce<'db>( db: &'db dyn HirDatabase, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, tys: &Canonical<'db, (Ty<'db>, Ty<'db>)>, ) -> bool { coerce(db, env, tys).is_ok() @@ -1548,7 +1543,7 @@ pub fn could_coerce<'db>( struct HirCoercionDelegate<'a, 'db> { infcx: &'a InferCtxt<'db>, - env: &'a TraitEnvironment<'db>, + param_env: ParamEnv<'db>, target_features: &'a TargetFeatures<'db>, } @@ -1558,8 +1553,8 @@ impl<'db> CoerceDelegate<'db> for HirCoercionDelegate<'_, 'db> { self.infcx } #[inline] - fn env(&self) -> &TraitEnvironment<'db> { - self.env + fn param_env(&self) -> ParamEnv<'db> { + self.param_env } fn target_features(&self) -> (&TargetFeatures<'db>, TargetFeatureIsSafeInTarget) { (self.target_features, TargetFeatureIsSafeInTarget::No) @@ -1573,7 +1568,7 @@ impl<'db> CoerceDelegate<'db> for HirCoercionDelegate<'_, 'db> { fn coerce<'db>( db: &'db dyn HirDatabase, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, tys: &Canonical<'db, (Ty<'db>, Ty<'db>)>, ) -> Result<(Vec<Adjustment<'db>>, Ty<'db>), TypeError<DbInterner<'db>>> { let interner = DbInterner::new_with(db, env.krate); @@ -1586,7 +1581,7 @@ fn coerce<'db>( let mut coerce = Coerce { delegate: HirCoercionDelegate { infcx: &infcx, - env: &env, + param_env: env.param_env, target_features: &target_features, }, cause, diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index 01508b0f9b..4e1711e48e 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -4,7 +4,7 @@ use std::{iter::repeat_with, mem}; use either::Either; use hir_def::{ - BlockId, FieldId, GenericDefId, ItemContainerId, Lookup, TupleFieldId, TupleId, + FieldId, GenericDefId, ItemContainerId, Lookup, TupleFieldId, TupleId, expr_store::path::{GenericArgs as HirGenericArgs, Path}, hir::{ Array, AsmOperand, AsmOptions, BinaryOp, BindingAnnotation, Expr, ExprId, ExprOrPatId, @@ -23,7 +23,7 @@ use syntax::ast::RangeOp; use tracing::debug; use crate::{ - Adjust, Adjustment, CallableDefId, DeclContext, DeclOrigin, Rawness, TraitEnvironment, + Adjust, Adjustment, CallableDefId, DeclContext, DeclOrigin, Rawness, autoderef::InferenceContextAutoderef, consteval, db::InternedCoroutine, @@ -377,11 +377,11 @@ impl<'db> InferenceContext<'_, 'db> { ); self.types.bool } - Expr::Block { statements, tail, label, id } => { - self.infer_block(tgt_expr, *id, statements, *tail, *label, expected) + Expr::Block { statements, tail, label, id: _ } => { + self.infer_block(tgt_expr, statements, *tail, *label, expected) } - Expr::Unsafe { id, statements, tail } => { - self.infer_block(tgt_expr, *id, statements, *tail, None, expected) + Expr::Unsafe { id: _, statements, tail } => { + self.infer_block(tgt_expr, statements, *tail, None, expected) } Expr::Const(id) => { self.with_breakable_ctx(BreakableKind::Border, None, None, |this| { @@ -389,8 +389,8 @@ impl<'db> InferenceContext<'_, 'db> { }) .1 } - Expr::Async { id, statements, tail } => { - self.infer_async_block(tgt_expr, id, statements, tail) + Expr::Async { id: _, statements, tail } => { + self.infer_async_block(tgt_expr, statements, tail) } &Expr::Loop { body, label } => { // FIXME: should be: @@ -1167,7 +1167,6 @@ impl<'db> InferenceContext<'_, 'db> { fn infer_async_block( &mut self, tgt_expr: ExprId, - id: &Option<BlockId>, statements: &[Statement], tail: &Option<ExprId>, ) -> Ty<'db> { @@ -1179,7 +1178,7 @@ impl<'db> InferenceContext<'_, 'db> { // FIXME: We should handle async blocks like we handle closures let expected = &Expectation::has_type(ret_ty); let (_, inner_ty) = self.with_breakable_ctx(BreakableKind::Border, None, None, |this| { - let ty = this.infer_block(tgt_expr, *id, statements, *tail, None, expected); + let ty = this.infer_block(tgt_expr, statements, *tail, None, expected); if let Some(target) = expected.only_has_type(&mut this.table) { match this.coerce(tgt_expr.into(), ty, target, AllowTwoPhase::No, ExprIsRead::Yes) { Ok(res) => res, @@ -1447,7 +1446,6 @@ impl<'db> InferenceContext<'_, 'db> { fn infer_block( &mut self, expr: ExprId, - block_id: Option<BlockId>, statements: &[Statement], tail: Option<ExprId>, label: Option<LabelId>, @@ -1455,11 +1453,6 @@ impl<'db> InferenceContext<'_, 'db> { ) -> Ty<'db> { let coerce_ty = expected.coercion_target_type(&mut self.table); let g = self.resolver.update_to_inner_scope(self.db, self.owner, expr); - let prev_env = block_id.map(|block_id| { - let prev_env = self.table.trait_env.clone(); - TraitEnvironment::with_block(&mut self.table.trait_env, block_id); - prev_env - }); let (break_ty, ty) = self.with_breakable_ctx(BreakableKind::Block, Some(coerce_ty), label, |this| { @@ -1566,9 +1559,6 @@ impl<'db> InferenceContext<'_, 'db> { } }); self.resolver.reset_to_guard(g); - if let Some(prev_env) = prev_env { - self.table.trait_env = prev_env; - } break_ty.unwrap_or(ty) } @@ -1974,7 +1964,7 @@ impl<'db> InferenceContext<'_, 'db> { // is polymorphic) and the expected return type. // No argument expectations are produced if unification fails. let origin = ObligationCause::new(); - ocx.sup(&origin, self.table.trait_env.env, expected_output, formal_output)?; + ocx.sup(&origin, self.table.param_env, expected_output, formal_output)?; if !ocx.try_evaluate_obligations().is_empty() { return Err(TypeError::Mismatch); } @@ -2066,7 +2056,7 @@ impl<'db> InferenceContext<'_, 'db> { let formal_ty_error = this .table .infer_ctxt - .at(&ObligationCause::new(), this.table.trait_env.env) + .at(&ObligationCause::new(), this.table.param_env) .eq(formal_input_ty, coerced_ty); // If neither check failed, the types are compatible @@ -2143,7 +2133,7 @@ impl<'db> InferenceContext<'_, 'db> { self.db, GenericDefId::from_callable(self.db, fn_def.0), ); - let param_env = self.table.trait_env.env; + let param_env = self.table.param_env; self.table.register_predicates(clauses_as_obligations( generic_predicates.iter_instantiated_copied(self.interner(), parameters.as_slice()), ObligationCause::new(), @@ -2162,7 +2152,7 @@ impl<'db> InferenceContext<'_, 'db> { self.table.register_predicate(Obligation::new( self.interner(), ObligationCause::new(), - self.table.trait_env.env, + self.table.param_env, TraitRef::new(self.interner(), trait_.into(), substs), )); } diff --git a/crates/hir-ty/src/infer/op.rs b/crates/hir-ty/src/infer/op.rs index 6fbac8f5ae..8236de167f 100644 --- a/crates/hir-ty/src/infer/op.rs +++ b/crates/hir-ty/src/infer/op.rs @@ -343,7 +343,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { let obligation = Obligation::new( self.interner(), cause, - self.table.trait_env.env, + self.table.param_env, TraitRef::new_from_args(self.interner(), trait_did.into(), args), ); let mut ocx = ObligationCtxt::new(self.infcx()); diff --git a/crates/hir-ty/src/infer/opaques.rs b/crates/hir-ty/src/infer/opaques.rs index ba4b53a0d7..ce4597f83d 100644 --- a/crates/hir-ty/src/infer/opaques.rs +++ b/crates/hir-ty/src/infer/opaques.rs @@ -136,7 +136,7 @@ impl<'db> InferenceContext<'_, 'db> { } let cause = ObligationCause::new(); - let at = self.table.infer_ctxt.at(&cause, self.table.trait_env.env); + let at = self.table.infer_ctxt.at(&cause, self.table.param_env); let hidden_type = match at.deeply_normalize(hidden_type) { Ok(hidden_type) => hidden_type, Err(_errors) => OpaqueHiddenType { ty: self.types.error }, diff --git a/crates/hir-ty/src/infer/path.rs b/crates/hir-ty/src/infer/path.rs index 6e3d15893f..301cbf462c 100644 --- a/crates/hir-ty/src/infer/path.rs +++ b/crates/hir-ty/src/infer/path.rs @@ -224,7 +224,7 @@ impl<'db> InferenceContext<'_, 'db> { ) { let interner = self.interner(); let predicates = GenericPredicates::query_all(self.db, def); - let param_env = self.table.trait_env.env; + let param_env = self.table.param_env; self.table.register_predicates(clauses_as_obligations( predicates.iter_instantiated_copied(interner, subst.as_slice()), ObligationCause::new(), @@ -343,7 +343,7 @@ impl<'db> InferenceContext<'_, 'db> { self.table.register_predicate(Obligation::new( self.interner(), ObligationCause::new(), - self.table.trait_env.env, + self.table.param_env, trait_ref, )); args diff --git a/crates/hir-ty/src/infer/place_op.rs b/crates/hir-ty/src/infer/place_op.rs index 9544fb449f..3ef5e5870a 100644 --- a/crates/hir-ty/src/infer/place_op.rs +++ b/crates/hir-ty/src/infer/place_op.rs @@ -124,7 +124,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { ctx.table.register_predicate(Obligation::new( ctx.interner(), ObligationCause::new(), - ctx.table.trait_env.env, + ctx.table.param_env, ClauseKind::ConstArgHasType(ct, ctx.types.usize), )); self_ty = Ty::new_slice(ctx.interner(), element_ty); diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs index bc3c46341c..a5060416a1 100644 --- a/crates/hir-ty/src/infer/unify.rs +++ b/crates/hir-ty/src/infer/unify.rs @@ -2,6 +2,7 @@ use std::fmt; +use base_db::Crate; use hir_def::{AdtId, DefWithBodyId, GenericParamId}; use hir_expand::name::Name; use intern::sym; @@ -12,15 +13,13 @@ use rustc_type_ir::{ solve::Certainty, }; use smallvec::SmallVec; -use triomphe::Arc; use crate::{ - TraitEnvironment, db::HirDatabase, next_solver::{ AliasTy, Canonical, ClauseKind, Const, DbInterner, ErrorGuaranteed, GenericArg, - GenericArgs, Goal, Predicate, PredicateKind, Region, SolverDefId, Term, TraitRef, Ty, - TyKind, TypingMode, + GenericArgs, Goal, ParamEnv, Predicate, PredicateKind, Region, SolverDefId, Term, TraitRef, + Ty, TyKind, TypingMode, fulfill::{FulfillmentCtxt, NextSolverError}, infer::{ DbInternerInferExt, InferCtxt, InferOk, InferResult, @@ -32,7 +31,8 @@ use crate::{ obligation_ctxt::ObligationCtxt, }, traits::{ - FnTrait, NextTraitSolveResult, next_trait_solve_canonical_in_ctxt, next_trait_solve_in_ctxt, + FnTrait, NextTraitSolveResult, ParamEnvAndCrate, next_trait_solve_canonical_in_ctxt, + next_trait_solve_in_ctxt, }, }; @@ -89,7 +89,7 @@ impl<'a, 'db> ProofTreeVisitor<'db> for NestedObligationsForSelfTy<'a, 'db> { /// unresolved goal `T = U`. pub fn could_unify<'db>( db: &'db dyn HirDatabase, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, tys: &Canonical<'db, (Ty<'db>, Ty<'db>)>, ) -> bool { could_unify_impl(db, env, tys, |ctxt| ctxt.try_evaluate_obligations()) @@ -101,7 +101,7 @@ pub fn could_unify<'db>( /// them. For example `Option<T>` and `Option<U>` do not unify as we cannot show that `T = U` pub fn could_unify_deeply<'db>( db: &'db dyn HirDatabase, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, tys: &Canonical<'db, (Ty<'db>, Ty<'db>)>, ) -> bool { could_unify_impl(db, env, tys, |ctxt| ctxt.evaluate_obligations_error_on_ambiguity()) @@ -109,14 +109,14 @@ pub fn could_unify_deeply<'db>( fn could_unify_impl<'db>( db: &'db dyn HirDatabase, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, tys: &Canonical<'db, (Ty<'db>, Ty<'db>)>, select: for<'a> fn(&mut ObligationCtxt<'a, 'db>) -> Vec<NextSolverError<'db>>, ) -> bool { let interner = DbInterner::new_with(db, env.krate); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); let cause = ObligationCause::dummy(); - let at = infcx.at(&cause, env.env); + let at = infcx.at(&cause, env.param_env); let ((ty1_with_vars, ty2_with_vars), _) = infcx.instantiate_canonical(tys); let mut ctxt = ObligationCtxt::new(&infcx); let can_unify = at @@ -129,7 +129,7 @@ fn could_unify_impl<'db>( #[derive(Clone)] pub(crate) struct InferenceTable<'db> { pub(crate) db: &'db dyn HirDatabase, - pub(crate) trait_env: Arc<TraitEnvironment<'db>>, + pub(crate) param_env: ParamEnv<'db>, pub(crate) infer_ctxt: InferCtxt<'db>, pub(super) fulfillment_cx: FulfillmentCtxt<'db>, pub(super) diverging_type_vars: FxHashSet<Ty<'db>>, @@ -145,10 +145,11 @@ impl<'db> InferenceTable<'db> { /// Outside it, always pass `owner = None`. pub(crate) fn new( db: &'db dyn HirDatabase, - trait_env: Arc<TraitEnvironment<'db>>, + trait_env: ParamEnv<'db>, + krate: Crate, owner: Option<DefWithBodyId>, ) -> Self { - let interner = DbInterner::new_with(db, trait_env.krate); + let interner = DbInterner::new_with(db, krate); let typing_mode = match owner { Some(owner) => TypingMode::typeck_for_body(interner, owner.into()), // IDE things wants to reveal opaque types. @@ -157,7 +158,7 @@ impl<'db> InferenceTable<'db> { let infer_ctxt = interner.infer_ctxt().build(typing_mode); InferenceTable { db, - trait_env, + param_env: trait_env, fulfillment_cx: FulfillmentCtxt::new(&infer_ctxt), infer_ctxt, diverging_type_vars: FxHashSet::default(), @@ -170,7 +171,7 @@ impl<'db> InferenceTable<'db> { } pub(crate) fn type_is_copy_modulo_regions(&self, ty: Ty<'db>) -> bool { - self.infer_ctxt.type_is_copy_modulo_regions(self.trait_env.env, ty) + self.infer_ctxt.type_is_copy_modulo_regions(self.param_env, ty) } pub(crate) fn type_var_is_sized(&self, self_ty: TyVid) -> bool { @@ -272,7 +273,7 @@ impl<'db> InferenceTable<'db> { pub(crate) fn normalize_alias_ty(&mut self, alias: Ty<'db>) -> Ty<'db> { self.infer_ctxt - .at(&ObligationCause::new(), self.trait_env.env) + .at(&ObligationCause::new(), self.param_env) .structurally_normalize_ty(alias, &mut self.fulfillment_cx) .unwrap_or(alias) } @@ -332,7 +333,7 @@ impl<'db> InferenceTable<'db> { } pub(crate) fn at<'a>(&'a self, cause: &'a ObligationCause) -> At<'a, 'db> { - self.infer_ctxt.at(cause, self.trait_env.env) + self.infer_ctxt.at(cause, self.param_env) } pub(crate) fn shallow_resolve(&self, ty: Ty<'db>) -> Ty<'db> { @@ -374,7 +375,7 @@ impl<'db> InferenceTable<'db> { // in a reentrant borrow, causing an ICE. let result = self .infer_ctxt - .at(&ObligationCause::misc(), self.trait_env.env) + .at(&ObligationCause::misc(), self.param_env) .structurally_normalize_ty(ty, &mut self.fulfillment_cx); match result { Ok(normalized_ty) => normalized_ty, @@ -422,14 +423,14 @@ impl<'db> InferenceTable<'db> { /// choice (during e.g. method resolution or deref). #[tracing::instrument(level = "debug", skip(self))] pub(crate) fn try_obligation(&mut self, predicate: Predicate<'db>) -> NextTraitSolveResult { - let goal = Goal { param_env: self.trait_env.env, predicate }; + let goal = Goal { param_env: self.param_env, predicate }; let canonicalized = self.canonicalize(goal); next_trait_solve_canonical_in_ctxt(&self.infer_ctxt, canonicalized) } pub(crate) fn register_obligation(&mut self, predicate: Predicate<'db>) { - let goal = Goal { param_env: self.trait_env.env, predicate }; + let goal = Goal { param_env: self.param_env, predicate }; self.register_obligation_in_env(goal) } @@ -486,7 +487,7 @@ impl<'db> InferenceTable<'db> { self.register_predicate(Obligation::new( self.interner(), cause, - self.trait_env.env, + self.param_env, ClauseKind::WellFormed(term), )); } diff --git a/crates/hir-ty/src/inhabitedness.rs b/crates/hir-ty/src/inhabitedness.rs index 5e742bba3e..075a7066db 100644 --- a/crates/hir-ty/src/inhabitedness.rs +++ b/crates/hir-ty/src/inhabitedness.rs @@ -7,14 +7,12 @@ use rustc_type_ir::{ TypeSuperVisitable, TypeVisitable, TypeVisitor, inherent::{AdtDef, IntoKind}, }; -use triomphe::Arc; use crate::{ - TraitEnvironment, consteval::try_const_usize, db::HirDatabase, next_solver::{ - DbInterner, EarlyBinder, GenericArgs, Ty, TyKind, + DbInterner, EarlyBinder, GenericArgs, ParamEnv, Ty, TyKind, infer::{InferCtxt, traits::ObligationCause}, obligation_ctxt::ObligationCtxt, }, @@ -26,7 +24,7 @@ pub(crate) fn is_ty_uninhabited_from<'db>( infcx: &InferCtxt<'db>, ty: Ty<'db>, target_mod: ModuleId, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnv<'db>, ) -> bool { let _p = tracing::info_span!("is_ty_uninhabited_from", ?ty).entered(); let mut uninhabited_from = UninhabitedFrom::new(infcx, target_mod, env); @@ -41,7 +39,7 @@ pub(crate) fn is_enum_variant_uninhabited_from<'db>( variant: EnumVariantId, subst: GenericArgs<'db>, target_mod: ModuleId, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnv<'db>, ) -> bool { let _p = tracing::info_span!("is_enum_variant_uninhabited_from").entered(); @@ -56,7 +54,7 @@ struct UninhabitedFrom<'a, 'db> { // guard for preventing stack overflow in non trivial non terminating types max_depth: usize, infcx: &'a InferCtxt<'db>, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnv<'db>, } const CONTINUE_OPAQUELY_INHABITED: ControlFlow<VisiblyUninhabited> = Continue(()); @@ -78,7 +76,7 @@ impl<'db> TypeVisitor<DbInterner<'db>> for UninhabitedFrom<'_, 'db> { if matches!(ty.kind(), TyKind::Alias(..)) { let mut ocx = ObligationCtxt::new(self.infcx); - match ocx.structurally_normalize_ty(&ObligationCause::dummy(), self.env.env, ty) { + match ocx.structurally_normalize_ty(&ObligationCause::dummy(), self.env, ty) { Ok(it) => ty = it, Err(_) => return CONTINUE_OPAQUELY_INHABITED, } @@ -101,11 +99,7 @@ impl<'db> TypeVisitor<DbInterner<'db>> for UninhabitedFrom<'_, 'db> { } impl<'a, 'db> UninhabitedFrom<'a, 'db> { - fn new( - infcx: &'a InferCtxt<'db>, - target_mod: ModuleId, - env: Arc<TraitEnvironment<'db>>, - ) -> Self { + fn new(infcx: &'a InferCtxt<'db>, target_mod: ModuleId, env: ParamEnv<'db>) -> Self { Self { target_mod, recursive_ty: FxHashSet::default(), max_depth: 500, infcx, env } } diff --git a/crates/hir-ty/src/layout.rs b/crates/hir-ty/src/layout.rs index 97660a67ef..565063fb13 100644 --- a/crates/hir-ty/src/layout.rs +++ b/crates/hir-ty/src/layout.rs @@ -21,7 +21,7 @@ use rustc_type_ir::{ use triomphe::Arc; use crate::{ - InferenceResult, TraitEnvironment, + InferenceResult, ParamEnvAndCrate, consteval::try_const_usize, db::HirDatabase, next_solver::{ @@ -131,7 +131,7 @@ fn layout_of_simd_ty<'db>( id: StructId, repr_packed: bool, args: &GenericArgs<'db>, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, dl: &TargetDataLayout, ) -> Result<Arc<Layout>, LayoutError> { // Supported SIMD vectors are homogeneous ADTs with exactly one array field: @@ -159,7 +159,7 @@ fn layout_of_simd_ty<'db>( pub fn layout_of_ty_query<'db>( db: &'db dyn HirDatabase, ty: Ty<'db>, - trait_env: Arc<TraitEnvironment<'db>>, + trait_env: ParamEnvAndCrate<'db>, ) -> Result<Arc<Layout>, LayoutError> { let krate = trait_env.krate; let interner = DbInterner::new_with(db, krate); @@ -248,10 +248,8 @@ pub fn layout_of_ty_query<'db>( let kind = if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized }; - let fields = tys - .iter() - .map(|k| db.layout_of_ty(k, trait_env.clone())) - .collect::<Result<Vec<_>, _>>()?; + let fields = + tys.iter().map(|k| db.layout_of_ty(k, trait_env)).collect::<Result<Vec<_>, _>>()?; let fields = fields.iter().map(|it| &**it).collect::<Vec<_>>(); let fields = fields.iter().collect::<IndexVec<_, _>>(); cx.calc.univariant(&fields, &ReprOptions::default(), kind)? @@ -329,7 +327,7 @@ pub fn layout_of_ty_query<'db>( .map(|it| { let ty = it.ty.instantiate(interner, args.split_closure_args_untupled().parent_args); - db.layout_of_ty(ty, trait_env.clone()) + db.layout_of_ty(ty, trait_env) }) .collect::<Result<Vec<_>, _>>()?; let fields = fields.iter().map(|it| &**it).collect::<Vec<_>>(); @@ -362,7 +360,7 @@ pub fn layout_of_ty_query<'db>( pub(crate) fn layout_of_ty_cycle_result<'db>( _: &dyn HirDatabase, _: Ty<'db>, - _: Arc<TraitEnvironment<'db>>, + _: ParamEnvAndCrate<'db>, ) -> Result<Arc<Layout>, LayoutError> { Err(LayoutError::RecursiveTypeWithoutIndirection) } diff --git a/crates/hir-ty/src/layout/adt.rs b/crates/hir-ty/src/layout/adt.rs index ecebf7935d..cf2d0989fd 100644 --- a/crates/hir-ty/src/layout/adt.rs +++ b/crates/hir-ty/src/layout/adt.rs @@ -13,7 +13,7 @@ use smallvec::SmallVec; use triomphe::Arc; use crate::{ - TraitEnvironment, + ParamEnvAndCrate, db::HirDatabase, layout::{Layout, LayoutCx, LayoutError, field_ty}, next_solver::GenericArgs, @@ -23,7 +23,7 @@ pub fn layout_of_adt_query<'db>( db: &'db dyn HirDatabase, def: AdtId, args: GenericArgs<'db>, - trait_env: Arc<TraitEnvironment<'db>>, + trait_env: ParamEnvAndCrate<'db>, ) -> Result<Arc<Layout>, LayoutError> { let krate = trait_env.krate; let Ok(target) = db.target_data_layout(krate) else { @@ -34,7 +34,7 @@ pub fn layout_of_adt_query<'db>( let handle_variant = |def: VariantId, var: &VariantFields| { var.fields() .iter() - .map(|(fd, _)| db.layout_of_ty(field_ty(db, def, fd, &args), trait_env.clone())) + .map(|(fd, _)| db.layout_of_ty(field_ty(db, def, fd, &args), trait_env)) .collect::<Result<Vec<_>, _>>() }; let (variants, repr, is_special_no_niche) = match def { @@ -99,7 +99,7 @@ pub(crate) fn layout_of_adt_cycle_result<'db>( _: &'db dyn HirDatabase, _def: AdtId, _args: GenericArgs<'db>, - _trait_env: Arc<TraitEnvironment<'db>>, + _trait_env: ParamEnvAndCrate<'db>, ) -> Result<Arc<Layout>, LayoutError> { Err(LayoutError::RecursiveTypeWithoutIndirection) } diff --git a/crates/hir-ty/src/layout/tests.rs b/crates/hir-ty/src/layout/tests.rs index 878813a696..43215253ba 100644 --- a/crates/hir-ty/src/layout/tests.rs +++ b/crates/hir-ty/src/layout/tests.rs @@ -1,6 +1,6 @@ use base_db::target::TargetData; use either::Either; -use hir_def::db::DefDatabase; +use hir_def::{HasModule, db::DefDatabase}; use project_model::{Sysroot, toolchain_info::QueryConfig}; use rustc_hash::FxHashMap; use rustc_type_ir::inherent::GenericArgs as _; @@ -9,7 +9,7 @@ use test_fixture::WithFixture; use triomphe::Arc; use crate::{ - InferenceResult, + InferenceResult, ParamEnvAndCrate, db::HirDatabase, layout::{Layout, LayoutError}, next_solver::{DbInterner, GenericArgs}, @@ -90,13 +90,15 @@ fn eval_goal( ), Either::Right(ty_id) => db.ty(ty_id.into()).instantiate_identity(), }; - db.layout_of_ty( - goal_ty, - db.trait_environment(match adt_or_type_alias_id { - Either::Left(adt) => hir_def::GenericDefId::AdtId(adt), - Either::Right(ty) => hir_def::GenericDefId::TypeAliasId(ty), - }), - ) + let param_env = db.trait_environment(match adt_or_type_alias_id { + Either::Left(adt) => hir_def::GenericDefId::AdtId(adt), + Either::Right(ty) => hir_def::GenericDefId::TypeAliasId(ty), + }); + let krate = match adt_or_type_alias_id { + Either::Left(it) => it.krate(&db), + Either::Right(it) => it.krate(&db), + }; + db.layout_of_ty(goal_ty, ParamEnvAndCrate { param_env, krate }) }) } @@ -139,7 +141,9 @@ fn eval_expr( .0; let infer = InferenceResult::for_body(&db, function_id.into()); let goal_ty = infer.type_of_binding[b]; - db.layout_of_ty(goal_ty, db.trait_environment(function_id.into())) + let param_env = db.trait_environment(function_id.into()); + let krate = function_id.krate(&db); + db.layout_of_ty(goal_ty, ParamEnvAndCrate { param_env, krate }) }) } diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index 6d3adec6a8..f27962eb85 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -67,7 +67,6 @@ use rustc_type_ir::{ }; use syntax::ast::{ConstArg, make}; use traits::FnTrait; -use triomphe::Arc; use crate::{ db::HirDatabase, @@ -94,7 +93,7 @@ pub use lower::{ }; pub use next_solver::interner::{attach_db, attach_db_allow_change, with_attached_db}; pub use target_feature::TargetFeatures; -pub use traits::{TraitEnvironment, check_orphan_rules}; +pub use traits::{ParamEnvAndCrate, check_orphan_rules}; pub use utils::{ TargetFeatureIsSafeInTarget, Unsafety, all_super_traits, direct_super_traits, is_fn_unsafe_to_call, target_feature_is_safe_in_target, @@ -474,10 +473,10 @@ where /// To be used from `hir` only. pub fn callable_sig_from_fn_trait<'db>( self_ty: Ty<'db>, - trait_env: Arc<TraitEnvironment<'db>>, + trait_env: ParamEnvAndCrate<'db>, db: &'db dyn HirDatabase, ) -> Option<(FnTrait, PolyFnSig<'db>)> { - let mut table = InferenceTable::new(db, trait_env.clone(), None); + let mut table = InferenceTable::new(db, trait_env.param_env, trait_env.krate, None); let lang_items = table.interner().lang_items(); let fn_once_trait = FnTrait::FnOnce.get_id(lang_items)?; diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index cfd2a06b2a..301e89556d 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -53,7 +53,7 @@ use tracing::debug; use triomphe::{Arc, ThinArc}; use crate::{ - FnAbi, ImplTraitId, TraitEnvironment, TyLoweringDiagnostic, TyLoweringDiagnosticKind, + FnAbi, ImplTraitId, TyLoweringDiagnostic, TyLoweringDiagnosticKind, consteval::intern_const_ref, db::{HirDatabase, InternedOpaqueTyId}, generics::{Generics, generics, trait_self_param_idx}, @@ -1743,10 +1743,9 @@ impl<'db> GenericPredicates<'db> { pub(crate) fn trait_environment_for_body_query( db: &dyn HirDatabase, def: DefWithBodyId, -) -> Arc<TraitEnvironment<'_>> { +) -> ParamEnv<'_> { let Some(def) = def.as_generic_def_id(db) else { - let krate = def.module(db).krate(); - return TraitEnvironment::empty(krate); + return ParamEnv::empty(); }; db.trait_environment(def) } @@ -1754,24 +1753,16 @@ pub(crate) fn trait_environment_for_body_query( pub(crate) fn trait_environment_query<'db>( db: &'db dyn HirDatabase, def: GenericDefId, -) -> Arc<TraitEnvironment<'db>> { +) -> ParamEnv<'db> { let module = def.module(db); let interner = DbInterner::new_with(db, module.krate()); let predicates = GenericPredicates::query_all(db, def); - let traits_in_scope = predicates - .iter_identity_copied() - .filter_map(|pred| match pred.kind().skip_binder() { - ClauseKind::Trait(tr) => Some((tr.self_ty(), tr.def_id().0)), - _ => None, - }) - .collect(); let clauses = rustc_type_ir::elaborate::elaborate(interner, predicates.iter_identity_copied()); let clauses = Clauses::new_from_iter(interner, clauses); - let env = ParamEnv { clauses }; // FIXME: We should normalize projections here, like rustc does. - TraitEnvironment::new(module.krate(), module.containing_block(), traits_in_scope, env) + ParamEnv { clauses } } #[derive(Copy, Clone, Debug, PartialEq, Eq)] diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs index 9a6adedb99..a5ec2a3fec 100644 --- a/crates/hir-ty/src/method_resolution.rs +++ b/crates/hir-ty/src/method_resolution.rs @@ -32,13 +32,13 @@ use stdx::impl_from; use triomphe::Arc; use crate::{ - TraitEnvironment, all_super_traits, + all_super_traits, db::HirDatabase, infer::{InferenceContext, unify::InferenceTable}, lower::GenericPredicates, next_solver::{ - Binder, ClauseKind, DbInterner, FnSig, GenericArgs, PredicateKind, SimplifiedType, - SolverDefId, TraitRef, Ty, TyKind, TypingMode, + Binder, ClauseKind, DbInterner, FnSig, GenericArgs, ParamEnv, PredicateKind, + SimplifiedType, SolverDefId, TraitRef, Ty, TyKind, TypingMode, infer::{ BoundRegionConversionTime, DbInternerInferExt, InferCtxt, InferOk, select::ImplSource, @@ -47,6 +47,7 @@ use crate::{ obligation_ctxt::ObligationCtxt, util::clauses_as_obligations, }, + traits::ParamEnvAndCrate, }; pub use self::probe::{ @@ -75,7 +76,7 @@ impl MethodResolutionUnstableFeatures { pub struct MethodResolutionContext<'a, 'db> { pub infcx: &'a InferCtxt<'db>, pub resolver: &'a Resolver<'db>, - pub env: &'a TraitEnvironment<'db>, + pub param_env: ParamEnv<'db>, pub traits_in_scope: &'a FxHashSet<TraitId>, pub edition: Edition, pub unstable_features: &'a MethodResolutionUnstableFeatures, @@ -194,7 +195,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { let ctx = MethodResolutionContext { infcx: &self.table.infer_ctxt, resolver: &self.resolver, - env: &self.table.trait_env, + param_env: self.table.param_env, traits_in_scope, edition: self.edition, unstable_features: &self.unstable_features, @@ -264,7 +265,7 @@ impl<'db> InferenceTable<'db> { let obligation = Obligation::new( self.interner(), cause, - self.trait_env.env, + self.param_env, TraitRef::new_from_args(self.interner(), trait_def_id.into(), args), ); @@ -322,7 +323,7 @@ impl<'db> InferenceTable<'db> { let bounds = clauses_as_obligations( bounds.iter_instantiated_copied(interner, args.as_slice()), ObligationCause::new(), - self.trait_env.env, + self.param_env, ); obligations.extend(bounds); @@ -336,7 +337,7 @@ impl<'db> InferenceTable<'db> { obligations.push(Obligation::new( interner, obligation.cause.clone(), - self.trait_env.env, + self.param_env, Binder::dummy(PredicateKind::Clause(ClauseKind::WellFormed(ty.into()))), )); } @@ -350,7 +351,7 @@ impl<'db> InferenceTable<'db> { pub fn lookup_impl_const<'db>( infcx: &InferCtxt<'db>, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnv<'db>, const_id: ConstId, subs: GenericArgs<'db>, ) -> (ConstId, GenericArgs<'db>) { @@ -380,7 +381,7 @@ pub fn lookup_impl_const<'db>( /// call the method using the vtable. pub fn is_dyn_method<'db>( interner: DbInterner<'db>, - _env: Arc<TraitEnvironment<'db>>, + _env: ParamEnv<'db>, func: FunctionId, fn_subst: GenericArgs<'db>, ) -> Option<usize> { @@ -415,7 +416,7 @@ pub fn is_dyn_method<'db>( /// Returns `func` if it's not a method defined in a trait or the lookup failed. pub(crate) fn lookup_impl_method_query<'db>( db: &'db dyn HirDatabase, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, func: FunctionId, fn_subst: GenericArgs<'db>, ) -> (FunctionId, GenericArgs<'db>) { @@ -433,11 +434,15 @@ pub(crate) fn lookup_impl_method_query<'db>( ); let name = &db.function_signature(func).name; - let Some((impl_fn, impl_subst)) = - lookup_impl_assoc_item_for_trait_ref(&infcx, trait_ref, env, name).and_then(|assoc| { - if let (AssocItemId::FunctionId(id), subst) = assoc { Some((id, subst)) } else { None } - }) - else { + let Some((impl_fn, impl_subst)) = lookup_impl_assoc_item_for_trait_ref( + &infcx, + trait_ref, + env.param_env, + name, + ) + .and_then(|assoc| { + if let (AssocItemId::FunctionId(id), subst) = assoc { Some((id, subst)) } else { None } + }) else { return (func, fn_subst); }; @@ -453,10 +458,10 @@ pub(crate) fn lookup_impl_method_query<'db>( fn lookup_impl_assoc_item_for_trait_ref<'db>( infcx: &InferCtxt<'db>, trait_ref: TraitRef<'db>, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnv<'db>, name: &Name, ) -> Option<(AssocItemId, GenericArgs<'db>)> { - let (impl_id, impl_subst) = find_matching_impl(infcx, &env, trait_ref)?; + let (impl_id, impl_subst) = find_matching_impl(infcx, env, trait_ref)?; let item = impl_id.impl_items(infcx.interner.db).items.iter().find_map(|(n, it)| match *it { AssocItemId::FunctionId(f) => (n == name).then_some(AssocItemId::FunctionId(f)), @@ -468,13 +473,12 @@ fn lookup_impl_assoc_item_for_trait_ref<'db>( pub(crate) fn find_matching_impl<'db>( infcx: &InferCtxt<'db>, - env: &TraitEnvironment<'db>, + env: ParamEnv<'db>, trait_ref: TraitRef<'db>, ) -> Option<(ImplId, GenericArgs<'db>)> { - let trait_ref = - infcx.at(&ObligationCause::dummy(), env.env).deeply_normalize(trait_ref).ok()?; + let trait_ref = infcx.at(&ObligationCause::dummy(), env).deeply_normalize(trait_ref).ok()?; - let obligation = Obligation::new(infcx.interner, ObligationCause::dummy(), env.env, trait_ref); + let obligation = Obligation::new(infcx.interner, ObligationCause::dummy(), env, trait_ref); let selection = infcx.select(&obligation).ok()??; diff --git a/crates/hir-ty/src/method_resolution/confirm.rs b/crates/hir-ty/src/method_resolution/confirm.rs index 570dd63a50..6d6515a457 100644 --- a/crates/hir-ty/src/method_resolution/confirm.rs +++ b/crates/hir-ty/src/method_resolution/confirm.rs @@ -507,7 +507,7 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { GenericPredicates::query_all(self.db(), def_id.into()) .iter_instantiated_copied(self.interner(), all_args), ObligationCause::new(), - self.ctx.table.trait_env.env, + self.ctx.table.param_env, ); let sig = diff --git a/crates/hir-ty/src/method_resolution/probe.rs b/crates/hir-ty/src/method_resolution/probe.rs index adc144ce11..02f86815ed 100644 --- a/crates/hir-ty/src/method_resolution/probe.rs +++ b/crates/hir-ty/src/method_resolution/probe.rs @@ -334,7 +334,7 @@ impl<'a, 'db> MethodResolutionContext<'a, 'db> { .infcx .instantiate_query_response_and_region_obligations( &ObligationCause::new(), - self.env.env, + self.param_env, &orig_values, ty, ) @@ -394,7 +394,7 @@ impl<'a, 'db> MethodResolutionContext<'a, 'db> { // converted to, in order to find out which of those methods might actually // be callable. let mut autoderef_via_deref = - Autoderef::new(infcx, self.env, self_ty).include_raw_pointers(); + Autoderef::new(infcx, self.param_env, self_ty).include_raw_pointers(); let mut reached_raw_pointer = false; let arbitrary_self_types_enabled = self.unstable_features.arbitrary_self_types @@ -403,7 +403,7 @@ impl<'a, 'db> MethodResolutionContext<'a, 'db> { let reachable_via_deref = autoderef_via_deref.by_ref().map(|_| true).chain(std::iter::repeat(false)); - let mut autoderef_via_receiver = Autoderef::new(infcx, self.env, self_ty) + let mut autoderef_via_receiver = Autoderef::new(infcx, self.param_env, self_ty) .include_raw_pointers() .use_receiver_trait(); let steps = autoderef_via_receiver @@ -835,7 +835,7 @@ impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice> { #[inline] fn param_env(&self) -> ParamEnv<'db> { - self.ctx.env.env + self.ctx.param_env } /// When we're looking up a method by path (UFCS), we relate the receiver diff --git a/crates/hir-ty/src/mir/borrowck.rs b/crates/hir-ty/src/mir/borrowck.rs index 2d2fc03dcc..031654a259 100644 --- a/crates/hir-ty/src/mir/borrowck.rs +++ b/crates/hir-ty/src/mir/borrowck.rs @@ -12,12 +12,12 @@ use stdx::never; use triomphe::Arc; use crate::{ - InferenceResult, TraitEnvironment, + InferenceResult, db::{HirDatabase, InternedClosure, InternedClosureId}, display::DisplayTarget, mir::OperandKind, next_solver::{ - DbInterner, GenericArgs, Ty, TypingMode, + DbInterner, GenericArgs, ParamEnv, Ty, TypingMode, infer::{DbInternerInferExt, InferCtxt}, }, }; @@ -107,8 +107,8 @@ pub fn borrowck_query<'db>( let infcx = interner.infer_ctxt().build(typing_mode); res.push(BorrowckResult { mutability_of_locals: mutability_of_locals(&infcx, &body), - moved_out_of_ref: moved_out_of_ref(&infcx, &env, &body), - partially_moved: partially_moved(&infcx, &env, &body), + moved_out_of_ref: moved_out_of_ref(&infcx, env, &body), + partially_moved: partially_moved(&infcx, env, &body), borrow_regions: borrow_regions(db, &body), mir_body: body, }); @@ -131,7 +131,7 @@ fn make_fetch_closure_field<'db>( fn moved_out_of_ref<'db>( infcx: &InferCtxt<'db>, - env: &TraitEnvironment<'db>, + env: ParamEnv<'db>, body: &MirBody<'db>, ) -> Vec<MovedOutOfRef<'db>> { let db = infcx.interner.db; @@ -152,7 +152,7 @@ fn moved_out_of_ref<'db>( ); } if is_dereference_of_ref - && !infcx.type_is_copy_modulo_regions(env.env, ty) + && !infcx.type_is_copy_modulo_regions(env, ty) && !ty.references_non_lt_error() { result.push(MovedOutOfRef { span: op.span.unwrap_or(span), ty }); @@ -231,7 +231,7 @@ fn moved_out_of_ref<'db>( fn partially_moved<'db>( infcx: &InferCtxt<'db>, - env: &TraitEnvironment<'db>, + env: ParamEnv<'db>, body: &MirBody<'db>, ) -> Vec<PartiallyMoved<'db>> { let db = infcx.interner.db; @@ -247,7 +247,7 @@ fn partially_moved<'db>( body.owner.module(db).krate(), ); } - if !infcx.type_is_copy_modulo_regions(env.env, ty) && !ty.references_non_lt_error() { + if !infcx.type_is_copy_modulo_regions(env, ty) && !ty.references_non_lt_error() { result.push(PartiallyMoved { span, ty, local: p.local }); } } diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index 3418689027..02e322f037 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -34,7 +34,7 @@ use syntax::{SyntaxNodePtr, TextRange}; use triomphe::Arc; use crate::{ - CallableDefId, ComplexMemoryMap, InferenceResult, MemoryMap, TraitEnvironment, + CallableDefId, ComplexMemoryMap, InferenceResult, MemoryMap, ParamEnvAndCrate, consteval::{self, ConstEvalError, try_const_usize}, db::{HirDatabase, InternedClosure, InternedClosureId}, display::{ClosureStyle, DisplayTarget, HirDisplay}, @@ -165,7 +165,7 @@ enum MirOrDynIndex<'db> { pub struct Evaluator<'db> { db: &'db dyn HirDatabase, - trait_env: Arc<TraitEnvironment<'db>>, + param_env: ParamEnvAndCrate<'db>, target_data_layout: Arc<TargetDataLayout>, stack: Vec<u8>, heap: Vec<u8>, @@ -594,7 +594,7 @@ pub fn interpret_mir<'db>( // a zero size, hoping that they are all outside of our current body. Even without a fix for #7434, we can // (and probably should) do better here, for example by excluding bindings outside of the target expression. assert_placeholder_ty_is_unused: bool, - trait_env: Option<Arc<TraitEnvironment<'db>>>, + trait_env: Option<ParamEnvAndCrate<'db>>, ) -> Result<'db, (Result<'db, Const<'db>>, MirOutput)> { let ty = body.locals[return_slot()].ty; let mut evaluator = Evaluator::new(db, body.owner, assert_placeholder_ty_is_unused, trait_env)?; @@ -632,7 +632,7 @@ impl<'db> Evaluator<'db> { db: &'db dyn HirDatabase, owner: DefWithBodyId, assert_placeholder_ty_is_unused: bool, - trait_env: Option<Arc<TraitEnvironment<'db>>>, + trait_env: Option<ParamEnvAndCrate<'db>>, ) -> Result<'db, Evaluator<'db>> { let module = owner.module(db); let crate_id = module.krate(); @@ -654,7 +654,10 @@ impl<'db> Evaluator<'db> { static_locations: Default::default(), db, random_state: oorandom::Rand64::new(0), - trait_env: trait_env.unwrap_or_else(|| db.trait_environment_for_body(owner)), + param_env: trait_env.unwrap_or_else(|| ParamEnvAndCrate { + param_env: db.trait_environment_for_body(owner), + krate: crate_id, + }), crate_id, stdout: vec![], stderr: vec![], @@ -864,7 +867,7 @@ impl<'db> Evaluator<'db> { } let r = self .db - .layout_of_ty(ty, self.trait_env.clone()) + .layout_of_ty(ty, self.param_env) .map_err(|e| MirEvalError::LayoutError(e, ty))?; self.layout_cache.borrow_mut().insert(ty, r.clone()); Ok(r) @@ -1927,18 +1930,17 @@ impl<'db> Evaluator<'db> { let mut id = const_id.0; let mut subst = subst; if let hir_def::GeneralConstId::ConstId(c) = id { - let (c, s) = lookup_impl_const(&self.infcx, self.trait_env.clone(), c, subst); + let (c, s) = lookup_impl_const(&self.infcx, self.param_env.param_env, c, subst); id = hir_def::GeneralConstId::ConstId(c); subst = s; } result_owner = match id { - GeneralConstId::ConstId(const_id) => self - .db - .const_eval(const_id, subst, Some(self.trait_env.clone())) - .map_err(|e| { + GeneralConstId::ConstId(const_id) => { + self.db.const_eval(const_id, subst, Some(self.param_env)).map_err(|e| { let name = id.name(self.db); MirEvalError::ConstEvalError(name, Box::new(e)) - })?, + })? + } GeneralConstId::StaticId(static_id) => { self.db.const_eval_static(static_id).map_err(|e| { let name = id.name(self.db); @@ -2331,7 +2333,7 @@ impl<'db> Evaluator<'db> { let ty = ocx .structurally_normalize_ty( &ObligationCause::dummy(), - this.trait_env.env, + this.param_env.param_env, ty, ) .map_err(|_| MirEvalError::NotSupported("couldn't normalize".to_owned()))?; @@ -2510,7 +2512,7 @@ impl<'db> Evaluator<'db> { ) -> Result<'db, Option<StackFrame<'db>>> { let mir_body = self .db - .monomorphized_mir_body_for_closure(closure, generic_args, self.trait_env.clone()) + .monomorphized_mir_body_for_closure(closure, generic_args, self.param_env) .map_err(|it| MirEvalError::MirLowerErrorForClosure(closure, it))?; let closure_data = if mir_body.locals[mir_body.param_locals[0]].ty.as_reference().is_some() { @@ -2606,16 +2608,19 @@ impl<'db> Evaluator<'db> { } let (def, generic_args) = pair; let r = if let Some(self_ty_idx) = - is_dyn_method(self.interner(), self.trait_env.clone(), def, generic_args) + is_dyn_method(self.interner(), self.param_env.param_env, def, generic_args) { MirOrDynIndex::Dyn(self_ty_idx) } else { - let (imp, generic_args) = - self.db.lookup_impl_method(self.trait_env.clone(), def, generic_args); + let (imp, generic_args) = self.db.lookup_impl_method( + ParamEnvAndCrate { param_env: self.param_env.param_env, krate: self.crate_id }, + def, + generic_args, + ); let mir_body = self .db - .monomorphized_mir_body(imp.into(), generic_args, self.trait_env.clone()) + .monomorphized_mir_body(imp.into(), generic_args, self.param_env) .map_err(|e| { MirEvalError::InFunction( Box::new(MirEvalError::MirLowerError(imp, e)), diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs index 591c12ec24..42c11113ee 100644 --- a/crates/hir-ty/src/mir/eval/shim.rs +++ b/crates/hir-ty/src/mir/eval/shim.rs @@ -840,7 +840,7 @@ impl<'db> Evaluator<'db> { "size_of generic arg is not provided".into(), )); }; - let result = match has_drop_glue(&self.infcx, ty, self.trait_env.clone()) { + let result = match has_drop_glue(&self.infcx, ty, self.param_env.param_env) { DropGlue::HasDropGlue => true, DropGlue::None => false, DropGlue::DependOnParams => { diff --git a/crates/hir-ty/src/mir/eval/tests.rs b/crates/hir-ty/src/mir/eval/tests.rs index bb2afb2f00..2c0c3427cb 100644 --- a/crates/hir-ty/src/mir/eval/tests.rs +++ b/crates/hir-ty/src/mir/eval/tests.rs @@ -1,4 +1,4 @@ -use hir_def::db::DefDatabase; +use hir_def::{HasModule, db::DefDatabase}; use hir_expand::EditionedFileId; use span::Edition; use syntax::{TextRange, TextSize}; @@ -40,7 +40,10 @@ fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String), .monomorphized_mir_body( func_id.into(), GenericArgs::new_from_iter(interner, []), - db.trait_environment(func_id.into()), + crate::ParamEnvAndCrate { + param_env: db.trait_environment(func_id.into()), + krate: func_id.krate(db), + }, ) .map_err(|e| MirEvalError::MirLowerError(func_id, e))?; diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index 190b2f99cc..5bce4222a4 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -25,7 +25,7 @@ use syntax::TextRange; use triomphe::Arc; use crate::{ - Adjust, Adjustment, AutoBorrow, CallableDefId, TraitEnvironment, + Adjust, Adjustment, AutoBorrow, CallableDefId, ParamEnvAndCrate, consteval::ConstEvalError, db::{HirDatabase, InternedClosure, InternedClosureId}, display::{DisplayTarget, HirDisplay, hir_display_with_store}, @@ -42,7 +42,7 @@ use crate::{ TupleFieldId, Ty, UnOp, VariantId, return_slot, }, next_solver::{ - Const, DbInterner, ParamConst, Region, TyKind, TypingMode, UnevaluatedConst, + Const, DbInterner, ParamConst, ParamEnv, Region, TyKind, TypingMode, UnevaluatedConst, infer::{DbInternerInferExt, InferCtxt}, }, traits::FnTrait, @@ -81,7 +81,7 @@ struct MirLowerCtx<'a, 'db> { infer: &'a InferenceResult<'db>, resolver: Resolver<'db>, drop_scopes: Vec<DropScope<'db>>, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnv<'db>, infcx: InferCtxt<'db>, } @@ -302,7 +302,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { }; let resolver = owner.resolver(db); let env = db.trait_environment_for_body(owner); - let interner = DbInterner::new_with(db, env.krate); + let interner = DbInterner::new_with(db, resolver.krate()); // FIXME(next-solver): Is `non_body_analysis()` correct here? Don't we want to reveal opaque types defined by this body? let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); @@ -1462,7 +1462,11 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { } fn lower_literal_to_operand(&mut self, ty: Ty<'db>, l: &Literal) -> Result<'db, Operand<'db>> { - let size = || self.db.layout_of_ty(ty, self.env.clone()).map(|it| it.size.bytes_usize()); + let size = || { + self.db + .layout_of_ty(ty, ParamEnvAndCrate { param_env: self.env, krate: self.krate() }) + .map(|it| it.size.bytes_usize()) + }; const USIZE_SIZE: usize = size_of::<usize>(); let bytes: Box<[_]> = match l { hir_def::hir::Literal::String(b) => { @@ -1799,7 +1803,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { &self.infcx, self.infer[expr_id], self.owner.module(self.db), - self.env.clone(), + self.env, ) } @@ -2070,7 +2074,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { span: MirSpan, ) { for &l in scope.locals.iter().rev() { - if !self.infcx.type_is_copy_modulo_regions(self.env.env, self.result.locals[l].ty) { + if !self.infcx.type_is_copy_modulo_regions(self.env, self.result.locals[l].ty) { let prev = std::mem::replace(current, self.new_basic_block()); self.set_terminator( prev, diff --git a/crates/hir-ty/src/mir/monomorphization.rs b/crates/hir-ty/src/mir/monomorphization.rs index 1f73d5cd31..b67365c344 100644 --- a/crates/hir-ty/src/mir/monomorphization.rs +++ b/crates/hir-ty/src/mir/monomorphization.rs @@ -14,9 +14,11 @@ use rustc_type_ir::{ }; use triomphe::Arc; -use crate::next_solver::{Const, ConstKind, Region, RegionKind}; use crate::{ - TraitEnvironment, + ParamEnvAndCrate, + next_solver::{Const, ConstKind, Region, RegionKind}, +}; +use crate::{ db::{HirDatabase, InternedClosureId}, next_solver::{ DbInterner, GenericArgs, Ty, TyKind, TypingMode, @@ -30,7 +32,7 @@ use super::{MirBody, MirLowerError, Operand, OperandKind, Rvalue, StatementKind, struct Filler<'db> { infcx: InferCtxt<'db>, - trait_env: Arc<TraitEnvironment<'db>>, + trait_env: ParamEnvAndCrate<'db>, subst: GenericArgs<'db>, } @@ -53,7 +55,11 @@ impl<'db> FallibleTypeFolder<DbInterner<'db>> for Filler<'db> { let mut ocx = ObligationCtxt::new(&self.infcx); let ty = ocx - .structurally_normalize_ty(&ObligationCause::dummy(), self.trait_env.env, ty) + .structurally_normalize_ty( + &ObligationCause::dummy(), + self.trait_env.param_env, + ty, + ) .map_err(|_| MirLowerError::NotSupported("can't normalize alias".to_owned()))?; ty.try_super_fold_with(self) } @@ -93,11 +99,7 @@ impl<'db> FallibleTypeFolder<DbInterner<'db>> for Filler<'db> { } impl<'db> Filler<'db> { - fn new( - db: &'db dyn HirDatabase, - env: Arc<TraitEnvironment<'db>>, - subst: GenericArgs<'db>, - ) -> Self { + fn new(db: &'db dyn HirDatabase, env: ParamEnvAndCrate<'db>, subst: GenericArgs<'db>) -> Self { let interner = DbInterner::new_with(db, env.krate); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); Self { infcx, trait_env: env, subst } @@ -210,7 +212,7 @@ pub fn monomorphized_mir_body_query<'db>( db: &'db dyn HirDatabase, owner: DefWithBodyId, subst: GenericArgs<'db>, - trait_env: Arc<crate::TraitEnvironment<'db>>, + trait_env: ParamEnvAndCrate<'db>, ) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>> { let mut filler = Filler::new(db, trait_env, subst); let body = db.mir_body(owner)?; @@ -223,7 +225,7 @@ pub(crate) fn monomorphized_mir_body_cycle_result<'db>( _db: &'db dyn HirDatabase, _: DefWithBodyId, _: GenericArgs<'db>, - _: Arc<crate::TraitEnvironment<'db>>, + _: ParamEnvAndCrate<'db>, ) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>> { Err(MirLowerError::Loop) } @@ -232,7 +234,7 @@ pub fn monomorphized_mir_body_for_closure_query<'db>( db: &'db dyn HirDatabase, closure: InternedClosureId, subst: GenericArgs<'db>, - trait_env: Arc<crate::TraitEnvironment<'db>>, + trait_env: ParamEnvAndCrate<'db>, ) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>> { let mut filler = Filler::new(db, trait_env, subst); let body = db.mir_body_for_closure(closure)?; diff --git a/crates/hir-ty/src/next_solver/predicate.rs b/crates/hir-ty/src/next_solver/predicate.rs index 7cc3af748a..783966ee1e 100644 --- a/crates/hir-ty/src/next_solver/predicate.rs +++ b/crates/hir-ty/src/next_solver/predicate.rs @@ -427,6 +427,10 @@ impl<'db> ParamEnv<'db> { pub fn empty() -> Self { ParamEnv { clauses: Clauses::new_from_iter(DbInterner::conjure(), []) } } + + pub fn clauses(self) -> Clauses<'db> { + self.clauses + } } impl<'db> rustc_type_ir::inherent::ParamEnv<DbInterner<'db>> for ParamEnv<'db> { diff --git a/crates/hir-ty/src/opaques.rs b/crates/hir-ty/src/opaques.rs index 0b84ce13a3..dbac20074b 100644 --- a/crates/hir-ty/src/opaques.rs +++ b/crates/hir-ty/src/opaques.rs @@ -122,7 +122,7 @@ pub(crate) fn tait_hidden_types<'db>( let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); let mut ocx = ObligationCtxt::new(&infcx); let cause = ObligationCause::dummy(); - let param_env = db.trait_environment(type_alias.into()).env; + let param_env = db.trait_environment(type_alias.into()); let defining_bodies = tait_defining_bodies(db, &loc); diff --git a/crates/hir-ty/src/specialization.rs b/crates/hir-ty/src/specialization.rs index 0241751e82..495a9937f6 100644 --- a/crates/hir-ty/src/specialization.rs +++ b/crates/hir-ty/src/specialization.rs @@ -1,6 +1,6 @@ //! Impl specialization related things -use hir_def::{ImplId, nameres::crate_def_map}; +use hir_def::{HasModule, ImplId, nameres::crate_def_map}; use intern::sym; use rustc_type_ir::inherent::SliceLike; use tracing::debug; @@ -46,7 +46,7 @@ fn specializes_query( parent_impl_def_id: ImplId, ) -> bool { let trait_env = db.trait_environment(specializing_impl_def_id.into()); - let interner = DbInterner::new_with(db, trait_env.krate); + let interner = DbInterner::new_with(db, specializing_impl_def_id.krate(db)); let specializing_impl_signature = db.impl_signature(specializing_impl_def_id); let parent_impl_signature = db.impl_signature(parent_impl_def_id); @@ -70,7 +70,7 @@ fn specializes_query( // create a parameter environment corresponding to an identity instantiation of the specializing impl, // i.e. the most generic instantiation of the specializing impl. - let param_env = trait_env.env; + let param_env = trait_env; // Create an infcx, taking the predicates of the specializing impl as assumptions: let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); diff --git a/crates/hir-ty/src/traits.rs b/crates/hir-ty/src/traits.rs index 1462f1e317..b1a2802264 100644 --- a/crates/hir-ty/src/traits.rs +++ b/crates/hir-ty/src/traits.rs @@ -4,7 +4,7 @@ use std::hash::Hash; use base_db::Crate; use hir_def::{ - AdtId, AssocItemId, BlockId, HasModule, ImplId, Lookup, TraitId, + AdtId, AssocItemId, HasModule, ImplId, Lookup, TraitId, lang_item::LangItems, nameres::DefMap, signatures::{ConstFlags, EnumFlags, FnFlags, StructFlags, TraitFlags, TypeAliasFlags}, @@ -17,7 +17,6 @@ use rustc_type_ir::{ inherent::{AdtDef, BoundExistentialPredicates, IntoKind, Span as _}, solve::Certainty, }; -use triomphe::Arc; use crate::{ db::HirDatabase, @@ -29,60 +28,22 @@ use crate::{ }, }; -/// A set of clauses that we assume to be true. E.g. if we are inside this function: -/// ```rust -/// fn foo<T: Default>(t: T) {} -/// ``` -/// we assume that `T: Default`. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct TraitEnvironment<'db> { +/// Type for `hir`, because commonly we want both param env and a crate in an exported API. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct ParamEnvAndCrate<'db> { + pub param_env: ParamEnv<'db>, pub krate: Crate, - pub block: Option<BlockId>, - // FIXME make this a BTreeMap - traits_from_clauses: Box<[(Ty<'db>, TraitId)]>, - pub env: ParamEnv<'db>, -} - -impl<'db> TraitEnvironment<'db> { - pub fn empty(krate: Crate) -> Arc<Self> { - Arc::new(TraitEnvironment { - krate, - block: None, - traits_from_clauses: Box::default(), - env: ParamEnv::empty(), - }) - } - - pub fn new( - krate: Crate, - block: Option<BlockId>, - traits_from_clauses: Box<[(Ty<'db>, TraitId)]>, - env: ParamEnv<'db>, - ) -> Arc<Self> { - Arc::new(TraitEnvironment { krate, block, traits_from_clauses, env }) - } - - // pub fn with_block(self: &mut Arc<Self>, block: BlockId) { - pub fn with_block(this: &mut Arc<Self>, block: BlockId) { - Arc::make_mut(this).block = Some(block); - } - - pub fn traits_in_scope_from_clauses(&self, ty: Ty<'db>) -> impl Iterator<Item = TraitId> + '_ { - self.traits_from_clauses - .iter() - .filter_map(move |(self_ty, trait_id)| (*self_ty == ty).then_some(*trait_id)) - } } /// This should be used in `hir` only. pub fn structurally_normalize_ty<'db>( infcx: &InferCtxt<'db>, ty: Ty<'db>, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnv<'db>, ) -> Ty<'db> { let TyKind::Alias(..) = ty.kind() else { return ty }; let mut ocx = ObligationCtxt::new(infcx); - let ty = ocx.structurally_normalize_ty(&ObligationCause::dummy(), env.env, ty).unwrap_or(ty); + let ty = ocx.structurally_normalize_ty(&ObligationCause::dummy(), env, ty).unwrap_or(ty); ty.replace_infer_with_error(infcx.interner) } @@ -192,7 +153,7 @@ impl FnTrait { pub fn implements_trait_unique<'db>( ty: Ty<'db>, db: &'db dyn HirDatabase, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, trait_: TraitId, ) -> bool { implements_trait_unique_impl(db, env, trait_, &mut |infcx| { @@ -203,7 +164,7 @@ pub fn implements_trait_unique<'db>( /// This should not be used in `hir-ty`, only in `hir`. pub fn implements_trait_unique_with_args<'db>( db: &'db dyn HirDatabase, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, trait_: TraitId, args: GenericArgs<'db>, ) -> bool { @@ -212,7 +173,7 @@ pub fn implements_trait_unique_with_args<'db>( fn implements_trait_unique_impl<'db>( db: &'db dyn HirDatabase, - env: Arc<TraitEnvironment<'db>>, + env: ParamEnvAndCrate<'db>, trait_: TraitId, create_args: &mut dyn FnMut(&InferCtxt<'db>) -> GenericArgs<'db>, ) -> bool { @@ -222,7 +183,7 @@ fn implements_trait_unique_impl<'db>( let args = create_args(&infcx); let trait_ref = rustc_type_ir::TraitRef::new_from_args(interner, trait_.into(), args); - let goal = Goal::new(interner, env.env, trait_ref); + let goal = Goal::new(interner, env.param_env, trait_ref); let result = crate::traits::next_trait_solve_in_ctxt(&infcx, goal); matches!(result, Ok((_, Certainty::Yes))) diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs index 5e716c6df1..2f412d88ab 100644 --- a/crates/hir/src/attrs.rs +++ b/crates/hir/src/attrs.rs @@ -412,9 +412,7 @@ fn resolve_impl_trait_item<'db>( ns: Option<Namespace>, ) -> Option<DocLinkDef> { let krate = ty.krate(db); - let environment = resolver - .generic_def() - .map_or_else(|| crate::TraitEnvironment::empty(krate.id), |d| db.trait_environment(d)); + let environment = crate::param_env_from_resolver(db, &resolver); let traits_in_scope = resolver.traits_in_scope(db); // `ty.iterate_path_candidates()` require a scope, which is not available when resolving @@ -428,7 +426,7 @@ fn resolve_impl_trait_item<'db>( let ctx = MethodResolutionContext { infcx: &infcx, resolver: &resolver, - env: &environment, + param_env: environment.param_env, traits_in_scope: &traits_in_scope, edition: krate.edition(db), unstable_features: &unstable_features, 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; diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 8144b2f737..901c9e1575 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -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, }; @@ -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)), ) } @@ -827,7 +833,7 @@ impl<'db> SourceAnalyzer<'db> { 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 _| { @@ -1412,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) } @@ -1426,10 +1432,10 @@ impl<'db> SourceAnalyzer<'db> { Some(it) => it, None => return (const_id, subs), }; - let env = db.trait_environment_for_body(owner); + 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 { diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 767672fc2f..ed0b646685 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -10,8 +10,8 @@ use std::{ use cfg::{CfgAtom, CfgDiff}; use hir::{ - Adt, AssocItem, Crate, DefWithBody, FindPathConfig, HasSource, HirDisplay, ModuleDef, Name, - crate_lang_items, + Adt, AssocItem, Crate, DefWithBody, FindPathConfig, HasCrate, HasSource, HirDisplay, ModuleDef, + Name, crate_lang_items, db::{DefDatabase, ExpandDatabase, HirDatabase}, next_solver::{DbInterner, GenericArgs}, }; @@ -391,7 +391,10 @@ impl flags::AnalysisStats { let Err(e) = db.layout_of_adt( hir_def::AdtId::from(a), GenericArgs::new_from_iter(interner, []), - db.trait_environment(a.into()), + hir_ty::ParamEnvAndCrate { + param_env: db.trait_environment(a.into()), + krate: a.krate(db).into(), + }, ) else { continue; }; |