mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-25 11:17:13 +00:00
Merge pull request #20728 from jackh726/next-trait-solver-next2
Use ParamEnv in TraitEnvironment
This commit is contained in:
commit
7804a2dd67
@ -32,11 +32,11 @@ const AUTODEREF_RECURSION_LIMIT: usize = 20;
|
||||
/// - the yielded types don't contain inference variables (but may contain `TyKind::Error`).
|
||||
/// - a type won't be yielded more than once; in other words, the returned iterator will stop if it
|
||||
/// detects a cycle in the deref chain.
|
||||
pub fn autoderef(
|
||||
db: &dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
pub fn autoderef<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
ty: crate::Canonical<crate::Ty>,
|
||||
) -> impl Iterator<Item = crate::Ty> {
|
||||
) -> impl Iterator<Item = crate::Ty> + use<> {
|
||||
let mut table = InferenceTable::new(db, env);
|
||||
let interner = table.interner;
|
||||
let ty = table.instantiate_canonical(ty);
|
||||
@ -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.
|
||||
|
@ -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()
|
||||
|
@ -229,7 +229,7 @@ pub(crate) fn const_eval_cycle_result(
|
||||
_: &dyn HirDatabase,
|
||||
_: GeneralConstId,
|
||||
_: Substitution,
|
||||
_: Option<Arc<TraitEnvironment>>,
|
||||
_: Option<Arc<TraitEnvironment<'_>>>,
|
||||
) -> Result<Const, ConstEvalError> {
|
||||
Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
|
||||
}
|
||||
@ -252,7 +252,7 @@ pub(crate) fn const_eval_query(
|
||||
db: &dyn HirDatabase,
|
||||
def: GeneralConstId,
|
||||
subst: Substitution,
|
||||
trait_env: Option<Arc<TraitEnvironment>>,
|
||||
trait_env: Option<Arc<TraitEnvironment<'_>>>,
|
||||
) -> Result<Const, ConstEvalError> {
|
||||
let body = match def {
|
||||
GeneralConstId::ConstId(c) => {
|
||||
|
@ -49,7 +49,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
||||
&self,
|
||||
def: DefWithBodyId,
|
||||
subst: Substitution,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'_>>,
|
||||
) -> Result<Arc<MirBody>, MirLowerError>;
|
||||
|
||||
#[salsa::invoke(crate::mir::monomorphized_mir_body_for_closure_query)]
|
||||
@ -57,7 +57,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
||||
&self,
|
||||
def: InternedClosureId,
|
||||
subst: Substitution,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'_>>,
|
||||
) -> Result<Arc<MirBody>, MirLowerError>;
|
||||
|
||||
#[salsa::invoke(crate::mir::borrowck_query)]
|
||||
@ -70,7 +70,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
||||
&self,
|
||||
def: GeneralConstId,
|
||||
subst: Substitution,
|
||||
trait_env: Option<Arc<TraitEnvironment>>,
|
||||
trait_env: Option<Arc<TraitEnvironment<'_>>>,
|
||||
) -> Result<Const, ConstEvalError>;
|
||||
|
||||
#[salsa::invoke(crate::consteval::const_eval_static_query)]
|
||||
@ -84,7 +84,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
||||
#[salsa::invoke(crate::method_resolution::lookup_impl_method_query)]
|
||||
fn lookup_impl_method(
|
||||
&self,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'_>>,
|
||||
func: FunctionId,
|
||||
fn_subst: Substitution,
|
||||
) -> (FunctionId, Substitution);
|
||||
@ -97,7 +97,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
||||
&'db self,
|
||||
def: AdtId,
|
||||
args: crate::next_solver::GenericArgs<'db>,
|
||||
trait_env: Arc<TraitEnvironment>,
|
||||
trait_env: Arc<TraitEnvironment<'db>>,
|
||||
) -> Result<Arc<Layout>, LayoutError>;
|
||||
|
||||
#[salsa::invoke(crate::layout::layout_of_ty_query)]
|
||||
@ -105,7 +105,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
||||
fn layout_of_ty<'db>(
|
||||
&'db self,
|
||||
ty: crate::next_solver::Ty<'db>,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
) -> Result<Arc<Layout>, LayoutError>;
|
||||
|
||||
#[salsa::invoke(crate::layout::target_data_layout_query)]
|
||||
@ -182,12 +182,13 @@ 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(&self, def: DefWithBodyId) -> Arc<TraitEnvironment>;
|
||||
fn trait_environment_for_body<'db>(&'db self, def: DefWithBodyId)
|
||||
-> Arc<TraitEnvironment<'db>>;
|
||||
|
||||
#[salsa::invoke(crate::lower::trait_environment_query)]
|
||||
fn trait_environment(&self, def: GenericDefId) -> Arc<TraitEnvironment>;
|
||||
#[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)]
|
||||
#[salsa::cycle(cycle_result = crate::lower::generic_defaults_with_diagnostics_cycle_result)]
|
||||
@ -258,7 +259,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
||||
fn normalize_projection(
|
||||
&self,
|
||||
projection: crate::ProjectionTy,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'_>>,
|
||||
) -> Ty;
|
||||
|
||||
#[salsa::invoke(crate::traits::trait_solve_query)]
|
||||
@ -272,7 +273,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
||||
|
||||
#[salsa::invoke(crate::drop::has_drop_glue)]
|
||||
#[salsa::cycle(cycle_result = crate::drop::has_drop_glue_cycle_result)]
|
||||
fn has_drop_glue(&self, ty: Ty, env: Arc<TraitEnvironment>) -> DropGlue;
|
||||
fn has_drop_glue(&self, ty: Ty, env: Arc<TraitEnvironment<'_>>) -> DropGlue;
|
||||
|
||||
// next trait solver
|
||||
|
||||
|
@ -81,17 +81,17 @@ impl BodyValidationDiagnostic {
|
||||
}
|
||||
}
|
||||
|
||||
struct ExprValidator {
|
||||
struct ExprValidator<'db> {
|
||||
owner: DefWithBodyId,
|
||||
body: Arc<Body>,
|
||||
infer: Arc<InferenceResult>,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
diagnostics: Vec<BodyValidationDiagnostic>,
|
||||
validate_lints: bool,
|
||||
}
|
||||
|
||||
impl ExprValidator {
|
||||
fn validate_body(&mut self, db: &dyn HirDatabase) {
|
||||
impl<'db> ExprValidator<'db> {
|
||||
fn validate_body(&mut self, db: &'db dyn HirDatabase) {
|
||||
let mut filter_map_next_checker = None;
|
||||
// we'll pass &mut self while iterating over body.exprs, so they need to be disjoint
|
||||
let body = Arc::clone(&self.body);
|
||||
|
@ -70,7 +70,7 @@ pub(crate) struct MatchCheckCtx<'db> {
|
||||
body: DefWithBodyId,
|
||||
pub(crate) db: &'db dyn HirDatabase,
|
||||
exhaustive_patterns: bool,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
}
|
||||
|
||||
impl<'db> MatchCheckCtx<'db> {
|
||||
@ -78,7 +78,7 @@ impl<'db> MatchCheckCtx<'db> {
|
||||
module: ModuleId,
|
||||
body: DefWithBodyId,
|
||||
db: &'db dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
) -> Self {
|
||||
let def_map = module.crate_def_map(db);
|
||||
let exhaustive_patterns = def_map.is_unstable_feature_enabled(&sym::exhaustive_patterns);
|
||||
|
@ -792,19 +792,16 @@ 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)
|
||||
}
|
||||
|
||||
fn render_const_scalar_inner(
|
||||
fn render_const_scalar_inner<'db>(
|
||||
f: &mut HirFormatter<'_>,
|
||||
b: &[u8],
|
||||
memory_map: &MemoryMap<'_>,
|
||||
ty: crate::next_solver::Ty<'_>,
|
||||
trait_env: Arc<TraitEnvironment>,
|
||||
ty: crate::next_solver::Ty<'db>,
|
||||
trait_env: Arc<TraitEnvironment<'db>>,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
use rustc_type_ir::TyKind;
|
||||
match ty.kind() {
|
||||
@ -1068,11 +1065,11 @@ fn render_const_scalar_inner(
|
||||
}
|
||||
}
|
||||
|
||||
fn render_variant_after_name(
|
||||
fn render_variant_after_name<'db>(
|
||||
data: &VariantFields,
|
||||
f: &mut HirFormatter<'_>,
|
||||
field_types: &ArenaMap<LocalFieldId, Binders<Ty>>,
|
||||
trait_env: Arc<TraitEnvironment>,
|
||||
trait_env: Arc<TraitEnvironment<'db>>,
|
||||
layout: &Layout,
|
||||
args: GenericArgs<'_>,
|
||||
b: &[u8],
|
||||
|
@ -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,
|
||||
@ -43,7 +45,11 @@ pub enum DropGlue {
|
||||
HasDropGlue,
|
||||
}
|
||||
|
||||
pub(crate) fn has_drop_glue(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironment>) -> DropGlue {
|
||||
pub(crate) fn has_drop_glue(
|
||||
db: &dyn HirDatabase,
|
||||
ty: Ty,
|
||||
env: Arc<TraitEnvironment<'_>>,
|
||||
) -> DropGlue {
|
||||
match ty.kind(Interner) {
|
||||
TyKind::Adt(adt, subst) => {
|
||||
if has_destructor(db, adt.0) {
|
||||
@ -165,7 +171,7 @@ pub(crate) fn has_drop_glue(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironm
|
||||
|
||||
fn projection_has_drop_glue(
|
||||
db: &dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'_>>,
|
||||
projection: ProjectionTy,
|
||||
ty: Ty,
|
||||
) -> DropGlue {
|
||||
@ -178,13 +184,16 @@ fn projection_has_drop_glue(
|
||||
}
|
||||
}
|
||||
|
||||
fn is_copy(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironment>) -> bool {
|
||||
fn is_copy(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironment<'_>>) -> bool {
|
||||
let Some(copy_trait) = LangItem::Copy.resolve_trait(db, env.krate) else {
|
||||
return false;
|
||||
};
|
||||
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()
|
||||
@ -193,7 +202,7 @@ fn is_copy(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironment>) -> bool {
|
||||
pub(crate) fn has_drop_glue_cycle_result(
|
||||
_db: &dyn HirDatabase,
|
||||
_ty: Ty,
|
||||
_env: Arc<TraitEnvironment>,
|
||||
_env: Arc<TraitEnvironment<'_>>,
|
||||
) -> DropGlue {
|
||||
DropGlue::None
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ pub(crate) fn infer_cycle_result(_: &dyn HirDatabase, _: DefWithBodyId) -> Arc<I
|
||||
/// This is appropriate to use only after type-check: it assumes
|
||||
/// that normalization will succeed, for example.
|
||||
#[tracing::instrument(level = "debug", skip(db))]
|
||||
pub(crate) fn normalize(db: &dyn HirDatabase, trait_env: Arc<TraitEnvironment>, ty: Ty) -> Ty {
|
||||
pub(crate) fn normalize(db: &dyn HirDatabase, trait_env: Arc<TraitEnvironment<'_>>, ty: Ty) -> Ty {
|
||||
// FIXME: TypeFlags::HAS_CT_PROJECTION is not implemented in chalk, so TypeFlags::HAS_PROJECTION only
|
||||
// works for the type case, so we check array unconditionally. Remove the array part
|
||||
// when the bug in chalk becomes fixed.
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
@ -1564,9 +1568,9 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn could_coerce(
|
||||
db: &dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
pub fn could_coerce<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
tys: &crate::Canonical<(crate::Ty, crate::Ty)>,
|
||||
) -> bool {
|
||||
coerce(db, env, tys).is_ok()
|
||||
@ -1574,7 +1578,7 @@ pub fn could_coerce(
|
||||
|
||||
fn coerce<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
tys: &crate::Canonical<(crate::Ty, crate::Ty)>,
|
||||
) -> Result<(Vec<Adjustment>, crate::Ty), TypeError<DbInterner<'db>>> {
|
||||
let mut table = InferenceTable::new(db, env);
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
@ -121,7 +121,7 @@ impl<'a, 'db> ProofTreeVisitor<'db> for NestedObligationsForSelfTy<'a, 'db> {
|
||||
/// unresolved goal `T = U`.
|
||||
pub fn could_unify(
|
||||
db: &dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'_>>,
|
||||
tys: &Canonical<(Ty, Ty)>,
|
||||
) -> bool {
|
||||
unify(db, env, tys).is_some()
|
||||
@ -133,7 +133,7 @@ pub fn could_unify(
|
||||
/// them. For example `Option<T>` and `Option<U>` do not unify as we cannot show that `T = U`
|
||||
pub fn could_unify_deeply(
|
||||
db: &dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'_>>,
|
||||
tys: &Canonical<(Ty, Ty)>,
|
||||
) -> bool {
|
||||
let mut table = InferenceTable::new(db, env);
|
||||
@ -151,7 +151,7 @@ pub fn could_unify_deeply(
|
||||
|
||||
pub(crate) fn unify(
|
||||
db: &dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'_>>,
|
||||
tys: &Canonical<(Ty, Ty)>,
|
||||
) -> Option<Substitution> {
|
||||
let mut table = InferenceTable::new(db, env);
|
||||
@ -212,8 +212,7 @@ bitflags::bitflags! {
|
||||
pub(crate) struct InferenceTable<'db> {
|
||||
pub(crate) db: &'db dyn HirDatabase,
|
||||
pub(crate) interner: DbInterner<'db>,
|
||||
pub(crate) trait_env: Arc<TraitEnvironment>,
|
||||
pub(crate) param_env: ParamEnv<'db>,
|
||||
pub(crate) trait_env: Arc<TraitEnvironment<'db>>,
|
||||
pub(crate) tait_coercion_table: Option<FxHashMap<OpaqueTyId, Ty>>,
|
||||
pub(crate) infer_ctxt: InferCtxt<'db>,
|
||||
diverging_tys: FxHashSet<Ty>,
|
||||
@ -227,7 +226,7 @@ pub(crate) struct InferenceTableSnapshot<'db> {
|
||||
}
|
||||
|
||||
impl<'db> InferenceTable<'db> {
|
||||
pub(crate) fn new(db: &'db dyn HirDatabase, trait_env: Arc<TraitEnvironment>) -> Self {
|
||||
pub(crate) fn new(db: &'db dyn HirDatabase, trait_env: Arc<TraitEnvironment<'db>>) -> Self {
|
||||
let interner = DbInterner::new_with(db, Some(trait_env.krate), trait_env.block);
|
||||
let infer_ctxt = interner.infer_ctxt().build(rustc_type_ir::TypingMode::Analysis {
|
||||
defining_opaque_types_and_generators: SolverDefIds::new_from_iter(interner, []),
|
||||
@ -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)
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ pub(crate) fn is_ty_uninhabited_from(
|
||||
db: &dyn HirDatabase,
|
||||
ty: &Ty,
|
||||
target_mod: ModuleId,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'_>>,
|
||||
) -> bool {
|
||||
let _p = tracing::info_span!("is_ty_uninhabited_from", ?ty).entered();
|
||||
let mut uninhabited_from =
|
||||
@ -36,7 +36,7 @@ pub(crate) fn is_enum_variant_uninhabited_from(
|
||||
variant: EnumVariantId,
|
||||
subst: &Substitution,
|
||||
target_mod: ModuleId,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'_>>,
|
||||
) -> bool {
|
||||
let _p = tracing::info_span!("is_enum_variant_uninhabited_from").entered();
|
||||
|
||||
@ -52,7 +52,7 @@ struct UninhabitedFrom<'a> {
|
||||
// guard for preventing stack overflow in non trivial non terminating types
|
||||
max_depth: usize,
|
||||
db: &'a dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'a>>,
|
||||
}
|
||||
|
||||
const CONTINUE_OPAQUELY_INHABITED: ControlFlow<VisiblyUninhabited> = Continue(());
|
||||
|
@ -132,7 +132,7 @@ fn layout_of_simd_ty<'db>(
|
||||
id: StructId,
|
||||
repr_packed: bool,
|
||||
args: &GenericArgs<'db>,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
dl: &TargetDataLayout,
|
||||
) -> Result<Arc<Layout>, LayoutError> {
|
||||
// Supported SIMD vectors are homogeneous ADTs with exactly one array field:
|
||||
@ -160,7 +160,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>,
|
||||
trait_env: Arc<TraitEnvironment<'db>>,
|
||||
) -> Result<Arc<Layout>, LayoutError> {
|
||||
let krate = trait_env.krate;
|
||||
let interner = DbInterner::new_with(db, Some(krate), trait_env.block);
|
||||
@ -371,7 +371,7 @@ pub fn layout_of_ty_query<'db>(
|
||||
pub(crate) fn layout_of_ty_cycle_result<'db>(
|
||||
_: &dyn HirDatabase,
|
||||
_: Ty<'db>,
|
||||
_: Arc<TraitEnvironment>,
|
||||
_: Arc<TraitEnvironment<'db>>,
|
||||
) -> Result<Arc<Layout>, LayoutError> {
|
||||
Err(LayoutError::RecursiveTypeWithoutIndirection)
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ pub fn layout_of_adt_query<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
def: AdtId,
|
||||
args: GenericArgs<'db>,
|
||||
trait_env: Arc<TraitEnvironment>,
|
||||
trait_env: Arc<TraitEnvironment<'db>>,
|
||||
) -> Result<Arc<Layout>, LayoutError> {
|
||||
let krate = trait_env.krate;
|
||||
let Ok(target) = db.target_data_layout(krate) else {
|
||||
@ -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>,
|
||||
_trait_env: Arc<TraitEnvironment<'db>>,
|
||||
) -> Result<Arc<Layout>, LayoutError> {
|
||||
Err(LayoutError::RecursiveTypeWithoutIndirection)
|
||||
}
|
||||
|
@ -940,10 +940,10 @@ where
|
||||
Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(Interner, kinds) }
|
||||
}
|
||||
|
||||
pub fn callable_sig_from_fn_trait(
|
||||
pub fn callable_sig_from_fn_trait<'db>(
|
||||
self_ty: &Ty,
|
||||
trait_env: Arc<TraitEnvironment>,
|
||||
db: &dyn HirDatabase,
|
||||
trait_env: Arc<TraitEnvironment<'db>>,
|
||||
db: &'db dyn HirDatabase,
|
||||
) -> Option<(FnTrait, CallableSig)> {
|
||||
let krate = trait_env.krate;
|
||||
let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?;
|
||||
|
@ -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: &dyn HirDatabase,
|
||||
def: GenericDefId,
|
||||
) -> Arc<TraitEnvironment> {
|
||||
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>]>>);
|
||||
|
||||
|
@ -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(¶m_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,
|
||||
|
@ -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},
|
||||
@ -545,7 +545,7 @@ pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option<Sma
|
||||
pub(crate) fn lookup_method<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
ty: &next_solver::Canonical<'db, crate::next_solver::Ty<'db>>,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
traits_in_scope: &FxHashSet<TraitId>,
|
||||
visible_from_module: VisibleFromModule,
|
||||
name: &Name,
|
||||
@ -714,7 +714,7 @@ impl ReceiverAdjustments {
|
||||
pub(crate) fn iterate_method_candidates<'db, T>(
|
||||
ty: &next_solver::Canonical<'db, crate::next_solver::Ty<'db>>,
|
||||
db: &'db dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
traits_in_scope: &FxHashSet<TraitId>,
|
||||
visible_from_module: VisibleFromModule,
|
||||
name: Option<&Name>,
|
||||
@ -742,9 +742,9 @@ pub(crate) fn iterate_method_candidates<'db, T>(
|
||||
slot
|
||||
}
|
||||
|
||||
pub fn lookup_impl_const(
|
||||
db: &dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
pub fn lookup_impl_const<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
const_id: ConstId,
|
||||
subs: Substitution,
|
||||
) -> (ConstId, Substitution) {
|
||||
@ -770,9 +770,9 @@ pub fn lookup_impl_const(
|
||||
|
||||
/// Checks if the self parameter of `Trait` method is the `dyn Trait` and we should
|
||||
/// call the method using the vtable.
|
||||
pub fn is_dyn_method(
|
||||
db: &dyn HirDatabase,
|
||||
_env: Arc<TraitEnvironment>,
|
||||
pub fn is_dyn_method<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
_env: Arc<TraitEnvironment<'db>>,
|
||||
func: FunctionId,
|
||||
fn_subst: Substitution,
|
||||
) -> Option<usize> {
|
||||
@ -812,9 +812,9 @@ pub fn is_dyn_method(
|
||||
/// Looks up the impl method that actually runs for the trait method `func`.
|
||||
///
|
||||
/// Returns `func` if it's not a method defined in a trait or the lookup failed.
|
||||
pub(crate) fn lookup_impl_method_query(
|
||||
db: &dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
pub(crate) fn lookup_impl_method_query<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
func: FunctionId,
|
||||
fn_subst: Substitution,
|
||||
) -> (FunctionId, Substitution) {
|
||||
@ -845,10 +845,10 @@ pub(crate) fn lookup_impl_method_query(
|
||||
)
|
||||
}
|
||||
|
||||
fn lookup_impl_assoc_item_for_trait_ref(
|
||||
fn lookup_impl_assoc_item_for_trait_ref<'db>(
|
||||
trait_ref: TraitRef,
|
||||
db: &dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
db: &'db dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
name: &Name,
|
||||
) -> Option<(AssocItemId, Substitution)> {
|
||||
let hir_trait_id = trait_ref.hir_trait_id();
|
||||
@ -1067,7 +1067,7 @@ pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool {
|
||||
pub fn iterate_path_candidates<'db>(
|
||||
ty: &next_solver::Canonical<'db, crate::next_solver::Ty<'db>>,
|
||||
db: &'db dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
traits_in_scope: &FxHashSet<TraitId>,
|
||||
visible_from_module: VisibleFromModule,
|
||||
name: Option<&Name>,
|
||||
@ -1089,7 +1089,7 @@ pub fn iterate_path_candidates<'db>(
|
||||
pub fn iterate_method_candidates_dyn<'db>(
|
||||
ty: &next_solver::Canonical<'db, crate::next_solver::Ty<'db>>,
|
||||
db: &'db dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
traits_in_scope: &FxHashSet<TraitId>,
|
||||
visible_from_module: VisibleFromModule,
|
||||
name: Option<&Name>,
|
||||
@ -1351,7 +1351,7 @@ fn iterate_method_candidates_by_receiver<'db>(
|
||||
fn iterate_method_candidates_for_self_ty<'db>(
|
||||
self_ty: &next_solver::Canonical<'db, crate::next_solver::Ty<'db>>,
|
||||
db: &'db dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
traits_in_scope: &FxHashSet<TraitId>,
|
||||
visible_from_module: VisibleFromModule,
|
||||
name: Option<&Name>,
|
||||
@ -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() {
|
||||
@ -1856,10 +1864,10 @@ fn is_valid_impl_fn_candidate(
|
||||
})
|
||||
}
|
||||
|
||||
pub fn implements_trait_unique(
|
||||
pub fn implements_trait_unique<'db>(
|
||||
ty: &Canonical<Ty>,
|
||||
db: &dyn HirDatabase,
|
||||
env: &TraitEnvironment,
|
||||
db: &'db dyn HirDatabase,
|
||||
env: &TraitEnvironment<'db>,
|
||||
trait_: TraitId,
|
||||
) -> bool {
|
||||
let goal = generic_implements_goal(db, env, trait_, ty);
|
||||
@ -1869,9 +1877,9 @@ pub fn implements_trait_unique(
|
||||
/// This creates Substs for a trait with the given Self type and type variables
|
||||
/// for all other parameters, to query next solver with it.
|
||||
#[tracing::instrument(skip_all)]
|
||||
fn generic_implements_goal(
|
||||
db: &dyn HirDatabase,
|
||||
env: &TraitEnvironment,
|
||||
fn generic_implements_goal<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
env: &TraitEnvironment<'db>,
|
||||
trait_: TraitId,
|
||||
self_ty: &Canonical<Ty>,
|
||||
) -> Canonical<InEnvironment<super::DomainGoal>> {
|
||||
@ -1893,7 +1901,10 @@ fn generic_implements_goal(
|
||||
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)
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ enum MirOrDynIndex {
|
||||
|
||||
pub struct Evaluator<'a> {
|
||||
db: &'a dyn HirDatabase,
|
||||
trait_env: Arc<TraitEnvironment>,
|
||||
trait_env: Arc<TraitEnvironment<'a>>,
|
||||
target_data_layout: Arc<TargetDataLayout>,
|
||||
stack: Vec<u8>,
|
||||
heap: Vec<u8>,
|
||||
@ -582,8 +582,8 @@ impl MirOutput {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn interpret_mir(
|
||||
db: &dyn HirDatabase,
|
||||
pub fn interpret_mir<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
body: Arc<MirBody>,
|
||||
// FIXME: This is workaround. Ideally, const generics should have a separate body (issue #7434), but now
|
||||
// they share their body with their parent, so in MIR lowering we have locals of the parent body, which
|
||||
@ -591,7 +591,7 @@ pub fn interpret_mir(
|
||||
// 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>>,
|
||||
trait_env: Option<Arc<TraitEnvironment<'db>>>,
|
||||
) -> Result<(Result<Const>, MirOutput)> {
|
||||
let ty = body.locals[return_slot()].ty.clone();
|
||||
let mut evaluator = Evaluator::new(db, body.owner, assert_placeholder_ty_is_unused, trait_env)?;
|
||||
@ -632,11 +632,11 @@ const EXECUTION_LIMIT: usize = 10_000_000;
|
||||
|
||||
impl<'db> Evaluator<'db> {
|
||||
pub fn new(
|
||||
db: &dyn HirDatabase,
|
||||
db: &'db dyn HirDatabase,
|
||||
owner: DefWithBodyId,
|
||||
assert_placeholder_ty_is_unused: bool,
|
||||
trait_env: Option<Arc<TraitEnvironment>>,
|
||||
) -> Result<Evaluator<'_>> {
|
||||
trait_env: Option<Arc<TraitEnvironment<'db>>>,
|
||||
) -> Result<Evaluator<'db>> {
|
||||
let crate_id = owner.module(db).krate();
|
||||
let target_data_layout = match db.target_data_layout(crate_id) {
|
||||
Ok(target_data_layout) => target_data_layout,
|
||||
|
@ -82,7 +82,7 @@ struct MirLowerCtx<'db> {
|
||||
infer: &'db InferenceResult,
|
||||
resolver: Resolver<'db>,
|
||||
drop_scopes: Vec<DropScope>,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
}
|
||||
|
||||
// FIXME: Make this smaller, its stored in database queries
|
||||
|
@ -35,7 +35,7 @@ macro_rules! not_supported {
|
||||
|
||||
struct Filler<'a> {
|
||||
db: &'a dyn HirDatabase,
|
||||
trait_env: Arc<TraitEnvironment>,
|
||||
trait_env: Arc<TraitEnvironment<'a>>,
|
||||
subst: &'a Substitution,
|
||||
generics: Option<Generics>,
|
||||
}
|
||||
@ -301,11 +301,11 @@ impl Filler<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn monomorphized_mir_body_query(
|
||||
db: &dyn HirDatabase,
|
||||
pub fn monomorphized_mir_body_query<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
owner: DefWithBodyId,
|
||||
subst: Substitution,
|
||||
trait_env: Arc<crate::TraitEnvironment>,
|
||||
trait_env: Arc<crate::TraitEnvironment<'db>>,
|
||||
) -> Result<Arc<MirBody>, MirLowerError> {
|
||||
let generics = owner.as_generic_def_id(db).map(|g_def| generics(db, g_def));
|
||||
let filler = &mut Filler { db, subst: &subst, trait_env, generics };
|
||||
@ -315,20 +315,20 @@ pub fn monomorphized_mir_body_query(
|
||||
Ok(Arc::new(body))
|
||||
}
|
||||
|
||||
pub(crate) fn monomorphized_mir_body_cycle_result(
|
||||
_db: &dyn HirDatabase,
|
||||
pub(crate) fn monomorphized_mir_body_cycle_result<'db>(
|
||||
_db: &'db dyn HirDatabase,
|
||||
_: DefWithBodyId,
|
||||
_: Substitution,
|
||||
_: Arc<crate::TraitEnvironment>,
|
||||
_: Arc<crate::TraitEnvironment<'db>>,
|
||||
) -> Result<Arc<MirBody>, MirLowerError> {
|
||||
Err(MirLowerError::Loop)
|
||||
}
|
||||
|
||||
pub fn monomorphized_mir_body_for_closure_query(
|
||||
db: &dyn HirDatabase,
|
||||
pub fn monomorphized_mir_body_for_closure_query<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
closure: InternedClosureId,
|
||||
subst: Substitution,
|
||||
trait_env: Arc<crate::TraitEnvironment>,
|
||||
trait_env: Arc<crate::TraitEnvironment<'db>>,
|
||||
) -> Result<Arc<MirBody>, MirLowerError> {
|
||||
let InternedClosure(owner, _) = db.lookup_intern_closure(closure);
|
||||
let generics = owner.as_generic_def_id(db).map(|g_def| generics(db, g_def));
|
||||
|
@ -1266,7 +1266,7 @@ pub fn convert_args_for_result<'db>(
|
||||
Substitution::from_iter(Interner, substs)
|
||||
}
|
||||
|
||||
pub(crate) fn convert_ty_for_result<'db>(interner: DbInterner<'db>, ty: Ty<'db>) -> crate::Ty {
|
||||
pub fn convert_ty_for_result<'db>(interner: DbInterner<'db>, ty: Ty<'db>) -> crate::Ty {
|
||||
use crate::{Scalar, TyKind};
|
||||
use chalk_ir::{FloatTy, IntTy, UintTy};
|
||||
match ty.kind() {
|
||||
|
@ -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
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
@ -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,
|
||||
@ -39,21 +39,21 @@ use crate::{
|
||||
/// ```
|
||||
/// we assume that `T: Default`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct TraitEnvironment {
|
||||
pub struct TraitEnvironment<'db> {
|
||||
pub krate: Crate,
|
||||
pub block: Option<BlockId>,
|
||||
// FIXME make this a BTreeMap
|
||||
traits_from_clauses: Box<[(Ty, TraitId)]>,
|
||||
pub env: chalk_ir::Environment<Interner>,
|
||||
pub env: ParamEnv<'db>,
|
||||
}
|
||||
|
||||
impl TraitEnvironment {
|
||||
impl<'db> TraitEnvironment<'db> {
|
||||
pub fn empty(krate: Crate) -> Arc<Self> {
|
||||
Arc::new(TraitEnvironment {
|
||||
krate,
|
||||
block: None,
|
||||
traits_from_clauses: Box::default(),
|
||||
env: chalk_ir::Environment::new(Interner),
|
||||
env: ParamEnv::empty(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ impl TraitEnvironment {
|
||||
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 })
|
||||
}
|
||||
@ -78,10 +78,10 @@ impl TraitEnvironment {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn normalize_projection_query(
|
||||
db: &dyn HirDatabase,
|
||||
pub(crate) fn normalize_projection_query<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
projection: ProjectionTy,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
) -> Ty {
|
||||
if projection.substitution.iter(Interner).any(|arg| {
|
||||
arg.ty(Interner)
|
||||
|
@ -24,7 +24,7 @@ use crate::{
|
||||
Adt, AsAssocItem, AssocItem, AssocItemContainer, Const, ConstParam, Crate, Enum,
|
||||
ExternCrateDecl, Field, Function, GenericParam, HasCrate, HasVisibility, Impl, LifetimeParam,
|
||||
Macro, Module, SelfParam, Static, Struct, StructKind, Trait, TraitRef, TupleField, TyBuilder,
|
||||
Type, TypeAlias, TypeOrConstParam, TypeParam, Union, Variant,
|
||||
Type, TypeAlias, TypeNs, TypeOrConstParam, TypeParam, Union, Variant,
|
||||
};
|
||||
|
||||
impl HirDisplay for Function {
|
||||
@ -437,6 +437,12 @@ impl HirDisplay for Type<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl HirDisplay for TypeNs<'_> {
|
||||
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
|
||||
self.ty.hir_fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl HirDisplay for ExternCrateDecl {
|
||||
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
|
||||
write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
|
||||
|
@ -86,7 +86,9 @@ use hir_ty::{
|
||||
method_resolution,
|
||||
mir::{MutBorrowKind, interpret_mir},
|
||||
next_solver::{
|
||||
ClauseKind, DbInterner, GenericArgs, infer::InferCtxt, mapping::ChalkToNextSolver,
|
||||
ClauseKind, DbInterner, GenericArgs,
|
||||
infer::InferCtxt,
|
||||
mapping::{ChalkToNextSolver, NextSolverToChalk, convert_ty_for_result},
|
||||
},
|
||||
primitive::UintTy,
|
||||
traits::FnTrait,
|
||||
@ -680,7 +682,7 @@ impl Module {
|
||||
push_ty_diagnostics(
|
||||
db,
|
||||
acc,
|
||||
db.field_types_with_diagnostics(s.id.into()).1,
|
||||
db.field_types_with_diagnostics_ns(s.id.into()).1,
|
||||
source_map,
|
||||
);
|
||||
}
|
||||
@ -692,7 +694,7 @@ impl Module {
|
||||
push_ty_diagnostics(
|
||||
db,
|
||||
acc,
|
||||
db.field_types_with_diagnostics(u.id.into()).1,
|
||||
db.field_types_with_diagnostics_ns(u.id.into()).1,
|
||||
source_map,
|
||||
);
|
||||
}
|
||||
@ -722,7 +724,7 @@ impl Module {
|
||||
push_ty_diagnostics(
|
||||
db,
|
||||
acc,
|
||||
db.field_types_with_diagnostics(v.into()).1,
|
||||
db.field_types_with_diagnostics_ns(v.into()).1,
|
||||
source_map,
|
||||
);
|
||||
expr_store_diagnostics(db, acc, source_map);
|
||||
@ -738,7 +740,7 @@ impl Module {
|
||||
push_ty_diagnostics(
|
||||
db,
|
||||
acc,
|
||||
db.type_for_type_alias_with_diagnostics(type_alias.id).1,
|
||||
db.type_for_type_alias_with_diagnostics_ns(type_alias.id).1,
|
||||
&source_map,
|
||||
);
|
||||
acc.extend(def.diagnostics(db, style_lints));
|
||||
@ -913,13 +915,13 @@ impl Module {
|
||||
push_ty_diagnostics(
|
||||
db,
|
||||
acc,
|
||||
db.impl_self_ty_with_diagnostics(impl_def.id).1,
|
||||
db.impl_self_ty_with_diagnostics_ns(impl_def.id).1,
|
||||
&source_map,
|
||||
);
|
||||
push_ty_diagnostics(
|
||||
db,
|
||||
acc,
|
||||
db.impl_trait_with_diagnostics(impl_def.id).and_then(|it| it.1),
|
||||
db.impl_trait_with_diagnostics_ns(impl_def.id).and_then(|it| it.1),
|
||||
&source_map,
|
||||
);
|
||||
|
||||
@ -1346,19 +1348,12 @@ impl Field {
|
||||
u32::from(self.id.into_raw()) as usize
|
||||
}
|
||||
|
||||
/// Returns the type as in the signature of the struct (i.e., with
|
||||
/// placeholder types for type parameters). Only use this in the context of
|
||||
/// the field definition.
|
||||
pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> {
|
||||
/// Returns the type as in the signature of the struct. Only use this in the
|
||||
/// context of the field definition.
|
||||
pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> TypeNs<'db> {
|
||||
let var_id = self.parent.into();
|
||||
let generic_def_id: GenericDefId = match self.parent {
|
||||
VariantDef::Struct(it) => it.id.into(),
|
||||
VariantDef::Union(it) => it.id.into(),
|
||||
VariantDef::Variant(it) => it.id.lookup(db).parent.into(),
|
||||
};
|
||||
let substs = TyBuilder::placeholder_subst(db, generic_def_id);
|
||||
let ty = db.field_types(var_id)[self.id].clone().substitute(Interner, &substs);
|
||||
Type::new(db, var_id, ty)
|
||||
let ty = db.field_types_ns(var_id)[self.id].skip_binder();
|
||||
TypeNs::new(db, var_id, ty)
|
||||
}
|
||||
|
||||
// FIXME: Find better API to also handle const generics
|
||||
@ -1388,9 +1383,8 @@ impl Field {
|
||||
}
|
||||
|
||||
pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
db.layout_of_ty(
|
||||
self.ty(db).ty.to_nextsolver(interner),
|
||||
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())
|
||||
@ -3646,7 +3640,7 @@ impl AssocItem {
|
||||
push_ty_diagnostics(
|
||||
db,
|
||||
acc,
|
||||
db.type_for_type_alias_with_diagnostics(type_alias.id).1,
|
||||
db.type_for_type_alias_with_diagnostics_ns(type_alias.id).1,
|
||||
&db.type_alias_signature_with_source_map(type_alias.id).1,
|
||||
);
|
||||
for diag in hir_ty::diagnostics::incorrect_case(db, type_alias.id.into()) {
|
||||
@ -3782,7 +3776,7 @@ impl GenericDef {
|
||||
push_ty_diagnostics(
|
||||
db,
|
||||
acc,
|
||||
db.const_param_ty_with_diagnostics(ConstParamId::from_unchecked(
|
||||
db.const_param_ty_with_diagnostics_ns(ConstParamId::from_unchecked(
|
||||
TypeOrConstParamId { parent: def, local_id: param_id },
|
||||
))
|
||||
.1,
|
||||
@ -3814,12 +3808,12 @@ impl GenericDef {
|
||||
pub struct GenericSubstitution<'db> {
|
||||
def: GenericDefId,
|
||||
subst: Substitution,
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
_pd: PhantomCovariantLifetime<'db>,
|
||||
}
|
||||
|
||||
impl<'db> GenericSubstitution<'db> {
|
||||
fn new(def: GenericDefId, subst: Substitution, env: Arc<TraitEnvironment>) -> Self {
|
||||
fn new(def: GenericDefId, subst: Substitution, env: Arc<TraitEnvironment<'db>>) -> Self {
|
||||
Self { def, subst, env, _pd: PhantomCovariantLifetime::new() }
|
||||
}
|
||||
|
||||
@ -4573,7 +4567,7 @@ impl Impl {
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct TraitRef<'db> {
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
trait_ref: hir_ty::next_solver::TraitRef<'db>,
|
||||
_pd: PhantomCovariantLifetime<'db>,
|
||||
}
|
||||
@ -4796,7 +4790,7 @@ impl CaptureUsageSource {
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct Type<'db> {
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
ty: Ty,
|
||||
_pd: PhantomCovariantLifetime<'db>,
|
||||
}
|
||||
@ -5177,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),
|
||||
};
|
||||
|
||||
@ -5951,7 +5952,7 @@ impl<'db> Type<'db> {
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct TypeNs<'db> {
|
||||
env: Arc<TraitEnvironment>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
ty: hir_ty::next_solver::Ty<'db>,
|
||||
_pd: PhantomCovariantLifetime<'db>,
|
||||
}
|
||||
@ -5969,6 +5970,11 @@ impl<'db> TypeNs<'db> {
|
||||
TypeNs { env: environment, ty, _pd: PhantomCovariantLifetime::new() }
|
||||
}
|
||||
|
||||
pub fn to_type(&self, db: &'db dyn HirDatabase) -> Type<'db> {
|
||||
let interner = DbInterner::new_with(db, Some(self.env.krate), self.env.block);
|
||||
Type { env: self.env.clone(), ty: convert_ty_for_result(interner, self.ty), _pd: self._pd }
|
||||
}
|
||||
|
||||
// FIXME: Find better API that also handles const generics
|
||||
pub fn impls_trait(&self, infcx: InferCtxt<'db>, trait_: Trait, args: &[TypeNs<'db>]) -> bool {
|
||||
let args = GenericArgs::new_from_iter(
|
||||
@ -5992,6 +5998,10 @@ impl<'db> TypeNs<'db> {
|
||||
let res = hir_ty::traits::next_trait_solve_in_ctxt(&infcx, goal);
|
||||
res.map_or(false, |res| matches!(res.1, rustc_type_ir::solve::Certainty::Yes))
|
||||
}
|
||||
|
||||
pub fn is_bool(&self) -> bool {
|
||||
matches!(self.ty.kind(), rustc_type_ir::TyKind::Bool)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
|
||||
|
@ -219,7 +219,7 @@ impl<'db> SourceAnalyzer<'db> {
|
||||
})
|
||||
}
|
||||
|
||||
fn trait_environment(&self, db: &'db dyn HirDatabase) -> Arc<TraitEnvironment> {
|
||||
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),
|
||||
|
@ -521,7 +521,7 @@ fn build_pat(
|
||||
hir::StructKind::Tuple => {
|
||||
let mut name_generator = suggest_name::NameGenerator::default();
|
||||
let pats = fields.into_iter().map(|f| {
|
||||
let name = name_generator.for_type(&f.ty(db), db, edition);
|
||||
let name = name_generator.for_type(&f.ty(db).to_type(db), db, edition);
|
||||
match name {
|
||||
Some(name) => make::ext::simple_ident_pat(make.name(&name)).into(),
|
||||
None => make.wildcard_pat().into(),
|
||||
|
@ -145,8 +145,11 @@ fn expand_tuple_struct_rest_pattern(
|
||||
make.ident_pat(
|
||||
false,
|
||||
false,
|
||||
match name_gen.for_type(&f.ty(ctx.sema.db), ctx.sema.db, ctx.edition())
|
||||
{
|
||||
match name_gen.for_type(
|
||||
&f.ty(ctx.sema.db).to_type(ctx.sema.db),
|
||||
ctx.sema.db,
|
||||
ctx.edition(),
|
||||
) {
|
||||
Some(name) => make.name(&name),
|
||||
None => make.name(&format!("_{}", f.index())),
|
||||
},
|
||||
|
@ -28,7 +28,11 @@ pub(crate) fn complete_record_pattern_fields(
|
||||
record_pat.record_pat_field_list().and_then(|fl| fl.fields().next()).is_some();
|
||||
|
||||
match were_fields_specified {
|
||||
false => un.fields(ctx.db).into_iter().map(|f| (f, f.ty(ctx.db))).collect(),
|
||||
false => un
|
||||
.fields(ctx.db)
|
||||
.into_iter()
|
||||
.map(|f| (f, f.ty(ctx.db).to_type(ctx.db)))
|
||||
.collect(),
|
||||
true => return,
|
||||
}
|
||||
}
|
||||
@ -56,7 +60,11 @@ pub(crate) fn complete_record_expr_fields(
|
||||
record_expr.record_expr_field_list().and_then(|fl| fl.fields().next()).is_some();
|
||||
|
||||
match were_fields_specified {
|
||||
false => un.fields(ctx.db).into_iter().map(|f| (f, f.ty(ctx.db))).collect(),
|
||||
false => un
|
||||
.fields(ctx.db)
|
||||
.into_iter()
|
||||
.map(|f| (f, f.ty(ctx.db).to_type(ctx.db)))
|
||||
.collect(),
|
||||
true => return,
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -88,7 +88,7 @@ pub(crate) fn goto_type_definition(
|
||||
ast::Pat(it) => sema.type_of_pat(&it)?.original,
|
||||
ast::SelfParam(it) => sema.type_of_self(&it)?,
|
||||
ast::Type(it) => sema.resolve_type(&it)?,
|
||||
ast::RecordField(it) => sema.to_def(&it)?.ty(db),
|
||||
ast::RecordField(it) => sema.to_def(&it)?.ty(db).to_type(db),
|
||||
// can't match on RecordExprField directly as `ast::Expr` will match an iteration too early otherwise
|
||||
ast::NameRef(it) => {
|
||||
if let Some(record_field) = ast::RecordExprField::for_name_ref(&it) {
|
||||
|
@ -440,7 +440,7 @@ pub(crate) fn hover_for_definition(
|
||||
Definition::Local(it) => Some(it.ty(db)),
|
||||
Definition::GenericParam(hir::GenericParam::ConstParam(it)) => Some(it.ty(db)),
|
||||
Definition::GenericParam(hir::GenericParam::TypeParam(it)) => Some(it.ty(db)),
|
||||
Definition::Field(field) => Some(field.ty(db)),
|
||||
Definition::Field(field) => Some(field.ty(db).to_type(db)),
|
||||
Definition::TupleField(it) => Some(it.ty(db)),
|
||||
Definition::Function(it) => Some(it.ty(db)),
|
||||
Definition::Adt(it) => Some(it.ty(db)),
|
||||
@ -602,7 +602,7 @@ fn goto_type_action_for_def(
|
||||
|
||||
let ty = match def {
|
||||
Definition::Local(it) => Some(it.ty(db)),
|
||||
Definition::Field(field) => Some(field.ty(db)),
|
||||
Definition::Field(field) => Some(field.ty(db).to_type(db)),
|
||||
Definition::TupleField(field) => Some(field.ty(db)),
|
||||
Definition::Const(it) => Some(it.ty(db)),
|
||||
Definition::Static(it) => Some(it.ty(db)),
|
||||
|
@ -692,14 +692,14 @@ pub(super) fn definition(
|
||||
}
|
||||
let drop_info = match def {
|
||||
Definition::Field(field) => {
|
||||
DropInfo { drop_glue: field.ty(db).drop_glue(db), has_dtor: None }
|
||||
DropInfo { drop_glue: field.ty(db).to_type(db).drop_glue(db), has_dtor: None }
|
||||
}
|
||||
Definition::Adt(Adt::Struct(strukt)) => {
|
||||
let struct_drop_glue = strukt.ty_placeholders(db).drop_glue(db);
|
||||
let mut fields_drop_glue = strukt
|
||||
.fields(db)
|
||||
.iter()
|
||||
.map(|field| field.ty(db).drop_glue(db))
|
||||
.map(|field| field.ty(db).to_type(db).drop_glue(db))
|
||||
.max()
|
||||
.unwrap_or(DropGlue::None);
|
||||
let has_dtor = match (fields_drop_glue, struct_drop_glue) {
|
||||
@ -727,7 +727,7 @@ pub(super) fn definition(
|
||||
variant
|
||||
.fields(db)
|
||||
.iter()
|
||||
.map(|field| field.ty(db).drop_glue(db))
|
||||
.map(|field| field.ty(db).to_type(db).drop_glue(db))
|
||||
.max()
|
||||
.unwrap_or(DropGlue::None)
|
||||
})
|
||||
@ -742,7 +742,7 @@ pub(super) fn definition(
|
||||
let fields_drop_glue = variant
|
||||
.fields(db)
|
||||
.iter()
|
||||
.map(|field| field.ty(db).drop_glue(db))
|
||||
.map(|field| field.ty(db).to_type(db).drop_glue(db))
|
||||
.max()
|
||||
.unwrap_or(DropGlue::None);
|
||||
DropInfo { drop_glue: fields_drop_glue, has_dtor: None }
|
||||
|
@ -526,7 +526,7 @@ fn signature_help_for_tuple_struct_pat(
|
||||
pat.syntax(),
|
||||
token,
|
||||
pat.fields(),
|
||||
fields.into_iter().map(|it| it.ty(db)),
|
||||
fields.into_iter().map(|it| it.ty(db).to_type(db)),
|
||||
display_target,
|
||||
))
|
||||
}
|
||||
|
@ -99,9 +99,9 @@ pub(crate) fn view_memory_layout(
|
||||
Definition::BuiltinType(it) => it.ty(db),
|
||||
Definition::SelfType(it) => it.self_ty(db),
|
||||
Definition::Local(it) => it.ty(db),
|
||||
Definition::Field(it) => it.ty(db),
|
||||
Definition::Const(it) => it.ty(db),
|
||||
Definition::Static(it) => it.ty(db),
|
||||
Definition::Field(it) => salsa::attach(db, || it.ty(db).to_type(db)),
|
||||
Definition::Const(it) => salsa::attach(db, || it.ty(db)),
|
||||
Definition::Static(it) => salsa::attach(db, || it.ty(db)),
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user