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:
bors[bot] 2021-04-07 11:18:20 +00:00 committed by GitHub
commit 45510ae23d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 64 additions and 66 deletions

View File

@ -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) {

View File

@ -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,

View File

@ -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> {

View File

@ -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,
}; };