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`.
Chayim Refael Friedman 5 months ago
parent 2d3f2e5 · commit 8f31042
-rw-r--r--crates/hir-ty/src/autoderef.rs37
-rw-r--r--crates/hir-ty/src/consteval.rs27
-rw-r--r--crates/hir-ty/src/db.rs24
-rw-r--r--crates/hir-ty/src/diagnostics/expr.rs12
-rw-r--r--crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs22
-rw-r--r--crates/hir-ty/src/display.rs37
-rw-r--r--crates/hir-ty/src/drop.rs29
-rw-r--r--crates/hir-ty/src/infer.rs2
-rw-r--r--crates/hir-ty/src/infer/autoderef.rs4
-rw-r--r--crates/hir-ty/src/infer/closure.rs17
-rw-r--r--crates/hir-ty/src/infer/coerce.rs49
-rw-r--r--crates/hir-ty/src/infer/expr.rs36
-rw-r--r--crates/hir-ty/src/infer/op.rs2
-rw-r--r--crates/hir-ty/src/infer/opaques.rs2
-rw-r--r--crates/hir-ty/src/infer/path.rs4
-rw-r--r--crates/hir-ty/src/infer/place_op.rs2
-rw-r--r--crates/hir-ty/src/infer/unify.rs41
-rw-r--r--crates/hir-ty/src/inhabitedness.rs18
-rw-r--r--crates/hir-ty/src/layout.rs16
-rw-r--r--crates/hir-ty/src/layout/adt.rs8
-rw-r--r--crates/hir-ty/src/layout/tests.rs24
-rw-r--r--crates/hir-ty/src/lib.rs7
-rw-r--r--crates/hir-ty/src/lower.rs19
-rw-r--r--crates/hir-ty/src/method_resolution.rs48
-rw-r--r--crates/hir-ty/src/method_resolution/confirm.rs2
-rw-r--r--crates/hir-ty/src/method_resolution/probe.rs8
-rw-r--r--crates/hir-ty/src/mir/borrowck.rs16
-rw-r--r--crates/hir-ty/src/mir/eval.rs41
-rw-r--r--crates/hir-ty/src/mir/eval/shim.rs2
-rw-r--r--crates/hir-ty/src/mir/eval/tests.rs7
-rw-r--r--crates/hir-ty/src/mir/lower.rs18
-rw-r--r--crates/hir-ty/src/mir/monomorphization.rs26
-rw-r--r--crates/hir-ty/src/next_solver/predicate.rs4
-rw-r--r--crates/hir-ty/src/opaques.rs2
-rw-r--r--crates/hir-ty/src/specialization.rs6
-rw-r--r--crates/hir-ty/src/traits.rs61
-rw-r--r--crates/hir/src/attrs.rs6
-rw-r--r--crates/hir/src/lib.rs174
-rw-r--r--crates/hir/src/source_analyzer.rs26
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs9
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;
};