Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/method_resolution.rs')
-rw-r--r--crates/hir-ty/src/method_resolution.rs50
1 files changed, 33 insertions, 17 deletions
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index fad74c2448..8ba8071d36 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -5,7 +5,7 @@
use std::ops::ControlFlow;
use base_db::CrateId;
-use chalk_ir::{cast::Cast, Mutability, TyKind, UniverseIndex, WhereClause};
+use chalk_ir::{cast::Cast, UniverseIndex, WithKind};
use hir_def::{
data::{adt::StructFlags, ImplData},
nameres::DefMap,
@@ -13,9 +13,9 @@ use hir_def::{
ModuleId, TraitId,
};
use hir_expand::name::Name;
+use intern::sym;
use rustc_hash::{FxHashMap, FxHashSet};
use smallvec::{smallvec, SmallVec};
-use span::Edition;
use stdx::never;
use triomphe::Arc;
@@ -24,12 +24,14 @@ use crate::{
db::HirDatabase,
error_lifetime, from_chalk_trait_id, from_foreign_def_id,
infer::{unify::InferenceTable, Adjust, Adjustment, OverloadedDeref, PointerCast},
+ lang_items::is_box,
primitive::{FloatTy, IntTy, UintTy},
to_chalk_trait_id,
utils::all_super_traits,
- AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, Goal, Guidance,
- InEnvironment, Interner, Scalar, Solution, Substitution, TraitEnvironment, TraitRef,
- TraitRefExt, Ty, TyBuilder, TyExt,
+ AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, GenericArgData,
+ Goal, Guidance, InEnvironment, Interner, Mutability, Scalar, Solution, Substitution,
+ TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, TyVariableKind,
+ VariableKind, WhereClause,
};
/// This is used as a key for indexing impls.
@@ -200,7 +202,7 @@ impl TraitImpls {
// FIXME: Reservation impls should be considered during coherence checks. If we are
// (ever) to implement coherence checks, this filtering should be done by the trait
// solver.
- if db.attrs(impl_id.into()).by_key("rustc_reservation_impl").exists() {
+ if db.attrs(impl_id.into()).by_key(&sym::rustc_reservation_impl).exists() {
continue;
}
let target_trait = match db.impl_trait(impl_id) {
@@ -1081,6 +1083,11 @@ fn iterate_method_candidates_by_receiver(
table.run_in_snapshot(|table| {
let mut autoderef = autoderef::Autoderef::new(table, receiver_ty.clone(), true);
while let Some((self_ty, _)) = autoderef.next() {
+ if matches!(self_ty.kind(Interner), TyKind::InferenceVar(_, TyVariableKind::General)) {
+ // don't try to resolve methods on unknown types
+ return ControlFlow::Continue(());
+ }
+
iterate_trait_method_candidates(
&self_ty,
autoderef.table,
@@ -1145,17 +1152,30 @@ fn iterate_trait_method_candidates(
'traits: for &t in traits_in_scope {
let data = db.trait_data(t);
- // Traits annotated with `#[rustc_skip_array_during_method_dispatch]` are skipped during
+ // Traits annotated with `#[rustc_skip_during_method_dispatch]` are skipped during
// method resolution, if the receiver is an array, and we're compiling for editions before
// 2021.
// This is to make `[a].into_iter()` not break code with the new `IntoIterator` impl for
// arrays.
if data.skip_array_during_method_dispatch
- && matches!(self_ty.kind(Interner), chalk_ir::TyKind::Array(..))
+ && matches!(self_ty.kind(Interner), TyKind::Array(..))
{
// FIXME: this should really be using the edition of the method name's span, in case it
// comes from a macro
- if db.crate_graph()[krate].edition < Edition::Edition2021 {
+ if !db.crate_graph()[krate].edition.at_least_2021() {
+ continue;
+ }
+ }
+ if data.skip_boxed_slice_during_method_dispatch
+ && matches!(
+ self_ty.kind(Interner), TyKind::Adt(AdtId(def), subst)
+ if is_box(table.db, *def)
+ && matches!(subst.at(Interner, 0).assert_ty_ref(Interner).kind(Interner), TyKind::Slice(..))
+ )
+ {
+ // FIXME: this should really be using the edition of the method name's span, in case it
+ // comes from a macro
+ if !db.crate_graph()[krate].edition.at_least_2024() {
continue;
}
}
@@ -1618,15 +1638,11 @@ fn generic_implements_goal(
let kinds =
binders.iter().cloned().chain(trait_ref.substitution.iter(Interner).skip(1).map(|it| {
let vk = match it.data(Interner) {
- chalk_ir::GenericArgData::Ty(_) => {
- chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)
- }
- chalk_ir::GenericArgData::Lifetime(_) => chalk_ir::VariableKind::Lifetime,
- chalk_ir::GenericArgData::Const(c) => {
- chalk_ir::VariableKind::Const(c.data(Interner).ty.clone())
- }
+ GenericArgData::Ty(_) => VariableKind::Ty(chalk_ir::TyVariableKind::General),
+ GenericArgData::Lifetime(_) => VariableKind::Lifetime,
+ GenericArgData::Const(c) => VariableKind::Const(c.data(Interner).ty.clone()),
};
- chalk_ir::WithKind::new(vk, UniverseIndex::ROOT)
+ WithKind::new(vk, UniverseIndex::ROOT)
}));
let binders = CanonicalVarKinds::from_iter(Interner, kinds);