Merge #8396
8396: Uncouple Ty::builtin_deref and Ty::def_crates from Ty r=Veykril a=Veykril bors r+ CC #8313 Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
45510ae23d
@ -53,7 +53,7 @@
|
|||||||
use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind};
|
use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind};
|
||||||
use hir_ty::{
|
use hir_ty::{
|
||||||
autoderef, could_unify,
|
autoderef, could_unify,
|
||||||
method_resolution::{self, TyFingerprint},
|
method_resolution::{self, def_crates, TyFingerprint},
|
||||||
primitive::UintTy,
|
primitive::UintTy,
|
||||||
subst_prefix,
|
subst_prefix,
|
||||||
traits::FnTrait,
|
traits::FnTrait,
|
||||||
@ -1568,7 +1568,7 @@ pub fn all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<Impl> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> {
|
pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> {
|
||||||
let def_crates = match ty.def_crates(db, krate) {
|
let def_crates = match def_crates(db, &ty, krate) {
|
||||||
Some(def_crates) => def_crates,
|
Some(def_crates) => def_crates,
|
||||||
None => return Vec::new(),
|
None => return Vec::new(),
|
||||||
};
|
};
|
||||||
@ -1955,7 +1955,7 @@ pub fn iterate_assoc_items<T>(
|
|||||||
krate: Crate,
|
krate: Crate,
|
||||||
mut callback: impl FnMut(AssocItem) -> Option<T>,
|
mut callback: impl FnMut(AssocItem) -> Option<T>,
|
||||||
) -> Option<T> {
|
) -> Option<T> {
|
||||||
for krate in self.ty.def_crates(db, krate.id)? {
|
for krate in def_crates(db, &self.ty, krate.id)? {
|
||||||
let impls = db.inherent_impls_in_crate(krate);
|
let impls = db.inherent_impls_in_crate(krate);
|
||||||
|
|
||||||
for impl_def in impls.for_self_ty(&self.ty) {
|
for impl_def in impls.for_self_ty(&self.ty) {
|
||||||
|
@ -35,13 +35,21 @@ pub(crate) fn deref(
|
|||||||
krate: CrateId,
|
krate: CrateId,
|
||||||
ty: InEnvironment<&Canonical<Ty>>,
|
ty: InEnvironment<&Canonical<Ty>>,
|
||||||
) -> Option<Canonical<Ty>> {
|
) -> Option<Canonical<Ty>> {
|
||||||
if let Some(derefed) = ty.goal.value.builtin_deref() {
|
if let Some(derefed) = builtin_deref(&ty.goal.value) {
|
||||||
Some(Canonical { value: derefed, binders: ty.goal.binders.clone() })
|
Some(Canonical { value: derefed, binders: ty.goal.binders.clone() })
|
||||||
} else {
|
} else {
|
||||||
deref_by_trait(db, krate, ty)
|
deref_by_trait(db, krate, ty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn builtin_deref(ty: &Ty) -> Option<Ty> {
|
||||||
|
match ty.kind(&Interner) {
|
||||||
|
TyKind::Ref(.., ty) => Some(ty.clone()),
|
||||||
|
TyKind::Raw(.., ty) => Some(ty.clone()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn deref_by_trait(
|
fn deref_by_trait(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
krate: CrateId,
|
krate: CrateId,
|
||||||
|
@ -199,14 +199,6 @@ pub fn equals_ctor(&self, other: &Ty) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn builtin_deref(&self) -> Option<Ty> {
|
|
||||||
match self.kind(&Interner) {
|
|
||||||
TyKind::Ref(.., ty) => Some(ty.clone()),
|
|
||||||
TyKind::Raw(.., ty) => Some(ty.clone()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the type parameters of this type if it has some (i.e. is an ADT
|
/// Returns the type parameters of this type if it has some (i.e. is an ADT
|
||||||
/// or function); so if `self` is `Option<u32>`, this returns the `u32`.
|
/// or function); so if `self` is `Option<u32>`, this returns the `u32`.
|
||||||
pub fn substs(&self) -> Option<&Substitution> {
|
pub fn substs(&self) -> Option<&Substitution> {
|
||||||
|
@ -239,15 +239,14 @@ pub fn all_impls(&self) -> impl Iterator<Item = ImplId> + '_ {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ty {
|
pub fn def_crates(
|
||||||
pub fn def_crates(
|
db: &dyn HirDatabase,
|
||||||
&self,
|
ty: &Ty,
|
||||||
db: &dyn HirDatabase,
|
cur_crate: CrateId,
|
||||||
cur_crate: CrateId,
|
) -> Option<ArrayVec<CrateId, 2>> {
|
||||||
) -> Option<ArrayVec<CrateId, 2>> {
|
// Types like slice can have inherent impls in several crates, (core and alloc).
|
||||||
// Types like slice can have inherent impls in several crates, (core and alloc).
|
// The corresponding impls are marked with lang items, so we can use them to find the required crates.
|
||||||
// The corresponding impls are marked with lang items, so we can use them to find the required crates.
|
macro_rules! lang_item_crate {
|
||||||
macro_rules! lang_item_crate {
|
|
||||||
($($name:expr),+ $(,)?) => {{
|
($($name:expr),+ $(,)?) => {{
|
||||||
let mut v = ArrayVec::<LangItemTarget, 2>::new();
|
let mut v = ArrayVec::<LangItemTarget, 2>::new();
|
||||||
$(
|
$(
|
||||||
@ -257,51 +256,50 @@ macro_rules! lang_item_crate {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
|
let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
|
||||||
|
|
||||||
let lang_item_targets = match self.kind(&Interner) {
|
let lang_item_targets = match ty.kind(&Interner) {
|
||||||
TyKind::Adt(AdtId(def_id), _) => {
|
TyKind::Adt(AdtId(def_id), _) => {
|
||||||
return mod_to_crate_ids(def_id.module(db.upcast()));
|
return mod_to_crate_ids(def_id.module(db.upcast()));
|
||||||
}
|
}
|
||||||
TyKind::Foreign(id) => {
|
TyKind::Foreign(id) => {
|
||||||
return mod_to_crate_ids(
|
return mod_to_crate_ids(
|
||||||
from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()),
|
from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
|
TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
|
||||||
TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"),
|
TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"),
|
||||||
TyKind::Scalar(Scalar::Float(f)) => match f {
|
TyKind::Scalar(Scalar::Float(f)) => match f {
|
||||||
// There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
|
// There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
|
||||||
FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
|
FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
|
||||||
FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
|
FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
|
||||||
},
|
},
|
||||||
&TyKind::Scalar(Scalar::Int(t)) => {
|
&TyKind::Scalar(Scalar::Int(t)) => {
|
||||||
lang_item_crate!(primitive::int_ty_to_string(t))
|
lang_item_crate!(primitive::int_ty_to_string(t))
|
||||||
}
|
}
|
||||||
&TyKind::Scalar(Scalar::Uint(t)) => {
|
&TyKind::Scalar(Scalar::Uint(t)) => {
|
||||||
lang_item_crate!(primitive::uint_ty_to_string(t))
|
lang_item_crate!(primitive::uint_ty_to_string(t))
|
||||||
}
|
}
|
||||||
TyKind::Str => lang_item_crate!("str_alloc", "str"),
|
TyKind::Str => lang_item_crate!("str_alloc", "str"),
|
||||||
TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"),
|
TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"),
|
||||||
TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"),
|
TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"),
|
||||||
TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
|
TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
|
||||||
TyKind::Dyn(_) => {
|
TyKind::Dyn(_) => {
|
||||||
return self.dyn_trait().and_then(|trait_| {
|
return ty.dyn_trait().and_then(|trait_| {
|
||||||
mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
|
mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
let res = lang_item_targets
|
let res = lang_item_targets
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|it| match it {
|
.filter_map(|it| match it {
|
||||||
LangItemTarget::ImplDefId(it) => Some(it),
|
LangItemTarget::ImplDefId(it) => Some(it),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.map(|it| it.lookup(db.upcast()).container.krate())
|
.map(|it| it.lookup(db.upcast()).container.krate())
|
||||||
.collect();
|
.collect();
|
||||||
Some(res)
|
Some(res)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Look up the method with the given name, returning the actual autoderefed
|
/// Look up the method with the given name, returning the actual autoderefed
|
||||||
@ -628,7 +626,7 @@ fn iterate_inherent_methods(
|
|||||||
visible_from_module: Option<ModuleId>,
|
visible_from_module: Option<ModuleId>,
|
||||||
callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
|
callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let def_crates = match self_ty.value.def_crates(db, krate) {
|
let def_crates = match def_crates(db, &self_ty.value, krate) {
|
||||||
Some(k) => k,
|
Some(k) => k,
|
||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user