Auto merge of #14068 - HKalbasi:unsize, r=flodiebold

Unsize cast array only on pointer type

fix #14000
This commit is contained in:
bors 2023-01-31 21:33:04 +00:00
commit a4d3a4a75b
4 changed files with 43 additions and 18 deletions

View File

@ -17,11 +17,13 @@
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,

View File

@ -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 @@
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 @@ pub(crate) fn apply(&self, table: &mut InferenceTable<'_>, ty: Ty) -> (Ty, Vec<A
}
}
}
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
}
};
// 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() });
}
if self.unsize_array {
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
};
adjust.push(Adjustment {
kind: Adjust::Pointer(PointerCast::Unsize),
target: ty.clone(),
});
}
(ty, adjust)
}

View File

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

View File

@ -273,6 +273,24 @@ fn index_mut(&mut self, index: I) -> &mut I::Output {
}
}
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;
}