unsize cast array only on pointer type
This commit is contained in:
parent
0fcef7fdd3
commit
0bf0d937b8
@ -17,11 +17,13 @@ use crate::{
|
|||||||
|
|
||||||
static AUTODEREF_RECURSION_LIMIT: Limit = Limit::new(10);
|
static AUTODEREF_RECURSION_LIMIT: Limit = Limit::new(10);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub(crate) enum AutoderefKind {
|
pub(crate) enum AutoderefKind {
|
||||||
Builtin,
|
Builtin,
|
||||||
Overloaded,
|
Overloaded,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub(crate) struct Autoderef<'a, 'db> {
|
pub(crate) struct Autoderef<'a, 'db> {
|
||||||
pub(crate) table: &'a mut InferenceTable<'db>,
|
pub(crate) table: &'a mut InferenceTable<'db>,
|
||||||
ty: Ty,
|
ty: Ty,
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
use std::{ops::ControlFlow, sync::Arc};
|
use std::{ops::ControlFlow, sync::Arc};
|
||||||
|
|
||||||
use base_db::{CrateId, Edition};
|
use base_db::{CrateId, Edition};
|
||||||
use chalk_ir::{cast::Cast, Mutability, UniverseIndex};
|
use chalk_ir::{cast::Cast, Mutability, TyKind, UniverseIndex};
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
data::ImplData, item_scope::ItemScope, lang_item::LangItem, nameres::DefMap, AssocItemId,
|
data::ImplData, item_scope::ItemScope, lang_item::LangItem, nameres::DefMap, AssocItemId,
|
||||||
BlockId, ConstId, FunctionId, HasModule, ImplId, ItemContainerId, Lookup, ModuleDefId,
|
BlockId, ConstId, FunctionId, HasModule, ImplId, ItemContainerId, Lookup, ModuleDefId,
|
||||||
@ -25,7 +25,7 @@ use crate::{
|
|||||||
static_lifetime, to_chalk_trait_id,
|
static_lifetime, to_chalk_trait_id,
|
||||||
utils::all_super_traits,
|
utils::all_super_traits,
|
||||||
AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, InEnvironment, Interner,
|
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.
|
/// This is used as a key for indexing impls.
|
||||||
@ -588,25 +588,31 @@ impl ReceiverAdjustments {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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 {
|
if let Some(m) = self.autoref {
|
||||||
ty = TyKind::Ref(m, static_lifetime(), ty).intern(Interner);
|
ty = TyKind::Ref(m, static_lifetime(), ty).intern(Interner);
|
||||||
adjust
|
adjust
|
||||||
.push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(m)), target: ty.clone() });
|
.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)
|
(ty, adjust)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1725,14 +1725,13 @@ fn test() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn receiver_adjustment_unsize_array() {
|
fn receiver_adjustment_unsize_array() {
|
||||||
// FIXME not quite correct
|
|
||||||
check(
|
check(
|
||||||
r#"
|
r#"
|
||||||
//- minicore: slice
|
//- minicore: slice
|
||||||
fn test() {
|
fn test() {
|
||||||
let a = [1, 2, 3];
|
let a = [1, 2, 3];
|
||||||
a.len();
|
a.len();
|
||||||
} //^ adjustments: Pointer(Unsize), Borrow(Ref(Not))
|
} //^ adjustments: Borrow(Ref(Not)), Pointer(Unsize)
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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> {
|
pub unsafe trait SliceIndex<T: ?Sized> {
|
||||||
type Output: ?Sized;
|
type Output: ?Sized;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user