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.rs | 50 |
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); |