Use ParamEnv in TraitEnvironment

This commit is contained in:
Jack Huey 2025-09-22 17:38:31 -04:00 committed by jackh726
parent c2513538cd
commit 34f773f596
17 changed files with 216 additions and 170 deletions

View File

@ -298,7 +298,7 @@ fn structurally_normalize_ty<'db>(
) -> Option<(Ty<'db>, PredicateObligations<'db>)> {
let mut ocx = ObligationCtxt::new(&table.infer_ctxt);
let Ok(normalized_ty) =
ocx.structurally_normalize_ty(&ObligationCause::misc(), table.param_env, ty)
ocx.structurally_normalize_ty(&ObligationCause::misc(), table.trait_env.env, ty)
else {
// We shouldn't have errors here in the old solver, except for
// evaluate/fulfill mismatches, but that's not a reason for an ICE.

View File

@ -15,8 +15,13 @@ use crate::{
AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, Canonical, CanonicalVarKinds,
ClosureId, DynTy, FnPointer, ImplTraitId, InEnvironment, Interner, Lifetime, ProjectionTy,
QuantifiedWhereClause, Substitution, ToChalk, TraitRef, Ty, TyBuilder, TyKind, TypeFlags,
WhereClause, db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
from_placeholder_idx, generics::generics, to_chalk_trait_id, utils::ClosureSubst,
WhereClause,
db::HirDatabase,
from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx,
generics::generics,
next_solver::{DbInterner, mapping::NextSolverToChalk},
to_chalk_trait_id,
utils::ClosureSubst,
};
pub trait TyExt {
@ -372,7 +377,10 @@ impl TyExt for Ty {
let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(self).build();
let env = db.trait_environment_for_body(owner);
let goal = Canonical {
value: InEnvironment::new(&env.env, trait_ref.cast(Interner)),
value: InEnvironment::new(
&env.env.to_chalk(DbInterner::new_with(db, Some(env.krate), env.block)),
trait_ref.cast(Interner),
),
binders: CanonicalVarKinds::empty(Interner),
};
!db.trait_solve(crate_id, None, goal).no_solution()

View File

@ -182,12 +182,12 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
#[salsa::invoke(crate::lower::generic_predicates_query)]
fn generic_predicates(&self, def: GenericDefId) -> GenericPredicates;
#[salsa::invoke(crate::lower::trait_environment_for_body_query)]
#[salsa::invoke(crate::lower_nextsolver::trait_environment_for_body_query)]
#[salsa::transparent]
fn trait_environment_for_body<'db>(&'db self, def: DefWithBodyId)
-> Arc<TraitEnvironment<'db>>;
#[salsa::invoke(crate::lower::trait_environment_query)]
#[salsa::invoke(crate::lower_nextsolver::trait_environment_query)]
fn trait_environment<'db>(&'db self, def: GenericDefId) -> Arc<TraitEnvironment<'db>>;
#[salsa::invoke(crate::lower::generic_defaults_with_diagnostics_query)]

View File

@ -792,10 +792,7 @@ fn render_const_scalar_ns(
let trait_env = TraitEnvironment::empty(f.krate());
let interner = DbInterner::new_with(f.db, Some(trait_env.krate), trait_env.block);
let infcx = interner.infer_ctxt().build(rustc_type_ir::TypingMode::PostAnalysis);
let ty = infcx
.at(&ObligationCause::new(), trait_env.env.to_nextsolver(interner))
.deeply_normalize(ty)
.unwrap_or(ty);
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)
}

View File

@ -7,6 +7,8 @@ use hir_def::signatures::StructFlags;
use stdx::never;
use triomphe::Arc;
use crate::next_solver::DbInterner;
use crate::next_solver::mapping::NextSolverToChalk;
use crate::{
AliasTy, Canonical, CanonicalVarKinds, ConcreteConst, ConstScalar, ConstValue, InEnvironment,
Interner, ProjectionTy, TraitEnvironment, Ty, TyBuilder, TyKind, db::HirDatabase,
@ -188,7 +190,10 @@ fn is_copy(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironment<'_>>) -> bool
};
let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(ty).build();
let goal = Canonical {
value: InEnvironment::new(&env.env, trait_ref.cast(Interner)),
value: InEnvironment::new(
&env.env.to_chalk(DbInterner::new_with(db, Some(env.krate), env.block)),
trait_ref.cast(Interner),
),
binders: CanonicalVarKinds::empty(Interner),
};
db.trait_solve(env.krate, env.block, goal).certain()

View File

@ -318,7 +318,7 @@ impl<'db> InferenceContext<'db> {
_ = self
.table
.infer_ctxt
.at(&ObligationCause::new(), self.table.param_env)
.at(&ObligationCause::new(), self.table.trait_env.env)
.eq(DefineOpaqueTypes::Yes, inferred_fnptr_sig, generalized_fnptr_sig)
.map(|infer_ok| self.table.register_infer_ok(infer_ok));
@ -703,7 +703,7 @@ impl<'db> InferenceContext<'db> {
let cause = ObligationCause::new();
let InferOk { value: (), obligations } = table
.infer_ctxt
.at(&cause, table.param_env)
.at(&cause, table.trait_env.env)
.eq(DefineOpaqueTypes::Yes, expected_ty, supplied_ty)?;
all_obligations.extend(obligations);
}
@ -711,7 +711,7 @@ impl<'db> InferenceContext<'db> {
let supplied_output_ty = supplied_sig.output();
let cause = ObligationCause::new();
let InferOk { value: (), obligations } =
table.infer_ctxt.at(&cause, table.param_env).eq(
table.infer_ctxt.at(&cause, table.trait_env.env).eq(
DefineOpaqueTypes::Yes,
expected_sigs.liberated_sig.output(),
supplied_output_ty,

View File

@ -144,7 +144,7 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
fn unify_raw(&mut self, a: Ty<'db>, b: Ty<'db>) -> InferResult<'db, Ty<'db>> {
debug!("unify(a: {:?}, b: {:?}, use_lub: {})", a, b, self.use_lub);
self.commit_if_ok(|this| {
let at = this.infer_ctxt().at(&this.cause, this.table.param_env);
let at = this.infer_ctxt().at(&this.cause, this.table.trait_env.env);
let res = if this.use_lub {
at.lub(b, a)
@ -330,7 +330,7 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
obligations.push(Obligation::new(
self.interner(),
self.cause.clone(),
self.table.param_env,
self.table.trait_env.env,
Binder::dummy(PredicateKind::Coerce(CoercePredicate {
a: source_ty,
b: target_ty,
@ -718,7 +718,7 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
let mut queue: SmallVec<[PredicateObligation<'db>; 4]> = smallvec![Obligation::new(
self.interner(),
cause,
self.table.param_env,
self.table.trait_env.env,
TraitRef::new(
self.interner(),
coerce_unsized_did.into(),
@ -1114,8 +1114,12 @@ 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.param_env, prev_ty, new_ty)?;
let value = ocx.lub(
&ObligationCause::new(),
table.trait_env.env,
prev_ty,
new_ty,
)?;
if ocx.select_where_possible().is_empty() {
Ok(InferOk { value, obligations: ocx.into_pending_obligations() })
} else {
@ -1158,7 +1162,7 @@ impl<'db> InferenceContext<'db> {
let sig = self
.table
.infer_ctxt
.at(&ObligationCause::new(), self.table.param_env)
.at(&ObligationCause::new(), self.table.trait_env.env)
.lub(a_sig, b_sig)
.map(|ok| self.table.register_infer_ok(ok))?;
@ -1248,7 +1252,7 @@ impl<'db> InferenceContext<'db> {
.commit_if_ok(|table| {
table
.infer_ctxt
.at(&ObligationCause::new(), table.param_env)
.at(&ObligationCause::new(), table.trait_env.env)
.lub(prev_ty, new_ty)
})
.unwrap_err())
@ -1498,7 +1502,7 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> {
assert!(expression_ty.is_unit(), "if let hack without unit type");
icx.table
.infer_ctxt
.at(cause, icx.table.param_env)
.at(cause, icx.table.trait_env.env)
.eq(
// needed for tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
DefineOpaqueTypes::Yes,

View File

@ -1662,7 +1662,6 @@ impl<'db> InferenceContext<'db> {
});
self.resolver.reset_to_guard(g);
if let Some(prev_env) = prev_env {
self.table.param_env = prev_env.env.to_nextsolver(self.table.interner);
self.table.trait_env = prev_env;
}
@ -2132,7 +2131,7 @@ impl<'db> InferenceContext<'db> {
let origin = ObligationCause::new();
ocx.sup(
&origin,
self.table.param_env,
self.table.trait_env.env,
expected_output.to_nextsolver(interner),
formal_output,
)?;
@ -2239,7 +2238,7 @@ impl<'db> InferenceContext<'db> {
let formal_ty_error = this
.table
.infer_ctxt
.at(&ObligationCause::new(), this.table.param_env)
.at(&ObligationCause::new(), this.table.trait_env.env)
.eq(DefineOpaqueTypes::Yes, formal_input_ty, coerced_ty);
// If neither check failed, the types are compatible

View File

@ -29,8 +29,8 @@ use crate::{
db::HirDatabase,
fold_generic_args, fold_tys_and_consts,
next_solver::{
self, ClauseKind, DbInterner, ErrorGuaranteed, ParamEnv, Predicate, PredicateKind,
SolverDefIds, Term, TraitRef,
self, ClauseKind, DbInterner, ErrorGuaranteed, Predicate, PredicateKind, SolverDefIds,
Term, TraitRef,
fulfill::FulfillmentCtxt,
infer::{
DbInternerInferExt, InferCtxt, InferOk,
@ -213,7 +213,6 @@ pub(crate) struct InferenceTable<'db> {
pub(crate) db: &'db dyn HirDatabase,
pub(crate) interner: DbInterner<'db>,
pub(crate) trait_env: Arc<TraitEnvironment<'db>>,
pub(crate) param_env: ParamEnv<'db>,
pub(crate) tait_coercion_table: Option<FxHashMap<OpaqueTyId, Ty>>,
pub(crate) infer_ctxt: InferCtxt<'db>,
diverging_tys: FxHashSet<Ty>,
@ -235,7 +234,6 @@ impl<'db> InferenceTable<'db> {
InferenceTable {
db,
interner,
param_env: trait_env.env.to_nextsolver(interner),
trait_env,
tait_coercion_table: None,
fulfillment_cx: FulfillmentCtxt::new(&infer_ctxt),
@ -426,7 +424,7 @@ impl<'db> InferenceTable<'db> {
{
let ty = self.resolve_vars_with_obligations(ty);
self.infer_ctxt
.at(&ObligationCause::new(), self.param_env)
.at(&ObligationCause::new(), self.trait_env.env)
.deeply_normalize(ty.clone())
.unwrap_or(ty)
}
@ -741,7 +739,7 @@ impl<'db> InferenceTable<'db> {
) -> InferResult<'db, ()> {
let variance = rustc_type_ir::Variance::Invariant;
let span = crate::next_solver::Span::dummy();
match self.infer_ctxt.relate(self.param_env, lhs, variance, rhs, span) {
match self.infer_ctxt.relate(self.trait_env.env, lhs, variance, rhs, span) {
Ok(goals) => Ok(crate::infer::InferOk { goals, value: () }),
Err(_) => Err(TypeError),
}
@ -798,7 +796,7 @@ impl<'db> InferenceTable<'db> {
fn structurally_normalize_term(&mut self, term: Term<'db>) -> Term<'db> {
self.infer_ctxt
.at(&ObligationCause::new(), self.param_env)
.at(&ObligationCause::new(), self.trait_env.env)
.structurally_normalize_term(term, &mut self.fulfillment_cx)
.unwrap_or(term)
}
@ -818,7 +816,7 @@ impl<'db> InferenceTable<'db> {
// in a reentrant borrow, causing an ICE.
let result = self
.infer_ctxt
.at(&ObligationCause::misc(), self.param_env)
.at(&ObligationCause::misc(), self.trait_env.env)
.structurally_normalize_ty(ty, &mut self.fulfillment_cx);
match result {
Ok(normalized_ty) => normalized_ty,
@ -874,14 +872,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 = next_solver::Goal { param_env: self.param_env, predicate };
let goal = next_solver::Goal { param_env: self.trait_env.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 = next_solver::Goal { param_env: self.param_env, predicate };
let goal = next_solver::Goal { param_env: self.trait_env.env, predicate };
self.register_obligation_in_env(goal)
}

View File

@ -24,9 +24,9 @@ use chalk_ir::{
use either::Either;
use hir_def::{
AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId,
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LocalFieldId,
Lookup, StaticId, StructId, TypeAliasId, TypeOrConstParamId, UnionId, VariantId,
AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId,
GenericDefId, GenericParamId, ImplId, ItemContainerId, LocalFieldId, Lookup, StaticId,
StructId, TypeAliasId, TypeOrConstParamId, UnionId, VariantId,
builtin_type::BuiltinType,
expr_store::{ExpressionStore, path::Path},
hir::generics::{GenericParamDataRef, TypeOrConstParamData, WherePredicate},
@ -46,11 +46,10 @@ use stdx::{impl_from, never};
use triomphe::{Arc, ThinArc};
use crate::{
AliasTy, Binders, BoundVar, CallableSig, Const, DebruijnIndex, DomainGoal, DynTy, FnAbi,
FnPointer, FnSig, FnSubst, ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime,
LifetimeData, LifetimeOutlives, PolyFnSig, QuantifiedWhereClause, QuantifiedWhereClauses,
Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
all_super_traits,
AliasTy, Binders, BoundVar, CallableSig, Const, DebruijnIndex, DynTy, FnAbi, FnPointer, FnSig,
FnSubst, ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime, LifetimeData,
LifetimeOutlives, PolyFnSig, QuantifiedWhereClause, QuantifiedWhereClauses, Substitution,
TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause, all_super_traits,
consteval::{intern_const_ref, path_to_const, unknown_const, unknown_const_as_generic},
db::HirDatabase,
error_lifetime,
@ -1086,102 +1085,6 @@ pub(crate) fn generic_predicates_for_param_cycle_result(
GenericPredicates(None)
}
pub(crate) fn trait_environment_for_body_query(
db: &dyn HirDatabase,
def: DefWithBodyId,
) -> Arc<TraitEnvironment<'_>> {
let Some(def) = def.as_generic_def_id(db) else {
let krate = def.module(db).krate();
return TraitEnvironment::empty(krate);
};
db.trait_environment(def)
}
pub(crate) fn trait_environment_query<'db>(
db: &'db dyn HirDatabase,
def: GenericDefId,
) -> Arc<TraitEnvironment<'db>> {
let generics = generics(db, def);
if generics.has_no_predicates() && generics.is_empty() {
return TraitEnvironment::empty(def.krate(db));
}
let resolver = def.resolver(db);
let mut ctx = TyLoweringContext::new(
db,
&resolver,
generics.store(),
def,
LifetimeElisionKind::AnonymousReportError,
)
.with_type_param_mode(ParamLoweringMode::Placeholder);
let mut traits_in_scope = Vec::new();
let mut clauses = Vec::new();
for maybe_parent_generics in
std::iter::successors(Some(&generics), |generics| generics.parent_generics())
{
ctx.store = maybe_parent_generics.store();
for pred in maybe_parent_generics.where_predicates() {
for pred in ctx.lower_where_predicate(pred, false) {
if let WhereClause::Implemented(tr) = pred.skip_binders() {
traits_in_scope
.push((tr.self_type_parameter(Interner).clone(), tr.hir_trait_id()));
}
let program_clause: Binders<DomainGoal> =
pred.map(|pred| pred.into_from_env_goal(Interner).cast(Interner));
clauses.push(program_clause);
}
}
}
if let Some(trait_id) = def.assoc_trait_container(db) {
// add `Self: Trait<T1, T2, ...>` to the environment in trait
// function default implementations (and speculative code
// inside consts or type aliases)
cov_mark::hit!(trait_self_implements_self);
let substs = TyBuilder::placeholder_subst(db, trait_id);
let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
let pred = WhereClause::Implemented(trait_ref);
clauses.push(Binders::empty(
Interner,
pred.cast::<DomainGoal>(Interner).into_from_env_goal(Interner),
));
}
let subst = generics.placeholder_subst(db);
if !subst.is_empty(Interner) {
let explicitly_unsized_tys = ctx.unsized_types;
if let Some(implicitly_sized_clauses) =
implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver)
{
clauses.extend(implicitly_sized_clauses.map(|pred| {
Binders::empty(
Interner,
pred.into_from_env_goal(Interner).cast::<DomainGoal>(Interner),
)
}));
};
}
let clauses = chalk_ir::ProgramClauses::from_iter(
Interner,
clauses.into_iter().map(|g| {
chalk_ir::ProgramClause::new(
Interner,
chalk_ir::ProgramClauseData(g.map(|g| chalk_ir::ProgramClauseImplication {
consequence: g,
conditions: chalk_ir::Goals::empty(Interner),
constraints: chalk_ir::Constraints::empty(Interner),
priority: chalk_ir::ClausePriority::High,
})),
)
}),
);
let env = chalk_ir::Environment { clauses };
TraitEnvironment::new(resolver.krate(), None, traits_in_scope.into_boxed_slice(), env)
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct GenericPredicates(Option<Arc<[Binders<QuantifiedWhereClause>]>>);

View File

@ -19,9 +19,9 @@ use base_db::Crate;
use either::Either;
use hir_def::item_tree::FieldsShape;
use hir_def::{
AdtId, AssocItemId, CallableDefId, ConstParamId, EnumVariantId, FunctionId, GenericDefId,
GenericParamId, ImplId, ItemContainerId, LocalFieldId, Lookup, StructId, TraitId, TypeAliasId,
TypeOrConstParamId, VariantId,
AdtId, AssocItemId, CallableDefId, ConstParamId, DefWithBodyId, EnumVariantId, FunctionId,
GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup,
StructId, TraitId, TypeAliasId, TypeOrConstParamId, VariantId,
expr_store::{
ExpressionStore,
path::{GenericArg, Path},
@ -57,7 +57,7 @@ use triomphe::Arc;
use crate::ValueTyDefId;
use crate::{
FnAbi, ImplTraitId, Interner, ParamKind, TyDefId, TyLoweringDiagnostic,
FnAbi, ImplTraitId, Interner, ParamKind, TraitEnvironment, TyDefId, TyLoweringDiagnostic,
TyLoweringDiagnosticKind,
consteval_nextsolver::{intern_const_ref, path_to_const, unknown_const_as_generic},
db::HirDatabase,
@ -66,8 +66,10 @@ use crate::{
next_solver::{
AdtDef, AliasTy, Binder, BoundExistentialPredicates, BoundRegionKind, BoundTyKind,
BoundVarKind, BoundVarKinds, Clause, Clauses, Const, DbInterner, EarlyBinder,
EarlyParamRegion, ErrorGuaranteed, GenericArgs, PolyFnSig, Predicate, Region, SolverDefId,
TraitPredicate, TraitRef, Ty, Tys, abi::Safety, mapping::ChalkToNextSolver,
EarlyParamRegion, ErrorGuaranteed, GenericArgs, ParamEnv, PolyFnSig, Predicate, Region,
SolverDefId, TraitPredicate, TraitRef, Ty, Tys,
abi::Safety,
mapping::{ChalkToNextSolver, convert_ty_for_result},
},
};
@ -1375,6 +1377,122 @@ impl<'db> ops::Deref for GenericPredicates<'db> {
}
}
pub(crate) fn trait_environment_for_body_query(
db: &dyn HirDatabase,
def: DefWithBodyId,
) -> Arc<TraitEnvironment<'_>> {
let Some(def) = def.as_generic_def_id(db) else {
let krate = def.module(db).krate();
return TraitEnvironment::empty(krate);
};
db.trait_environment(def)
}
pub(crate) fn trait_environment_query<'db>(
db: &'db dyn HirDatabase,
def: GenericDefId,
) -> Arc<TraitEnvironment<'db>> {
let generics = generics(db, def);
if generics.has_no_predicates() && generics.is_empty() {
return TraitEnvironment::empty(def.krate(db));
}
let interner = DbInterner::new_with(db, Some(def.krate(db)), None);
let resolver = def.resolver(db);
let mut ctx = TyLoweringContext::new(
db,
&resolver,
generics.store(),
def,
LifetimeElisionKind::AnonymousReportError,
);
let mut traits_in_scope = Vec::new();
let mut clauses = Vec::new();
for maybe_parent_generics in
std::iter::successors(Some(&generics), |generics| generics.parent_generics())
{
ctx.store = maybe_parent_generics.store();
for pred in maybe_parent_generics.where_predicates() {
for pred in ctx.lower_where_predicate(pred, false, &generics, PredicateFilter::All) {
if let rustc_type_ir::ClauseKind::Trait(tr) = pred.kind().skip_binder() {
traits_in_scope
.push((convert_ty_for_result(interner, tr.self_ty()), tr.def_id().0));
}
clauses.push(pred);
}
}
}
if let Some(trait_id) = def.assoc_trait_container(db) {
// add `Self: Trait<T1, T2, ...>` to the environment in trait
// function default implementations (and speculative code
// inside consts or type aliases)
cov_mark::hit!(trait_self_implements_self);
let trait_ref = TraitRef::identity(ctx.interner, trait_id.into());
let clause = Clause(Predicate::new(
ctx.interner,
Binder::dummy(rustc_type_ir::PredicateKind::Clause(rustc_type_ir::ClauseKind::Trait(
TraitPredicate { trait_ref, polarity: rustc_type_ir::PredicatePolarity::Positive },
))),
));
clauses.push(clause);
}
let explicitly_unsized_tys = ctx.unsized_types;
let sized_trait = LangItem::Sized.resolve_trait(db, resolver.krate());
if let Some(sized_trait) = sized_trait {
let (mut generics, mut def_id) =
(crate::next_solver::generics::generics(db, def.into()), def);
loop {
let self_idx = trait_self_param_idx(db, def_id);
for (idx, p) in generics.own_params.iter().enumerate() {
if let Some(self_idx) = self_idx
&& p.index() as usize == self_idx
{
continue;
}
let GenericParamId::TypeParamId(param_id) = p.id else {
continue;
};
let idx = idx as u32 + generics.parent_count as u32;
let param_ty = Ty::new_param(ctx.interner, param_id, idx, p.name.clone());
if explicitly_unsized_tys.contains(&param_ty) {
continue;
}
let trait_ref = TraitRef::new_from_args(
ctx.interner,
sized_trait.into(),
GenericArgs::new_from_iter(ctx.interner, [param_ty.into()]),
);
let clause = Clause(Predicate::new(
ctx.interner,
Binder::dummy(rustc_type_ir::PredicateKind::Clause(
rustc_type_ir::ClauseKind::Trait(TraitPredicate {
trait_ref,
polarity: rustc_type_ir::PredicatePolarity::Positive,
}),
)),
));
clauses.push(clause);
}
if let Some(g) = generics.parent {
generics = crate::next_solver::generics::generics(db, g.into());
def_id = g;
} else {
break;
}
}
}
let clauses = rustc_type_ir::elaborate::elaborate(ctx.interner, clauses);
let clauses = Clauses::new_from_iter(ctx.interner, clauses);
let env = ParamEnv { clauses };
TraitEnvironment::new(resolver.krate(), None, traits_in_scope.into_boxed_slice(), env)
}
#[derive(Copy, Clone, Debug)]
pub(crate) enum PredicateFilter {
SelfTrait,

View File

@ -31,7 +31,7 @@ use crate::{
infer::{Adjust, Adjustment, OverloadedDeref, PointerCast, unify::InferenceTable},
lang_items::is_box,
next_solver::{
self, SolverDefId,
self, DbInterner, SolverDefId,
infer::{
DefineOpaqueTypes,
traits::{ObligationCause, PredicateObligation},
@ -1755,7 +1755,10 @@ fn is_valid_trait_method_candidate(
};
let res = table
.infer_ctxt
.at(&next_solver::infer::traits::ObligationCause::dummy(), table.param_env)
.at(
&next_solver::infer::traits::ObligationCause::dummy(),
table.trait_env.env,
)
.relate(
DefineOpaqueTypes::No,
expected_receiver.to_nextsolver(table.interner),
@ -1845,7 +1848,12 @@ fn is_valid_impl_fn_candidate(
let mut ctxt = ObligationCtxt::new(&table.infer_ctxt);
ctxt.register_obligations(predicates.into_iter().map(|p| {
PredicateObligation::new(table.interner, ObligationCause::new(), table.param_env, p.0)
PredicateObligation::new(
table.interner,
ObligationCause::new(),
table.trait_env.env,
p.0,
)
}));
if ctxt.select_where_possible().is_empty() {
@ -1893,7 +1901,10 @@ fn generic_implements_goal<'db>(
let binders = CanonicalVarKinds::from_iter(Interner, kinds);
let obligation = trait_ref.cast(Interner);
let value = InEnvironment::new(&env.env, obligation);
let value = InEnvironment::new(
&env.env.to_chalk(DbInterner::new_with(db, Some(env.krate), env.block)),
obligation,
);
Canonical { binders, value }
}
@ -1910,7 +1921,7 @@ fn generic_implements_goal_ns<'db>(
let trait_ref =
rustc_type_ir::TraitRef::new_from_args(table.infer_ctxt.interner, trait_.into(), args)
.with_replaced_self_ty(table.infer_ctxt.interner, self_ty);
let goal = next_solver::Goal::new(table.infer_ctxt.interner, table.param_env, trait_ref);
let goal = next_solver::Goal::new(table.infer_ctxt.interner, table.trait_env.env, trait_ref);
table.canonicalize(goal)
}

View File

@ -632,7 +632,7 @@ fn issue_4053_diesel_where_clauses() {
488..522 '{ ... }': <SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}> as BoxedDsl<DB>>::Output
498..502 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}>
498..508 'self.order': O
498..515 'self.o...into()': dyn QueryFragment<DB> + '?
498..515 'self.o...into()': dyn QueryFragment<DB> + 'static
"#]],
);
}

View File

@ -25,7 +25,7 @@ use crate::{
db::HirDatabase,
infer::unify::InferenceTable,
next_solver::{
DbInterner, GenericArg, Predicate, SolverContext, Span,
DbInterner, GenericArg, ParamEnv, Predicate, SolverContext, Span,
infer::{DbInternerInferExt, InferCtxt},
mapping::{ChalkToNextSolver, convert_canonical_args_for_result},
util::mini_canonicalize,
@ -44,8 +44,7 @@ pub struct TraitEnvironment<'db> {
pub block: Option<BlockId>,
// FIXME make this a BTreeMap
traits_from_clauses: Box<[(Ty, TraitId)]>,
pub env: chalk_ir::Environment<Interner>,
_db: std::marker::PhantomData<&'db ()>,
pub env: ParamEnv<'db>,
}
impl<'db> TraitEnvironment<'db> {
@ -54,8 +53,7 @@ impl<'db> TraitEnvironment<'db> {
krate,
block: None,
traits_from_clauses: Box::default(),
env: chalk_ir::Environment::new(Interner),
_db: std::marker::PhantomData,
env: ParamEnv::empty(),
})
}
@ -63,15 +61,9 @@ impl<'db> TraitEnvironment<'db> {
krate: Crate,
block: Option<BlockId>,
traits_from_clauses: Box<[(Ty, TraitId)]>,
env: chalk_ir::Environment<Interner>,
env: ParamEnv<'db>,
) -> Arc<Self> {
Arc::new(TraitEnvironment {
krate,
block,
traits_from_clauses,
env,
_db: std::marker::PhantomData,
})
Arc::new(TraitEnvironment { krate, block, traits_from_clauses, env })
}
// pub fn with_block(self: &mut Arc<Self>, block: BlockId) {

View File

@ -88,7 +88,7 @@ use hir_ty::{
next_solver::{
ClauseKind, DbInterner, GenericArgs,
infer::InferCtxt,
mapping::{ChalkToNextSolver, convert_ty_for_result},
mapping::{ChalkToNextSolver, NextSolverToChalk, convert_ty_for_result},
},
primitive::UintTy,
traits::FnTrait,
@ -5171,7 +5171,14 @@ impl<'db> Type<'db> {
.build();
let goal = Canonical {
value: hir_ty::InEnvironment::new(&self.env.env, trait_ref.cast(Interner)),
value: hir_ty::InEnvironment::new(
&self.env.env.to_chalk(DbInterner::new_with(
db,
Some(self.env.krate),
self.env.block,
)),
trait_ref.cast(Interner),
),
binders: CanonicalVarKinds::empty(Interner),
};

View File

@ -26,6 +26,7 @@ mod visibility;
use base_db::{SourceDatabase, salsa};
use expect_test::Expect;
use hir::db::HirDatabase;
use hir::{PrefixKind, setup_tracing};
use ide_db::{
FilePosition, RootDatabase, SnippetCap,
@ -306,8 +307,11 @@ pub(crate) fn get_all_items(
trigger_character: Option<char>,
) -> Vec<CompletionItem> {
let (db, position) = position(code);
let res = salsa::attach(&db, || crate::completions(&db, &config, position, trigger_character))
.map_or_else(Vec::default, Into::into);
let res = salsa::attach(&db, || {
HirDatabase::zalsa_register_downcaster(&db);
crate::completions(&db, &config, position, trigger_character)
})
.map_or_else(Vec::default, Into::into);
// validate
res.iter().for_each(|it| {
let sr = it.source_range;

View File

@ -100,8 +100,8 @@ pub(crate) fn view_memory_layout(
Definition::SelfType(it) => it.self_ty(db),
Definition::Local(it) => it.ty(db),
Definition::Field(it) => salsa::attach(db, || it.ty(db).to_type(db)),
Definition::Const(it) => it.ty(db),
Definition::Static(it) => it.ty(db),
Definition::Const(it) => salsa::attach(db, || it.ty(db)),
Definition::Static(it) => salsa::attach(db, || it.ty(db)),
_ => return None,
};