mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 05:53:45 +00:00
Auto merge of #14068 - HKalbasi:unsize, r=flodiebold
Unsize cast array only on pointer type fix #14000
This commit is contained in:
commit
a4d3a4a75b
4 changed files with 43 additions and 18 deletions
|
@ -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,
|
||||
|
|
|
@ -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 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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue