Fix resolution of inherent array methods.

This commit is contained in:
Yotam Ofek 2021-09-08 11:13:29 +03:00
parent 1785493cae
commit 9593fe684d

View file

@ -16,6 +16,7 @@ use rustc_hash::{FxHashMap, FxHashSet};
use crate::{ use crate::{
autoderef, autoderef,
consteval::{self, ConstExt},
db::HirDatabase, db::HirDatabase,
from_foreign_def_id, from_foreign_def_id,
primitive::{self, FloatTy, IntTy, UintTy}, primitive::{self, FloatTy, IntTy, UintTy},
@ -725,7 +726,27 @@ fn iterate_inherent_methods(
for krate in def_crates { for krate in def_crates {
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.value) { let impls_for_self_ty = impls.for_self_ty(&self_ty.value).iter().chain(
{
if let TyKind::Array(parameters, array_len) = self_ty.value.kind(&Interner) {
if !array_len.is_unknown() {
let unknown_array_len_ty =
TyKind::Array(parameters.clone(), consteval::usize_const(None))
.intern(&Interner);
Some(impls.for_self_ty(&unknown_array_len_ty))
} else {
None
}
} else {
None
}
}
.into_iter()
.flatten(),
);
for &impl_def in impls_for_self_ty {
for &item in db.impl_data(impl_def).items.iter() { for &item in db.impl_data(impl_def).items.iter() {
if !is_valid_candidate( if !is_valid_candidate(
db, db,
@ -803,9 +824,22 @@ fn is_valid_candidate(
None => return false, None => return false,
}; };
if transformed_receiver_ty != receiver_ty.value { if transformed_receiver_ty != receiver_ty.value {
match (
transformed_receiver_ty.kind(&Interner),
receiver_ty.value.kind(&Interner),
) {
(
TyKind::Array(transformed_array_ty, transformed_array_len),
TyKind::Array(receiver_array_ty, receiver_array_len),
) if transformed_array_ty == receiver_array_ty
&& transformed_array_len.is_unknown()
&& !receiver_array_len.is_unknown() => {}
_ => {
return false; return false;
} }
} }
}
}
if let Some(from_module) = visible_from_module { if let Some(from_module) = visible_from_module {
if !db.function_visibility(m).is_visible_from(db.upcast(), from_module) { if !db.function_visibility(m).is_visible_from(db.upcast(), from_module) {
cov_mark::hit!(autoderef_candidate_not_visible); cov_mark::hit!(autoderef_candidate_not_visible);