Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/autoderef.rs2
-rw-r--r--crates/hir-ty/src/method_resolution.rs32
-rw-r--r--crates/hir-ty/src/tests/method_resolution.rs3
-rw-r--r--crates/test-utils/src/minicore.rs18
4 files changed, 40 insertions, 15 deletions
diff --git a/crates/hir-ty/src/autoderef.rs b/crates/hir-ty/src/autoderef.rs
index caddca6d91..58744dd0c0 100644
--- a/crates/hir-ty/src/autoderef.rs
+++ b/crates/hir-ty/src/autoderef.rs
@@ -17,11 +17,13 @@ use crate::{
static AUTODEREF_RECURSION_LIMIT: Limit = Limit::new(10);
+#[derive(Debug)]
pub(crate) enum AutoderefKind {
Builtin,
Overloaded,
}
+#[derive(Debug)]
pub(crate) struct Autoderef<'a, 'db> {
pub(crate) table: &'a mut InferenceTable<'db>,
ty: Ty,
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index 858de00059..8c7714b9a6 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, sync::Arc};
use base_db::{CrateId, Edition};
-use chalk_ir::{cast::Cast, Mutability, UniverseIndex};
+use chalk_ir::{cast::Cast, Mutability, TyKind, UniverseIndex};
use hir_def::{
data::ImplData, item_scope::ItemScope, lang_item::LangItem, nameres::DefMap, AssocItemId,
BlockId, ConstId, FunctionId, HasModule, ImplId, ItemContainerId, Lookup, ModuleDefId,
@@ -25,7 +25,7 @@ use crate::{
static_lifetime, to_chalk_trait_id,
utils::all_super_traits,
AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, InEnvironment, Interner,
- Scalar, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind,
+ Scalar, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt,
};
/// This is used as a key for indexing impls.
@@ -588,25 +588,31 @@ impl ReceiverAdjustments {
}
}
}
+ if let Some(m) = self.autoref {
+ ty = TyKind::Ref(m, static_lifetime(), ty).intern(Interner);
+ adjust
+ .push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(m)), target: ty.clone() });
+ }
if self.unsize_array {
- ty = match ty.kind(Interner) {
- TyKind::Array(inner, _) => TyKind::Slice(inner.clone()).intern(Interner),
- _ => {
- never!("unsize_array with non-array {:?}", ty);
- ty
+ ty = 'x: {
+ if let TyKind::Ref(m, l, inner) = ty.kind(Interner) {
+ if let TyKind::Array(inner, _) = inner.kind(Interner) {
+ break 'x TyKind::Ref(
+ m.clone(),
+ l.clone(),
+ TyKind::Slice(inner.clone()).intern(Interner),
+ )
+ .intern(Interner);
+ }
}
+ never!("unsize_array with non-reference-to-array {:?}", ty);
+ ty
};
- // FIXME this is kind of wrong since the unsize needs to happen to a pointer/reference
adjust.push(Adjustment {
kind: Adjust::Pointer(PointerCast::Unsize),
target: ty.clone(),
});
}
- if let Some(m) = self.autoref {
- ty = TyKind::Ref(m, static_lifetime(), ty).intern(Interner);
- adjust
- .push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(m)), target: ty.clone() });
- }
(ty, adjust)
}
diff --git a/crates/hir-ty/src/tests/method_resolution.rs b/crates/hir-ty/src/tests/method_resolution.rs
index 616ca8058e..42fb685abf 100644
--- a/crates/hir-ty/src/tests/method_resolution.rs
+++ b/crates/hir-ty/src/tests/method_resolution.rs
@@ -1725,14 +1725,13 @@ fn test() {
#[test]
fn receiver_adjustment_unsize_array() {
- // FIXME not quite correct
check(
r#"
//- minicore: slice
fn test() {
let a = [1, 2, 3];
a.len();
-} //^ adjustments: Pointer(Unsize), Borrow(Ref(Not))
+} //^ adjustments: Borrow(Ref(Not)), Pointer(Unsize)
"#,
);
}
diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs
index dff6091440..5634bafd06 100644
--- a/crates/test-utils/src/minicore.rs
+++ b/crates/test-utils/src/minicore.rs
@@ -273,6 +273,24 @@ pub mod ops {
}
}
+ impl<T, I, const N: usize> Index<I> for [T; N]
+ where
+ I: SliceIndex<[T]>,
+ {
+ type Output = I::Output;
+ fn index(&self, index: I) -> &I::Output {
+ loop {}
+ }
+ }
+ impl<T, I, const N: usize> IndexMut<I> for [T; N]
+ where
+ I: SliceIndex<[T]>,
+ {
+ fn index_mut(&mut self, index: I) -> &mut I::Output {
+ loop {}
+ }
+ }
+
pub unsafe trait SliceIndex<T: ?Sized> {
type Output: ?Sized;
}