Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/next_solver/solver.rs')
-rw-r--r--crates/hir-ty/src/next_solver/solver.rs125
1 files changed, 72 insertions, 53 deletions
diff --git a/crates/hir-ty/src/next_solver/solver.rs b/crates/hir-ty/src/next_solver/solver.rs
index d45ac6c959..b1b3a0e0dc 100644
--- a/crates/hir-ty/src/next_solver/solver.rs
+++ b/crates/hir-ty/src/next_solver/solver.rs
@@ -1,30 +1,32 @@
//! Defining `SolverContext` for next-trait-solver.
use hir_def::{
- AssocItemId, GeneralConstId,
+ AssocItemId,
signatures::{ConstSignature, TypeAliasSignature},
};
use rustc_next_trait_solver::delegate::SolverDelegate;
use rustc_type_ir::{
- AliasTyKind, GenericArgKind, InferCtxtLike, Interner, PredicatePolarity, TypeFlags,
+ AliasTyKind, GenericArgKind, InferCtxtLike, InferTy, Interner, PredicatePolarity, TypeFlags,
TypeVisitableExt,
inherent::{IntoKind, Term as _, Ty as _},
lang_items::SolverTraitLangItem,
- solve::{Certainty, NoSolution},
+ solve::{Certainty, FetchEligibleAssocItemResponse, NoSolution, VisibleForLeakCheck},
};
use tracing::debug;
use crate::{
- ParamEnvAndCrate,
+ ParamEnvAndCrate, Span,
+ db::GeneralConstId,
next_solver::{
- AliasTy, AnyImplId, CanonicalVarKind, Clause, ClauseKind, CoercePredicate, GenericArgs,
- ParamEnv, Predicate, PredicateKind, SubtypePredicate, Ty, TyKind, UnevaluatedConst,
- fold::fold_tys, util::sizedness_fast_path,
+ AliasTy, AnyImplId, CanonicalVarKind, Clause, ClauseKind, CoercePredicate, ErrorGuaranteed,
+ GenericArgs, ImplOrTraitAssocTermId, OpaqueTyIdWrapper, ParamEnv, Predicate, PredicateKind,
+ RegionConstraint, SubtypePredicate, TermId, TraitAssocTermId, Ty, TyKind, TypingMode,
+ UnevaluatedConst, fold::fold_tys, util::sizedness_fast_path,
},
};
use super::{
- Const, DbInterner, ErrorGuaranteed, GenericArg, SolverDefId, Span,
+ Const, DbInterner, GenericArg,
infer::{DbInternerInferExt, InferCtxt, canonical::instantiate::CanonicalExt},
};
@@ -63,15 +65,15 @@ impl<'db> SolverDelegate for SolverContext<'db> {
where
V: rustc_type_ir::TypeFoldable<Self::Interner>,
{
- let (infcx, value, vars) = cx.infer_ctxt().build_with_canonical(canonical);
+ let (infcx, value, vars) = cx.infer_ctxt().build_with_canonical(Span::Dummy, canonical);
(SolverContext(infcx), value, vars)
}
- fn fresh_var_for_kind_with_span(&self, arg: GenericArg<'db>, _span: Span) -> GenericArg<'db> {
+ fn fresh_var_for_kind_with_span(&self, arg: GenericArg<'db>, span: Span) -> GenericArg<'db> {
match arg.kind() {
- GenericArgKind::Lifetime(_) => self.next_region_var().into(),
- GenericArgKind::Type(_) => self.next_ty_var().into(),
- GenericArgKind::Const(_) => self.next_const_var().into(),
+ GenericArgKind::Lifetime(_) => self.next_region_var(span).into(),
+ GenericArgKind::Type(_) => self.next_ty_var(span).into(),
+ GenericArgKind::Const(_) => self.next_const_var(span).into(),
}
}
@@ -98,14 +100,9 @@ impl<'db> SolverDelegate for SolverContext<'db> {
None
}
- fn make_deduplicated_outlives_constraints(
+ fn make_deduplicated_region_constraints(
&self,
- ) -> Vec<
- rustc_type_ir::OutlivesPredicate<
- Self::Interner,
- <Self::Interner as rustc_type_ir::Interner>::GenericArg,
- >,
- > {
+ ) -> Vec<(RegionConstraint<'db>, VisibleForLeakCheck)> {
// FIXME: add if we care about regions
vec![]
}
@@ -124,23 +121,22 @@ impl<'db> SolverDelegate for SolverContext<'db> {
fn instantiate_canonical_var(
&self,
kind: CanonicalVarKind<'db>,
- _span: <Self::Interner as Interner>::Span,
+ span: Span,
var_values: &[GenericArg<'db>],
universe_map: impl Fn(rustc_type_ir::UniverseIndex) -> rustc_type_ir::UniverseIndex,
) -> GenericArg<'db> {
- self.0.instantiate_canonical_var(kind, var_values, universe_map)
+ self.0.instantiate_canonical_var(span, kind, var_values, universe_map)
}
fn add_item_bounds_for_hidden_type(
&self,
- def_id: SolverDefId,
+ opaque_id: OpaqueTyIdWrapper,
args: GenericArgs<'db>,
param_env: ParamEnv<'db>,
hidden_ty: Ty<'db>,
goals: &mut Vec<Goal<'db, Predicate<'db>>>,
) {
let interner = self.interner;
- let opaque_id = def_id.expect_opaque_ty();
// Require that the hidden type is well-formed. We have to
// make sure we wf-check the hidden type to fix #114728.
//
@@ -162,14 +158,14 @@ impl<'db> SolverDelegate for SolverContext<'db> {
kind: AliasTyKind::Opaque { def_id: def_id2 },
args: args2,
..
- }) if def_id == def_id2 && args == args2 => hidden_ty,
+ }) if opaque_id == def_id2 && args == args2 => hidden_ty,
_ => ty,
})
};
- let item_bounds = opaque_id.predicates(interner.db);
+ let item_bounds = opaque_id.0.predicates(interner.db);
for predicate in item_bounds.iter_instantiated_copied(interner, args.as_slice()) {
- let predicate = replace_opaques_in(predicate);
+ let predicate = replace_opaques_in(predicate.skip_norm_wip());
// Require that the predicate holds for the concrete type.
debug!(?predicate);
@@ -180,16 +176,16 @@ impl<'db> SolverDelegate for SolverContext<'db> {
fn fetch_eligible_assoc_item(
&self,
_goal_trait_ref: rustc_type_ir::TraitRef<Self::Interner>,
- trait_assoc_def_id: SolverDefId,
+ trait_assoc_def_id: TraitAssocTermId,
impl_id: AnyImplId,
- ) -> Result<Option<SolverDefId>, ErrorGuaranteed> {
+ ) -> FetchEligibleAssocItemResponse<Self::Interner> {
let AnyImplId::ImplId(impl_id) = impl_id else {
// Builtin derive traits don't have type/consts assoc items.
- return Ok(None);
+ return FetchEligibleAssocItemResponse::Err(ErrorGuaranteed);
};
let impl_items = impl_id.impl_items(self.0.interner.db());
- let id = match trait_assoc_def_id {
- SolverDefId::TypeAliasId(trait_assoc_id) => {
+ let id = match trait_assoc_def_id.0 {
+ TermId::TypeAliasId(trait_assoc_id) => {
let trait_assoc_data = TypeAliasSignature::of(self.0.interner.db, trait_assoc_id);
impl_items
.items
@@ -206,9 +202,9 @@ impl<'db> SolverDelegate for SolverContext<'db> {
.or_else(|| {
if trait_assoc_data.ty.is_some() { Some(trait_assoc_id) } else { None }
})
- .map(SolverDefId::TypeAliasId)
+ .map(|def| ImplOrTraitAssocTermId(TermId::TypeAliasId(def)))
}
- SolverDefId::ConstId(trait_assoc_id) => {
+ TermId::ConstId(trait_assoc_id) => {
let trait_assoc_data = ConstSignature::of(self.0.interner.db, trait_assoc_id);
let trait_assoc_name = trait_assoc_data
.name
@@ -231,11 +227,20 @@ impl<'db> SolverDelegate for SolverContext<'db> {
if trait_assoc_data.has_body() { Some(trait_assoc_id) } else { None }
},
)
- .map(SolverDefId::ConstId)
+ .map(|def| ImplOrTraitAssocTermId(TermId::ConstId(def)))
}
- _ => panic!("Unexpected SolverDefId"),
};
- Ok(id)
+ match id {
+ Some(id) => FetchEligibleAssocItemResponse::Found(id),
+ None => match self.typing_mode_raw() {
+ TypingMode::ErasedNotCoherence(_) => {
+ FetchEligibleAssocItemResponse::NotFoundBecauseErased
+ }
+ typing_mode => {
+ FetchEligibleAssocItemResponse::NotFound(typing_mode.assert_not_erased())
+ }
+ },
+ }
}
fn is_transmutable(
@@ -260,11 +265,10 @@ impl<'db> SolverDelegate for SolverContext<'db> {
self.cx().db.const_eval(c, subst, None).ok()?
}
GeneralConstId::StaticId(c) => self.cx().db.const_eval_static(c).ok()?,
- // TODO: Wire up const_eval_anon query in Phase 5.
- // For now, return an error const so normalization resolves the
- // unevaluated const to Error (matching the old behavior where
- // complex expressions produced ConstKind::Error directly).
- GeneralConstId::AnonConstId(_) => return Some(Const::error(self.cx())),
+ GeneralConstId::AnonConstId(c) => {
+ let subst = uv.args;
+ self.cx().db.anon_const_eval(c, subst, None).ok()?
+ }
};
Some(Const::new_from_allocation(
self.interner,
@@ -293,10 +297,10 @@ impl<'db> SolverDelegate for SolverContext<'db> {
}
if trait_pred.polarity() == PredicatePolarity::Positive {
- match self.0.cx().as_trait_lang_item(trait_pred.def_id()) {
+ match self.0.interner.as_trait_lang_item(trait_pred.def_id()) {
Some(SolverTraitLangItem::Sized) | Some(SolverTraitLangItem::MetaSized) => {
let predicate = self.resolve_vars_if_possible(goal.predicate);
- if sizedness_fast_path(self.cx(), predicate, goal.param_env) {
+ if sizedness_fast_path(self.interner, predicate, goal.param_env) {
return Some(Certainty::Yes);
}
}
@@ -322,17 +326,31 @@ impl<'db> SolverDelegate for SolverContext<'db> {
let pred = goal.predicate.kind();
match pred.no_bound_vars()? {
- PredicateKind::Clause(ClauseKind::RegionOutlives(_outlives)) => Some(Certainty::Yes),
- PredicateKind::Clause(ClauseKind::TypeOutlives(_outlives)) => Some(Certainty::Yes),
+ PredicateKind::DynCompatible(def_id)
+ if self.0.interner.trait_is_dyn_compatible(def_id) =>
+ {
+ Some(Certainty::Yes)
+ }
+ PredicateKind::Clause(ClauseKind::RegionOutlives(outlives)) => {
+ self.0.sub_regions(outlives.1, outlives.0);
+ Some(Certainty::Yes)
+ }
+ PredicateKind::Clause(ClauseKind::TypeOutlives(outlives)) => {
+ self.0.register_type_outlives_constraint(outlives.0, outlives.1);
+
+ Some(Certainty::Yes)
+ }
PredicateKind::Subtype(SubtypePredicate { a, b, .. })
| PredicateKind::Coerce(CoercePredicate { a, b }) => {
- if self.shallow_resolve(a).is_ty_var() && self.shallow_resolve(b).is_ty_var() {
- // FIXME: We also need to register a subtype relation between these vars
- // when those are added, and if they aren't in the same sub root then
- // we should mark this goal as `has_changed`.
- Some(Certainty::AMBIGUOUS)
- } else {
- None
+ match (self.shallow_resolve(a).kind(), self.shallow_resolve(b).kind()) {
+ (
+ TyKind::Infer(InferTy::TyVar(a_vid)),
+ TyKind::Infer(InferTy::TyVar(b_vid)),
+ ) => {
+ self.sub_unify_ty_vids_raw(a_vid, b_vid);
+ Some(Certainty::AMBIGUOUS)
+ }
+ _ => None,
}
}
PredicateKind::Clause(ClauseKind::ConstArgHasType(ct, _)) => {
@@ -343,6 +361,7 @@ impl<'db> SolverDelegate for SolverContext<'db> {
}
}
PredicateKind::Clause(ClauseKind::WellFormed(arg)) => {
+ let arg = self.shallow_resolve_term(arg);
if arg.is_trivially_wf(self.interner) {
Some(Certainty::Yes)
} else if arg.is_infer() {