Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/traits.rs')
-rw-r--r--crates/hir-ty/src/traits.rs112
1 files changed, 12 insertions, 100 deletions
diff --git a/crates/hir-ty/src/traits.rs b/crates/hir-ty/src/traits.rs
index 878696c721..ad1c3fb709 100644
--- a/crates/hir-ty/src/traits.rs
+++ b/crates/hir-ty/src/traits.rs
@@ -15,18 +15,16 @@ use hir_def::{
};
use hir_expand::name::Name;
use intern::sym;
-use rustc_next_trait_solver::solve::{HasChanged, SolverDelegateEvalExt};
use rustc_type_ir::{
TypingMode,
- inherent::{AdtDef, BoundExistentialPredicates, IntoKind, Span as _},
- solve::Certainty,
+ inherent::{BoundExistentialPredicates, IntoKind},
};
use crate::{
+ Span,
db::HirDatabase,
next_solver::{
- Canonical, DbInterner, GenericArgs, Goal, ParamEnv, Predicate, SolverContext, Span,
- StoredClauses, Ty, TyKind,
+ DbInterner, GenericArgs, ParamEnv, StoredClauses, Ty, TyKind,
infer::{
DbInternerInferExt, InferCtxt,
traits::{Obligation, ObligationCause},
@@ -79,91 +77,6 @@ pub fn structurally_normalize_ty<'db>(
ty.replace_infer_with_error(infcx.interner)
}
-#[derive(Clone, Debug, PartialEq)]
-pub enum NextTraitSolveResult {
- Certain,
- Uncertain,
- NoSolution,
-}
-
-impl NextTraitSolveResult {
- pub fn no_solution(&self) -> bool {
- matches!(self, NextTraitSolveResult::NoSolution)
- }
-
- pub fn certain(&self) -> bool {
- matches!(self, NextTraitSolveResult::Certain)
- }
-
- pub fn uncertain(&self) -> bool {
- matches!(self, NextTraitSolveResult::Uncertain)
- }
-}
-
-pub fn next_trait_solve_canonical_in_ctxt<'db>(
- infer_ctxt: &InferCtxt<'db>,
- goal: Canonical<'db, Goal<'db, Predicate<'db>>>,
-) -> NextTraitSolveResult {
- infer_ctxt.probe(|_| {
- let context = <&SolverContext<'db>>::from(infer_ctxt);
-
- tracing::info!(?goal);
-
- let (goal, var_values) = context.instantiate_canonical(&goal);
- tracing::info!(?var_values);
-
- let res = context.evaluate_root_goal(goal, Span::dummy(), None);
-
- let obligation = Obligation {
- cause: ObligationCause::dummy(),
- param_env: goal.param_env,
- recursion_depth: 0,
- predicate: goal.predicate,
- };
- infer_ctxt.inspect_evaluated_obligation(&obligation, &res, || {
- Some(context.evaluate_root_goal_for_proof_tree(goal, Span::dummy()).1)
- });
-
- let res = res.map(|r| (r.has_changed, r.certainty));
-
- tracing::debug!("solve_nextsolver({:?}) => {:?}", goal, res);
-
- match res {
- Err(_) => NextTraitSolveResult::NoSolution,
- Ok((_, Certainty::Yes)) => NextTraitSolveResult::Certain,
- Ok((_, Certainty::Maybe { .. })) => NextTraitSolveResult::Uncertain,
- }
- })
-}
-
-/// Solve a trait goal using next trait solver.
-pub fn next_trait_solve_in_ctxt<'db, 'a>(
- infer_ctxt: &'a InferCtxt<'db>,
- goal: Goal<'db, Predicate<'db>>,
-) -> Result<(HasChanged, Certainty), rustc_type_ir::solve::NoSolution> {
- tracing::info!(?goal);
-
- let context = <&SolverContext<'db>>::from(infer_ctxt);
-
- let res = context.evaluate_root_goal(goal, Span::dummy(), None);
-
- let obligation = Obligation {
- cause: ObligationCause::dummy(),
- param_env: goal.param_env,
- recursion_depth: 0,
- predicate: goal.predicate,
- };
- infer_ctxt.inspect_evaluated_obligation(&obligation, &res, || {
- Some(context.evaluate_root_goal_for_proof_tree(goal, Span::dummy()).1)
- });
-
- let res = res.map(|r| (r.has_changed, r.certainty));
-
- tracing::debug!("solve_nextsolver({:?}) => {:?}", goal, res);
-
- res
-}
-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, salsa::Update)]
pub enum FnTrait {
// Warning: Order is important. If something implements `x` it should also implement
@@ -209,7 +122,7 @@ pub fn implements_trait_unique<'db>(
trait_: TraitId,
) -> bool {
implements_trait_unique_impl(db, env, trait_, &mut |infcx| {
- infcx.fill_rest_fresh_args(trait_.into(), [ty.into()])
+ infcx.fill_rest_fresh_args(Span::Dummy, trait_.into(), [ty.into()])
})
}
@@ -235,14 +148,13 @@ fn implements_trait_unique_impl<'db>(
let args = create_args(&infcx);
let trait_ref = rustc_type_ir::TraitRef::new_from_args(interner, trait_.into(), args);
- let goal = Goal::new(interner, env.param_env, trait_ref);
- let result = crate::traits::next_trait_solve_in_ctxt(&infcx, goal);
- matches!(result, Ok((_, Certainty::Yes)))
+ let obligation = Obligation::new(interner, ObligationCause::dummy(), env.param_env, trait_ref);
+ infcx.predicate_must_hold_modulo_regions(&obligation)
}
pub fn is_inherent_impl_coherent(db: &dyn HirDatabase, def_map: &DefMap, impl_id: ImplId) -> bool {
- let self_ty = db.impl_self_ty(impl_id).instantiate_identity();
+ let self_ty = db.impl_self_ty(impl_id).instantiate_identity().skip_norm_wip();
let self_ty = self_ty.kind();
let impl_allowed = match self_ty {
TyKind::Tuple(_)
@@ -259,7 +171,7 @@ pub fn is_inherent_impl_coherent(db: &dyn HirDatabase, def_map: &DefMap, impl_id
| TyKind::Uint(_)
| TyKind::Float(_) => def_map.is_rustc_coherence_is_core(),
- TyKind::Adt(adt_def, _) => adt_def.def_id().0.module(db).krate(db) == def_map.krate(),
+ TyKind::Adt(adt_def, _) => adt_def.def_id().module(db).krate(db) == def_map.krate(),
TyKind::Dynamic(it, _) => it
.principal_def_id()
.is_some_and(|trait_id| trait_id.0.module(db).krate(db) == def_map.krate()),
@@ -282,7 +194,7 @@ pub fn is_inherent_impl_coherent(db: &dyn HirDatabase, def_map: &DefMap, impl_id
| TyKind::Uint(_)
| TyKind::Float(_) => true,
- TyKind::Adt(adt_def, _) => match adt_def.def_id().0 {
+ TyKind::Adt(adt_def, _) => match adt_def.def_id() {
hir_def::AdtId::StructId(id) => StructSignature::of(db, id)
.flags
.contains(StructFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
@@ -334,7 +246,7 @@ pub fn check_orphan_rules<'db>(db: &'db dyn HirDatabase, impl_: ImplId) -> bool
let local_crate = impl_.lookup(db).container.krate(db);
let is_local = |tgt_crate| tgt_crate == local_crate;
- let trait_ref = impl_trait.instantiate_identity();
+ let trait_ref = impl_trait.instantiate_identity().skip_norm_wip();
let trait_id = trait_ref.def_id.0;
if is_local(trait_id.module(db).krate(db)) {
// trait to be implemented is local
@@ -347,7 +259,7 @@ pub fn check_orphan_rules<'db>(db: &'db dyn HirDatabase, impl_: ImplId) -> bool
match ty.kind() {
TyKind::Ref(_, referenced, _) => ty = referenced,
TyKind::Adt(adt_def, subs) => {
- let AdtId::StructId(s) = adt_def.def_id().0 else {
+ let AdtId::StructId(s) = adt_def.def_id() else {
break ty;
};
let struct_signature = StructSignature::of(db, s);
@@ -370,7 +282,7 @@ pub fn check_orphan_rules<'db>(db: &'db dyn HirDatabase, impl_: ImplId) -> bool
// FIXME: param coverage
// - No uncovered type parameters `P1..=Pn` may appear in `T0..Ti`` (excluding `Ti`)
let is_not_orphan = trait_ref.args.types().any(|ty| match unwrap_fundamental(ty).kind() {
- TyKind::Adt(adt_def, _) => is_local(adt_def.def_id().0.module(db).krate(db)),
+ TyKind::Adt(adt_def, _) => is_local(adt_def.def_id().module(db).krate(db)),
TyKind::Error(_) => true,
TyKind::Dynamic(it, _) => {
it.principal_def_id().is_some_and(|trait_id| is_local(trait_id.0.module(db).krate(db)))