mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Convert some of dyn_compatibility to next-solver and remove generic_predicates_without_parent_query
This commit is contained in:
parent
484db3a517
commit
8228f6f9f7
@ -179,16 +179,6 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
|||||||
#[salsa::invoke(crate::lower::generic_predicates_query)]
|
#[salsa::invoke(crate::lower::generic_predicates_query)]
|
||||||
fn generic_predicates(&self, def: GenericDefId) -> GenericPredicates;
|
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::invoke(crate::lower::trait_environment_for_body_query)]
|
||||||
#[salsa::transparent]
|
#[salsa::transparent]
|
||||||
fn trait_environment_for_body(&self, def: DefWithBodyId) -> Arc<TraitEnvironment>;
|
fn trait_environment_for_body(&self, def: DefWithBodyId) -> Arc<TraitEnvironment>;
|
||||||
|
@ -13,6 +13,9 @@ use hir_def::{
|
|||||||
TypeAliasId, lang_item::LangItem, signatures::TraitFlags,
|
TypeAliasId, lang_item::LangItem, signatures::TraitFlags,
|
||||||
};
|
};
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
|
use rustc_type_ir::{
|
||||||
|
AliasTyKind, ClauseKind, PredicatePolarity, TypeSuperVisitable as _, inherent::IntoKind,
|
||||||
|
};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -21,6 +24,7 @@ use crate::{
|
|||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
from_assoc_type_id, from_chalk_trait_id,
|
from_assoc_type_id, from_chalk_trait_id,
|
||||||
generics::{generics, trait_self_param_idx},
|
generics::{generics, trait_self_param_idx},
|
||||||
|
next_solver::{DbInterner, SolverDefId, TraitPredicate},
|
||||||
to_chalk_trait_id,
|
to_chalk_trait_id,
|
||||||
utils::elaborate_clause_supertraits,
|
utils::elaborate_clause_supertraits,
|
||||||
};
|
};
|
||||||
@ -319,6 +323,61 @@ fn contains_illegal_self_type_reference<T: TypeVisitable<Interner>>(
|
|||||||
t.visit_with(visitor.as_dyn(), outer_binder).is_break()
|
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>(
|
fn dyn_compatibility_violation_for_assoc_item<F>(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
trait_: TraitId,
|
trait_: TraitId,
|
||||||
@ -415,40 +474,33 @@ where
|
|||||||
cb(MethodViolationCode::UndispatchableReceiver)?;
|
cb(MethodViolationCode::UndispatchableReceiver)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let predicates = &*db.generic_predicates_without_parent(func.into());
|
let predicates = &*db.generic_predicates_without_parent_ns(func.into());
|
||||||
let trait_self_idx = trait_self_param_idx(db, func.into());
|
|
||||||
for pred in predicates {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow `impl AutoTrait` predicates
|
// Allow `impl AutoTrait` predicates
|
||||||
if let WhereClause::Implemented(TraitRef { trait_id, substitution }) = pred {
|
let interner = DbInterner::new_with(db, None, None);
|
||||||
let trait_data = db.trait_signature(from_chalk_trait_id(*trait_id));
|
if let ClauseKind::Trait(TraitPredicate {
|
||||||
if trait_data.flags.contains(TraitFlags::AUTO)
|
trait_ref: pred_trait_ref,
|
||||||
&& substitution
|
polarity: PredicatePolarity::Positive,
|
||||||
.as_slice(Interner)
|
}) = pred
|
||||||
.first()
|
&& let SolverDefId::TraitId(trait_id) = pred_trait_ref.def_id
|
||||||
.and_then(|arg| arg.ty(Interner))
|
&& let trait_data = db.trait_signature(trait_id)
|
||||||
.and_then(|ty| ty.bound_var(Interner))
|
&& trait_data.flags.contains(TraitFlags::AUTO)
|
||||||
.is_some_and(|b| {
|
&& pred_trait_ref.self_ty()
|
||||||
b.debruijn == DebruijnIndex::ONE && Some(b.index) == trait_self_idx
|
== crate::next_solver::Ty::new(
|
||||||
})
|
interner,
|
||||||
{
|
rustc_type_ir::TyKind::Param(crate::next_solver::ParamTy { index: 0 }),
|
||||||
continue;
|
)
|
||||||
}
|
{
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if contains_illegal_self_type_reference(
|
if contains_illegal_self_type_reference_ns(db, trait_, &pred, AllowSelfProjection::Yes) {
|
||||||
db,
|
|
||||||
func.into(),
|
|
||||||
trait_,
|
|
||||||
pred,
|
|
||||||
DebruijnIndex::ONE,
|
|
||||||
AllowSelfProjection::Yes,
|
|
||||||
) {
|
|
||||||
cb(MethodViolationCode::WhereClauseReferencesSelf)?;
|
cb(MethodViolationCode::WhereClauseReferencesSelf)?;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1179,22 +1179,6 @@ pub(crate) fn generic_predicates_query(
|
|||||||
generic_predicates_filtered_by(db, def, |_, _| true).0
|
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,
|
/// Resolve the where clause(s) of an item with generics,
|
||||||
/// with a given filter
|
/// with a given filter
|
||||||
fn generic_predicates_filtered_by<F>(
|
fn generic_predicates_filtered_by<F>(
|
||||||
|
@ -3750,7 +3750,7 @@ impl GenericDef {
|
|||||||
push_ty_diagnostics(
|
push_ty_diagnostics(
|
||||||
db,
|
db,
|
||||||
acc,
|
acc,
|
||||||
db.generic_predicates_without_parent_with_diagnostics(def).1,
|
db.generic_predicates_without_parent_with_diagnostics_ns(def).1,
|
||||||
&source_map,
|
&source_map,
|
||||||
);
|
);
|
||||||
for (param_id, param) in generics.iter_type_or_consts() {
|
for (param_id, param) in generics.iter_type_or_consts() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user