Add DynTyExt::principal_id

This commit is contained in:
Lukas Wirth 2024-12-28 15:08:26 +01:00
parent c800485555
commit 17b3662755
4 changed files with 24 additions and 12 deletions

View file

@ -443,13 +443,25 @@ impl ProjectionTyExt for ProjectionTy {
}
pub trait DynTyExt {
fn principal(&self) -> Option<&TraitRef>;
fn principal(&self) -> Option<Binders<Binders<&TraitRef>>>;
fn principal_id(&self) -> Option<chalk_ir::TraitId<Interner>>;
}
impl DynTyExt for DynTy {
fn principal(&self) -> Option<&TraitRef> {
fn principal(&self) -> Option<Binders<Binders<&TraitRef>>> {
self.bounds.as_ref().filter_map(|bounds| {
bounds.interned().first().and_then(|b| {
b.as_ref().filter_map(|b| match b {
crate::WhereClause::Implemented(trait_ref) => Some(trait_ref),
_ => None,
})
})
})
}
fn principal_id(&self) -> Option<chalk_ir::TraitId<Interner>> {
self.bounds.skip_binders().interned().first().and_then(|b| match b.skip_binders() {
crate::WhereClause::Implemented(trait_ref) => Some(trait_ref),
crate::WhereClause::Implemented(trait_ref) => Some(trait_ref.trait_id),
_ => None,
})
}

View file

@ -96,8 +96,8 @@ impl InferenceContext<'_> {
.map(|b| b.into_value_and_skipped_binders().0);
self.deduce_closure_kind_from_predicate_clauses(clauses)
}
TyKind::Dyn(dyn_ty) => dyn_ty.principal().and_then(|trait_ref| {
self.fn_trait_kind_from_trait_id(from_chalk_trait_id(trait_ref.trait_id))
TyKind::Dyn(dyn_ty) => dyn_ty.principal_id().and_then(|trait_id| {
self.fn_trait_kind_from_trait_id(from_chalk_trait_id(trait_id))
}),
TyKind::InferenceVar(ty, chalk_ir::TyVariableKind::General) => {
let clauses = self.clauses_for_self_ty(*ty);

View file

@ -13,6 +13,7 @@ pub fn is_box(db: &dyn HirDatabase, adt: AdtId) -> bool {
pub fn is_unsafe_cell(db: &dyn HirDatabase, adt: AdtId) -> bool {
let AdtId::StructId(id) = adt else { return false };
db.struct_data(id).flags.contains(StructFlags::IS_UNSAFE_CELL)
}

View file

@ -805,8 +805,8 @@ fn is_inherent_impl_coherent(
| TyKind::Scalar(_) => def_map.is_rustc_coherence_is_core(),
&TyKind::Adt(AdtId(adt), _) => adt.module(db.upcast()).krate() == def_map.krate(),
TyKind::Dyn(it) => it.principal().map_or(false, |trait_ref| {
from_chalk_trait_id(trait_ref.trait_id).module(db.upcast()).krate() == def_map.krate()
TyKind::Dyn(it) => it.principal_id().map_or(false, |trait_id| {
from_chalk_trait_id(trait_id).module(db.upcast()).krate() == def_map.krate()
}),
_ => true,
@ -834,9 +834,8 @@ fn is_inherent_impl_coherent(
.contains(StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL),
hir_def::AdtId::EnumId(it) => db.enum_data(it).rustc_has_incoherent_inherent_impls,
},
TyKind::Dyn(it) => it.principal().map_or(false, |trait_ref| {
db.trait_data(from_chalk_trait_id(trait_ref.trait_id))
.rustc_has_incoherent_inherent_impls
TyKind::Dyn(it) => it.principal_id().map_or(false, |trait_id| {
db.trait_data(from_chalk_trait_id(trait_id)).rustc_has_incoherent_inherent_impls
}),
_ => false,
@ -896,8 +895,8 @@ pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool {
match unwrap_fundamental(ty).kind(Interner) {
&TyKind::Adt(AdtId(id), _) => is_local(id.module(db.upcast()).krate()),
TyKind::Error => true,
TyKind::Dyn(it) => it.principal().map_or(false, |trait_ref| {
is_local(from_chalk_trait_id(trait_ref.trait_id).module(db.upcast()).krate())
TyKind::Dyn(it) => it.principal_id().map_or(false, |trait_id| {
is_local(from_chalk_trait_id(trait_id).module(db.upcast()).krate())
}),
_ => false,
}