Convert some of dyn_compatibility to next-solver and remove generic_predicates_without_parent_query
diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs
index 6e24aea..7a5daac 100644
--- a/crates/hir-ty/src/db.rs
+++ b/crates/hir-ty/src/db.rs
@@ -179,16 +179,6 @@
#[salsa::invoke(crate::lower::generic_predicates_query)]
fn generic_predicates(&self, def: GenericDefId) -> GenericPredicates;
- #[salsa::invoke(crate::lower::generic_predicates_without_parent_with_diagnostics_query)]
- fn generic_predicates_without_parent_with_diagnostics(
- &self,
- def: GenericDefId,
- ) -> (GenericPredicates, Diagnostics);
-
- #[salsa::invoke(crate::lower::generic_predicates_without_parent_query)]
- #[salsa::transparent]
- fn generic_predicates_without_parent(&self, def: GenericDefId) -> GenericPredicates;
-
#[salsa::invoke(crate::lower::trait_environment_for_body_query)]
#[salsa::transparent]
fn trait_environment_for_body(&self, def: DefWithBodyId) -> Arc<TraitEnvironment>;
diff --git a/crates/hir-ty/src/dyn_compatibility.rs b/crates/hir-ty/src/dyn_compatibility.rs
index 2d21947..f571b64 100644
--- a/crates/hir-ty/src/dyn_compatibility.rs
+++ b/crates/hir-ty/src/dyn_compatibility.rs
@@ -13,6 +13,9 @@
TypeAliasId, lang_item::LangItem, signatures::TraitFlags,
};
use rustc_hash::FxHashSet;
+use rustc_type_ir::{
+ AliasTyKind, ClauseKind, PredicatePolarity, TypeSuperVisitable as _, inherent::IntoKind,
+};
use smallvec::SmallVec;
use crate::{
@@ -21,6 +24,7 @@
db::HirDatabase,
from_assoc_type_id, from_chalk_trait_id,
generics::{generics, trait_self_param_idx},
+ next_solver::{DbInterner, SolverDefId, TraitPredicate},
to_chalk_trait_id,
utils::elaborate_clause_supertraits,
};
@@ -319,6 +323,61 @@
t.visit_with(visitor.as_dyn(), outer_binder).is_break()
}
+fn contains_illegal_self_type_reference_ns<
+ 'db,
+ T: rustc_type_ir::TypeVisitable<DbInterner<'db>>,
+>(
+ db: &'db dyn HirDatabase,
+ trait_: TraitId,
+ t: &T,
+ allow_self_projection: AllowSelfProjection,
+) -> bool {
+ struct IllegalSelfTypeVisitor<'db> {
+ db: &'db dyn HirDatabase,
+ trait_: TraitId,
+ super_traits: Option<SmallVec<[TraitId; 4]>>,
+ allow_self_projection: AllowSelfProjection,
+ }
+ impl<'db> rustc_type_ir::TypeVisitor<DbInterner<'db>> for IllegalSelfTypeVisitor<'db> {
+ type Result = ControlFlow<()>;
+
+ fn visit_ty(
+ &mut self,
+ ty: <DbInterner<'db> as rustc_type_ir::Interner>::Ty,
+ ) -> Self::Result {
+ match ty.kind() {
+ rustc_type_ir::TyKind::Param(param) if param.index == 0 => ControlFlow::Break(()),
+ rustc_type_ir::TyKind::Param(_) => ControlFlow::Continue(()),
+ rustc_type_ir::TyKind::Alias(AliasTyKind::Projection, proj) => match self
+ .allow_self_projection
+ {
+ AllowSelfProjection::Yes => {
+ let trait_ = proj.trait_def_id(DbInterner::new_with(self.db, None, None));
+ let trait_ = match trait_ {
+ SolverDefId::TraitId(id) => id,
+ _ => unreachable!(),
+ };
+ if self.super_traits.is_none() {
+ self.super_traits = Some(all_super_traits(self.db, self.trait_));
+ }
+ if self.super_traits.as_ref().is_some_and(|s| s.contains(&trait_)) {
+ ControlFlow::Continue(())
+ } else {
+ ty.super_visit_with(self)
+ }
+ }
+ AllowSelfProjection::No => ty.super_visit_with(self),
+ },
+ _ => ty.super_visit_with(self),
+ }
+ }
+ }
+
+ let mut visitor =
+ IllegalSelfTypeVisitor { db, trait_, super_traits: None, allow_self_projection };
+ t.visit_with(&mut visitor).is_break()
+}
+
fn dyn_compatibility_violation_for_assoc_item<F>(
db: &dyn HirDatabase,
trait_: TraitId,
@@ -415,40 +474,33 @@
cb(MethodViolationCode::UndispatchableReceiver)?;
}
- let predicates = &*db.generic_predicates_without_parent(func.into());
- let trait_self_idx = trait_self_param_idx(db, func.into());
+ let predicates = &*db.generic_predicates_without_parent_ns(func.into());
for pred in predicates {
- let pred = pred.skip_binders().skip_binders();
+ let pred = pred.kind().skip_binder();
- if matches!(pred, WhereClause::TypeOutlives(_)) {
+ if matches!(pred, ClauseKind::TypeOutlives(_)) {
continue;
}
// Allow `impl AutoTrait` predicates
- if let WhereClause::Implemented(TraitRef { trait_id, substitution }) = pred {
- let trait_data = db.trait_signature(from_chalk_trait_id(*trait_id));
- if trait_data.flags.contains(TraitFlags::AUTO)
- && substitution
- .as_slice(Interner)
- .first()
- .and_then(|arg| arg.ty(Interner))
- .and_then(|ty| ty.bound_var(Interner))
- .is_some_and(|b| {
- b.debruijn == DebruijnIndex::ONE && Some(b.index) == trait_self_idx
- })
- {
- continue;
- }
+ let interner = DbInterner::new_with(db, None, None);
+ if let ClauseKind::Trait(TraitPredicate {
+ trait_ref: pred_trait_ref,
+ polarity: PredicatePolarity::Positive,
+ }) = pred
+ && let SolverDefId::TraitId(trait_id) = pred_trait_ref.def_id
+ && let trait_data = db.trait_signature(trait_id)
+ && trait_data.flags.contains(TraitFlags::AUTO)
+ && pred_trait_ref.self_ty()
+ == crate::next_solver::Ty::new(
+ interner,
+ rustc_type_ir::TyKind::Param(crate::next_solver::ParamTy { index: 0 }),
+ )
+ {
+ continue;
}
- if contains_illegal_self_type_reference(
- db,
- func.into(),
- trait_,
- pred,
- DebruijnIndex::ONE,
- AllowSelfProjection::Yes,
- ) {
+ if contains_illegal_self_type_reference_ns(db, trait_, &pred, AllowSelfProjection::Yes) {
cb(MethodViolationCode::WhereClauseReferencesSelf)?;
break;
}
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 7b6b3c3..065d2ea 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -1179,22 +1179,6 @@
generic_predicates_filtered_by(db, def, |_, _| true).0
}
-pub(crate) fn generic_predicates_without_parent_query(
- db: &dyn HirDatabase,
- def: GenericDefId,
-) -> GenericPredicates {
- db.generic_predicates_without_parent_with_diagnostics(def).0
-}
-
-/// Resolve the where clause(s) of an item with generics,
-/// except the ones inherited from the parent
-pub(crate) fn generic_predicates_without_parent_with_diagnostics_query(
- db: &dyn HirDatabase,
- def: GenericDefId,
-) -> (GenericPredicates, Diagnostics) {
- generic_predicates_filtered_by(db, def, |_, d| d == def)
-}
-
/// Resolve the where clause(s) of an item with generics,
/// with a given filter
fn generic_predicates_filtered_by<F>(
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 4eb50c1..11486ec 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -3750,7 +3750,7 @@
push_ty_diagnostics(
db,
acc,
- db.generic_predicates_without_parent_with_diagnostics(def).1,
+ db.generic_predicates_without_parent_with_diagnostics_ns(def).1,
&source_map,
);
for (param_id, param) in generics.iter_type_or_consts() {