mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 22:01:37 +00:00
Merge #8799
8799: Add basic support for array lengths in types r=flodiebold a=lf- This recognizes `let a = [1u8, 2, 3]` as having type `[u8; 3]` instead of the previous `[u8; _]`. Byte strings and `[0u8; 2]` kinds of range array declarations are unsupported as before. I don't know why a bunch of our rustc tests had single quotes inside strings un-escaped by `UPDATE_EXPECT=1 cargo t`, but I don't think it's bad? Maybe something in a nightly? Co-authored-by: Jade <software@lfcode.ca>
This commit is contained in:
commit
312f1fe20a
12 changed files with 156 additions and 110 deletions
21
crates/hir_ty/src/consts.rs
Normal file
21
crates/hir_ty/src/consts.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
//! Handling of concrete const values
|
||||||
|
|
||||||
|
/// A concrete constant value
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub enum ConstScalar {
|
||||||
|
// for now, we only support the trivial case of constant evaluating the length of an array
|
||||||
|
// Note that this is u64 because the target usize may be bigger than our usize
|
||||||
|
Usize(u64),
|
||||||
|
|
||||||
|
/// Case of an unknown value that rustc might know but we don't
|
||||||
|
Unknown,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for ConstScalar {
|
||||||
|
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||||
|
match self {
|
||||||
|
ConstScalar::Usize(us) => write!(fmt, "{}", us),
|
||||||
|
ConstScalar::Unknown => write!(fmt, "_"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -308,7 +308,7 @@ impl HirDisplay for Const {
|
||||||
let param_data = &generics.params.consts[id.local_id];
|
let param_data = &generics.params.consts[id.local_id];
|
||||||
write!(f, "{}", param_data.name)
|
write!(f, "{}", param_data.name)
|
||||||
}
|
}
|
||||||
ConstValue::Concrete(_) => write!(f, "_"),
|
ConstValue::Concrete(c) => write!(f, "{}", c.interned),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use std::iter::{repeat, repeat_with};
|
use std::iter::{repeat, repeat_with};
|
||||||
use std::{mem, sync::Arc};
|
use std::{mem, sync::Arc};
|
||||||
|
|
||||||
use chalk_ir::{cast::Cast, fold::Shift, Mutability, TyVariableKind};
|
use chalk_ir::{cast::Cast, fold::Shift, ConstData, Mutability, TyVariableKind};
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
|
expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
|
||||||
path::{GenericArg, GenericArgs},
|
path::{GenericArg, GenericArgs},
|
||||||
|
@ -15,7 +15,9 @@ use stdx::always;
|
||||||
use syntax::ast::RangeOp;
|
use syntax::ast::RangeOp;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
autoderef, dummy_usize_const,
|
autoderef,
|
||||||
|
consts::ConstScalar,
|
||||||
|
dummy_usize_const,
|
||||||
lower::lower_to_chalk_mutability,
|
lower::lower_to_chalk_mutability,
|
||||||
mapping::from_chalk,
|
mapping::from_chalk,
|
||||||
method_resolution, op,
|
method_resolution, op,
|
||||||
|
@ -23,7 +25,7 @@ use crate::{
|
||||||
static_lifetime, to_chalk_trait_id,
|
static_lifetime, to_chalk_trait_id,
|
||||||
traits::FnTrait,
|
traits::FnTrait,
|
||||||
utils::{generics, Generics},
|
utils::{generics, Generics},
|
||||||
AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
|
AdtId, Binders, CallableDefId, ConstValue, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
|
||||||
ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
|
ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -717,11 +719,12 @@ impl<'a> InferenceContext<'a> {
|
||||||
_ => self.table.new_type_var(),
|
_ => self.table.new_type_var(),
|
||||||
};
|
};
|
||||||
|
|
||||||
match array {
|
let len = match array {
|
||||||
Array::ElementList(items) => {
|
Array::ElementList(items) => {
|
||||||
for expr in items.iter() {
|
for expr in items.iter() {
|
||||||
self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone()));
|
self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone()));
|
||||||
}
|
}
|
||||||
|
Some(items.len())
|
||||||
}
|
}
|
||||||
Array::Repeat { initializer, repeat } => {
|
Array::Repeat { initializer, repeat } => {
|
||||||
self.infer_expr_coerce(
|
self.infer_expr_coerce(
|
||||||
|
@ -734,10 +737,20 @@ impl<'a> InferenceContext<'a> {
|
||||||
TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
|
TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
// FIXME: support length for Repeat array expressions
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
TyKind::Array(elem_ty, dummy_usize_const()).intern(&Interner)
|
let cd = ConstData {
|
||||||
|
ty: TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
|
||||||
|
value: ConstValue::Concrete(chalk_ir::ConcreteConst {
|
||||||
|
interned: len
|
||||||
|
.map(|len| ConstScalar::Usize(len as u64))
|
||||||
|
.unwrap_or(ConstScalar::Unknown),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
TyKind::Array(elem_ty, cd.intern(&Interner)).intern(&Interner)
|
||||||
}
|
}
|
||||||
Expr::Literal(lit) => match lit {
|
Expr::Literal(lit) => match lit {
|
||||||
Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
|
Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
|
||||||
|
@ -747,6 +760,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
}
|
}
|
||||||
Literal::ByteString(..) => {
|
Literal::ByteString(..) => {
|
||||||
let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner);
|
let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner);
|
||||||
|
|
||||||
let array_type =
|
let array_type =
|
||||||
TyKind::Array(byte_type, dummy_usize_const()).intern(&Interner);
|
TyKind::Array(byte_type, dummy_usize_const()).intern(&Interner);
|
||||||
TyKind::Ref(Mutability::Not, static_lifetime(), array_type).intern(&Interner)
|
TyKind::Ref(Mutability::Not, static_lifetime(), array_type).intern(&Interner)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Implementation of the Chalk `Interner` trait, which allows customizing the
|
//! Implementation of the Chalk `Interner` trait, which allows customizing the
|
||||||
//! representation of the various objects Chalk deals with (types, goals etc.).
|
//! representation of the various objects Chalk deals with (types, goals etc.).
|
||||||
|
|
||||||
use crate::{chalk_db, tls, GenericArg};
|
use crate::{chalk_db, consts::ConstScalar, tls, GenericArg};
|
||||||
use base_db::salsa::InternId;
|
use base_db::salsa::InternId;
|
||||||
use chalk_ir::{Goal, GoalData};
|
use chalk_ir::{Goal, GoalData};
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
|
@ -31,6 +31,7 @@ impl_internable!(
|
||||||
InternedWrapper<chalk_ir::TyData<Interner>>,
|
InternedWrapper<chalk_ir::TyData<Interner>>,
|
||||||
InternedWrapper<chalk_ir::LifetimeData<Interner>>,
|
InternedWrapper<chalk_ir::LifetimeData<Interner>>,
|
||||||
InternedWrapper<chalk_ir::ConstData<Interner>>,
|
InternedWrapper<chalk_ir::ConstData<Interner>>,
|
||||||
|
InternedWrapper<ConstScalar>,
|
||||||
InternedWrapper<Vec<chalk_ir::CanonicalVarKind<Interner>>>,
|
InternedWrapper<Vec<chalk_ir::CanonicalVarKind<Interner>>>,
|
||||||
InternedWrapper<Vec<chalk_ir::ProgramClause<Interner>>>,
|
InternedWrapper<Vec<chalk_ir::ProgramClause<Interner>>>,
|
||||||
InternedWrapper<Vec<chalk_ir::QuantifiedWhereClause<Interner>>>,
|
InternedWrapper<Vec<chalk_ir::QuantifiedWhereClause<Interner>>>,
|
||||||
|
@ -41,7 +42,7 @@ impl chalk_ir::interner::Interner for Interner {
|
||||||
type InternedType = Interned<InternedWrapper<chalk_ir::TyData<Interner>>>;
|
type InternedType = Interned<InternedWrapper<chalk_ir::TyData<Interner>>>;
|
||||||
type InternedLifetime = Interned<InternedWrapper<chalk_ir::LifetimeData<Self>>>;
|
type InternedLifetime = Interned<InternedWrapper<chalk_ir::LifetimeData<Self>>>;
|
||||||
type InternedConst = Interned<InternedWrapper<chalk_ir::ConstData<Self>>>;
|
type InternedConst = Interned<InternedWrapper<chalk_ir::ConstData<Self>>>;
|
||||||
type InternedConcreteConst = ();
|
type InternedConcreteConst = ConstScalar;
|
||||||
type InternedGenericArg = chalk_ir::GenericArgData<Self>;
|
type InternedGenericArg = chalk_ir::GenericArgData<Self>;
|
||||||
type InternedGoal = Arc<GoalData<Self>>;
|
type InternedGoal = Arc<GoalData<Self>>;
|
||||||
type InternedGoals = Vec<Goal<Self>>;
|
type InternedGoals = Vec<Goal<Self>>;
|
||||||
|
@ -245,10 +246,15 @@ impl chalk_ir::interner::Interner for Interner {
|
||||||
fn const_eq(
|
fn const_eq(
|
||||||
&self,
|
&self,
|
||||||
_ty: &Self::InternedType,
|
_ty: &Self::InternedType,
|
||||||
_c1: &Self::InternedConcreteConst,
|
c1: &Self::InternedConcreteConst,
|
||||||
_c2: &Self::InternedConcreteConst,
|
c2: &Self::InternedConcreteConst,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
true
|
match (c1, c2) {
|
||||||
|
(&ConstScalar::Usize(a), &ConstScalar::Usize(b)) => a == b,
|
||||||
|
// we were previously assuming this to be true, I'm not whether true or false on
|
||||||
|
// unknown values is safer.
|
||||||
|
(_, _) => true,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intern_generic_arg(
|
fn intern_generic_arg(
|
||||||
|
|
|
@ -12,6 +12,7 @@ mod chalk_db;
|
||||||
mod chalk_ext;
|
mod chalk_ext;
|
||||||
mod infer;
|
mod infer;
|
||||||
mod interner;
|
mod interner;
|
||||||
|
mod consts;
|
||||||
mod lower;
|
mod lower;
|
||||||
mod mapping;
|
mod mapping;
|
||||||
mod op;
|
mod op;
|
||||||
|
@ -39,7 +40,7 @@ use chalk_ir::{
|
||||||
};
|
};
|
||||||
use hir_def::{expr::ExprId, type_ref::Rawness, TypeParamId};
|
use hir_def::{expr::ExprId, type_ref::Rawness, TypeParamId};
|
||||||
|
|
||||||
use crate::{db::HirDatabase, display::HirDisplay, utils::generics};
|
use crate::{consts::ConstScalar, db::HirDatabase, display::HirDisplay, utils::generics};
|
||||||
|
|
||||||
pub use autoderef::autoderef;
|
pub use autoderef::autoderef;
|
||||||
pub use builder::TyBuilder;
|
pub use builder::TyBuilder;
|
||||||
|
@ -250,7 +251,9 @@ pub fn dummy_usize_const() -> Const {
|
||||||
let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner);
|
let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner);
|
||||||
chalk_ir::ConstData {
|
chalk_ir::ConstData {
|
||||||
ty: usize_ty,
|
ty: usize_ty,
|
||||||
value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }),
|
value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst {
|
||||||
|
interned: ConstScalar::Unknown,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
.intern(&Interner)
|
.intern(&Interner)
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,6 +174,8 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
}
|
}
|
||||||
TypeRef::Array(inner) => {
|
TypeRef::Array(inner) => {
|
||||||
let inner_ty = self.lower_ty(inner);
|
let inner_ty = self.lower_ty(inner);
|
||||||
|
// FIXME: we don't have length info here because we don't store an expression for
|
||||||
|
// the length
|
||||||
TyKind::Array(inner_ty, dummy_usize_const()).intern(&Interner)
|
TyKind::Array(inner_ty, dummy_usize_const()).intern(&Interner)
|
||||||
}
|
}
|
||||||
TypeRef::Slice(inner) => {
|
TypeRef::Slice(inner) => {
|
||||||
|
|
|
@ -55,7 +55,7 @@ fn coerce_places() {
|
||||||
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
|
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
|
||||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
|
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r"
|
expect![[r#"
|
||||||
30..31 '_': &[T]
|
30..31 '_': &[T]
|
||||||
44..55 '{ loop {} }': T
|
44..55 '{ loop {} }': T
|
||||||
46..53 'loop {}': !
|
46..53 'loop {}': !
|
||||||
|
@ -72,8 +72,8 @@ fn coerce_places() {
|
||||||
165..170 'gen()': *mut [U; _]
|
165..170 'gen()': *mut [U; _]
|
||||||
185..419 '{ ...rr); }': ()
|
185..419 '{ ...rr); }': ()
|
||||||
195..198 'arr': &[u8; _]
|
195..198 'arr': &[u8; _]
|
||||||
211..215 '&[1]': &[u8; _]
|
211..215 '&[1]': &[u8; 1]
|
||||||
212..215 '[1]': [u8; _]
|
212..215 '[1]': [u8; 1]
|
||||||
213..214 '1': u8
|
213..214 '1': u8
|
||||||
226..227 'a': &[u8]
|
226..227 'a': &[u8]
|
||||||
236..239 'arr': &[u8; _]
|
236..239 'arr': &[u8; _]
|
||||||
|
@ -90,7 +90,7 @@ fn coerce_places() {
|
||||||
302..314 'S { a: arr }': S<&[u8]>
|
302..314 'S { a: arr }': S<&[u8]>
|
||||||
309..312 'arr': &[u8; _]
|
309..312 'arr': &[u8; _]
|
||||||
325..326 'e': [&[u8]; _]
|
325..326 'e': [&[u8]; _]
|
||||||
340..345 '[arr]': [&[u8]; _]
|
340..345 '[arr]': [&[u8]; 1]
|
||||||
341..344 'arr': &[u8; _]
|
341..344 'arr': &[u8; _]
|
||||||
355..356 'f': [&[u8]; _]
|
355..356 'f': [&[u8]; _]
|
||||||
370..378 '[arr; 2]': [&[u8]; _]
|
370..378 '[arr; 2]': [&[u8]; _]
|
||||||
|
@ -100,7 +100,7 @@ fn coerce_places() {
|
||||||
406..416 '(arr, arr)': (&[u8], &[u8])
|
406..416 '(arr, arr)': (&[u8], &[u8])
|
||||||
407..410 'arr': &[u8; _]
|
407..410 'arr': &[u8; _]
|
||||||
412..415 'arr': &[u8; _]
|
412..415 'arr': &[u8; _]
|
||||||
"]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,17 +113,17 @@ fn infer_let_stmt_coerce() {
|
||||||
let x: *const [isize] = &[1];
|
let x: *const [isize] = &[1];
|
||||||
}
|
}
|
||||||
",
|
",
|
||||||
expect![[r"
|
expect![[r#"
|
||||||
10..75 '{ ...[1]; }': ()
|
10..75 '{ ...[1]; }': ()
|
||||||
20..21 'x': &[isize]
|
20..21 'x': &[isize]
|
||||||
34..38 '&[1]': &[isize; _]
|
34..38 '&[1]': &[isize; 1]
|
||||||
35..38 '[1]': [isize; _]
|
35..38 '[1]': [isize; 1]
|
||||||
36..37 '1': isize
|
36..37 '1': isize
|
||||||
48..49 'x': *const [isize]
|
48..49 'x': *const [isize]
|
||||||
68..72 '&[1]': &[isize; _]
|
68..72 '&[1]': &[isize; 1]
|
||||||
69..72 '[1]': [isize; _]
|
69..72 '[1]': [isize; 1]
|
||||||
70..71 '1': isize
|
70..71 '1': isize
|
||||||
"]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ fn infer_if_coerce() {
|
||||||
#[lang = "unsize"]
|
#[lang = "unsize"]
|
||||||
pub trait Unsize<T: ?Sized> {}
|
pub trait Unsize<T: ?Sized> {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r"
|
expect![[r#"
|
||||||
10..11 'x': &[T]
|
10..11 'x': &[T]
|
||||||
27..38 '{ loop {} }': &[T]
|
27..38 '{ loop {} }': &[T]
|
||||||
29..36 'loop {}': !
|
29..36 'loop {}': !
|
||||||
|
@ -220,14 +220,14 @@ fn infer_if_coerce() {
|
||||||
71..96 '{ ... }': &[i32]
|
71..96 '{ ... }': &[i32]
|
||||||
81..84 'foo': fn foo<i32>(&[i32]) -> &[i32]
|
81..84 'foo': fn foo<i32>(&[i32]) -> &[i32]
|
||||||
81..90 'foo(&[1])': &[i32]
|
81..90 'foo(&[1])': &[i32]
|
||||||
85..89 '&[1]': &[i32; _]
|
85..89 '&[1]': &[i32; 1]
|
||||||
86..89 '[1]': [i32; _]
|
86..89 '[1]': [i32; 1]
|
||||||
87..88 '1': i32
|
87..88 '1': i32
|
||||||
102..122 '{ ... }': &[i32; _]
|
102..122 '{ ... }': &[i32; 1]
|
||||||
112..116 '&[1]': &[i32; _]
|
112..116 '&[1]': &[i32; 1]
|
||||||
113..116 '[1]': [i32; _]
|
113..116 '[1]': [i32; 1]
|
||||||
114..115 '1': i32
|
114..115 '1': i32
|
||||||
"]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ fn infer_if_else_coerce() {
|
||||||
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
|
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
|
||||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
|
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r"
|
expect![[r#"
|
||||||
10..11 'x': &[T]
|
10..11 'x': &[T]
|
||||||
27..38 '{ loop {} }': &[T]
|
27..38 '{ loop {} }': &[T]
|
||||||
29..36 'loop {}': !
|
29..36 'loop {}': !
|
||||||
|
@ -263,17 +263,17 @@ fn infer_if_else_coerce() {
|
||||||
59..60 'x': &[i32]
|
59..60 'x': &[i32]
|
||||||
63..122 'if tru... }': &[i32]
|
63..122 'if tru... }': &[i32]
|
||||||
66..70 'true': bool
|
66..70 'true': bool
|
||||||
71..91 '{ ... }': &[i32; _]
|
71..91 '{ ... }': &[i32; 1]
|
||||||
81..85 '&[1]': &[i32; _]
|
81..85 '&[1]': &[i32; 1]
|
||||||
82..85 '[1]': [i32; _]
|
82..85 '[1]': [i32; 1]
|
||||||
83..84 '1': i32
|
83..84 '1': i32
|
||||||
97..122 '{ ... }': &[i32]
|
97..122 '{ ... }': &[i32]
|
||||||
107..110 'foo': fn foo<i32>(&[i32]) -> &[i32]
|
107..110 'foo': fn foo<i32>(&[i32]) -> &[i32]
|
||||||
107..116 'foo(&[1])': &[i32]
|
107..116 'foo(&[1])': &[i32]
|
||||||
111..115 '&[1]': &[i32; _]
|
111..115 '&[1]': &[i32; 1]
|
||||||
112..115 '[1]': [i32; _]
|
112..115 '[1]': [i32; 1]
|
||||||
113..114 '1': i32
|
113..114 '1': i32
|
||||||
"]],
|
"#]],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ fn infer_match_first_coerce() {
|
||||||
#[lang = "unsize"]
|
#[lang = "unsize"]
|
||||||
pub trait Unsize<T: ?Sized> {}
|
pub trait Unsize<T: ?Sized> {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r"
|
expect![[r#"
|
||||||
10..11 'x': &[T]
|
10..11 'x': &[T]
|
||||||
27..38 '{ loop {} }': &[T]
|
27..38 '{ loop {} }': &[T]
|
||||||
29..36 'loop {}': !
|
29..36 'loop {}': !
|
||||||
|
@ -309,19 +309,19 @@ fn infer_match_first_coerce() {
|
||||||
87..88 '2': i32
|
87..88 '2': i32
|
||||||
92..95 'foo': fn foo<i32>(&[i32]) -> &[i32]
|
92..95 'foo': fn foo<i32>(&[i32]) -> &[i32]
|
||||||
92..101 'foo(&[2])': &[i32]
|
92..101 'foo(&[2])': &[i32]
|
||||||
96..100 '&[2]': &[i32; _]
|
96..100 '&[2]': &[i32; 1]
|
||||||
97..100 '[2]': [i32; _]
|
97..100 '[2]': [i32; 1]
|
||||||
98..99 '2': i32
|
98..99 '2': i32
|
||||||
111..112 '1': i32
|
111..112 '1': i32
|
||||||
111..112 '1': i32
|
111..112 '1': i32
|
||||||
116..120 '&[1]': &[i32; _]
|
116..120 '&[1]': &[i32; 1]
|
||||||
117..120 '[1]': [i32; _]
|
117..120 '[1]': [i32; 1]
|
||||||
118..119 '1': i32
|
118..119 '1': i32
|
||||||
130..131 '_': i32
|
130..131 '_': i32
|
||||||
135..139 '&[3]': &[i32; _]
|
135..139 '&[3]': &[i32; 1]
|
||||||
136..139 '[3]': [i32; _]
|
136..139 '[3]': [i32; 1]
|
||||||
137..138 '3': i32
|
137..138 '3': i32
|
||||||
"]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ fn infer_match_second_coerce() {
|
||||||
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
|
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
|
||||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
|
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r"
|
expect![[r#"
|
||||||
10..11 'x': &[T]
|
10..11 'x': &[T]
|
||||||
27..38 '{ loop {} }': &[T]
|
27..38 '{ loop {} }': &[T]
|
||||||
29..36 'loop {}': !
|
29..36 'loop {}': !
|
||||||
|
@ -360,21 +360,21 @@ fn infer_match_second_coerce() {
|
||||||
75..76 'i': i32
|
75..76 'i': i32
|
||||||
87..88 '1': i32
|
87..88 '1': i32
|
||||||
87..88 '1': i32
|
87..88 '1': i32
|
||||||
92..96 '&[1]': &[i32; _]
|
92..96 '&[1]': &[i32; 1]
|
||||||
93..96 '[1]': [i32; _]
|
93..96 '[1]': [i32; 1]
|
||||||
94..95 '1': i32
|
94..95 '1': i32
|
||||||
106..107 '2': i32
|
106..107 '2': i32
|
||||||
106..107 '2': i32
|
106..107 '2': i32
|
||||||
111..114 'foo': fn foo<i32>(&[i32]) -> &[i32]
|
111..114 'foo': fn foo<i32>(&[i32]) -> &[i32]
|
||||||
111..120 'foo(&[2])': &[i32]
|
111..120 'foo(&[2])': &[i32]
|
||||||
115..119 '&[2]': &[i32; _]
|
115..119 '&[2]': &[i32; 1]
|
||||||
116..119 '[2]': [i32; _]
|
116..119 '[2]': [i32; 1]
|
||||||
117..118 '2': i32
|
117..118 '2': i32
|
||||||
130..131 '_': i32
|
130..131 '_': i32
|
||||||
135..139 '&[3]': &[i32; _]
|
135..139 '&[3]': &[i32; 1]
|
||||||
136..139 '[3]': [i32; _]
|
136..139 '[3]': [i32; 1]
|
||||||
137..138 '3': i32
|
137..138 '3': i32
|
||||||
"]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -685,15 +685,15 @@ fn coerce_unsize_array() {
|
||||||
let f: &[usize] = &[1, 2, 3];
|
let f: &[usize] = &[1, 2, 3];
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r"
|
expect![[r#"
|
||||||
161..198 '{ ... 3]; }': ()
|
161..198 '{ ... 3]; }': ()
|
||||||
171..172 'f': &[usize]
|
171..172 'f': &[usize]
|
||||||
185..195 '&[1, 2, 3]': &[usize; _]
|
185..195 '&[1, 2, 3]': &[usize; 3]
|
||||||
186..195 '[1, 2, 3]': [usize; _]
|
186..195 '[1, 2, 3]': [usize; 3]
|
||||||
187..188 '1': usize
|
187..188 '1': usize
|
||||||
190..191 '2': usize
|
190..191 '2': usize
|
||||||
193..194 '3': usize
|
193..194 '3': usize
|
||||||
"]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -243,8 +243,8 @@ fn infer_pattern_match_slice() {
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
10..209 '{ ... } }': ()
|
10..209 '{ ... } }': ()
|
||||||
20..25 'slice': &[f64]
|
20..25 'slice': &[f64]
|
||||||
36..42 '&[0.0]': &[f64; _]
|
36..42 '&[0.0]': &[f64; 1]
|
||||||
37..42 '[0.0]': [f64; _]
|
37..42 '[0.0]': [f64; 1]
|
||||||
38..41 '0.0': f64
|
38..41 '0.0': f64
|
||||||
48..207 'match ... }': ()
|
48..207 'match ... }': ()
|
||||||
54..59 'slice': &[f64]
|
54..59 'slice': &[f64]
|
||||||
|
@ -346,7 +346,7 @@ fn infer_pattern_match_arr() {
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
10..179 '{ ... } }': ()
|
10..179 '{ ... } }': ()
|
||||||
20..23 'arr': [f64; _]
|
20..23 'arr': [f64; _]
|
||||||
36..46 '[0.0, 1.0]': [f64; _]
|
36..46 '[0.0, 1.0]': [f64; 2]
|
||||||
37..40 '0.0': f64
|
37..40 '0.0': f64
|
||||||
42..45 '1.0': f64
|
42..45 '1.0': f64
|
||||||
52..177 'match ... }': ()
|
52..177 'match ... }': ()
|
||||||
|
|
|
@ -99,7 +99,7 @@ fn recursive_vars() {
|
||||||
10..47 '{ ...&y]; }': ()
|
10..47 '{ ...&y]; }': ()
|
||||||
20..21 'y': &{unknown}
|
20..21 'y': &{unknown}
|
||||||
24..31 'unknown': &{unknown}
|
24..31 'unknown': &{unknown}
|
||||||
37..44 '[y, &y]': [&&{unknown}; _]
|
37..44 '[y, &y]': [&&{unknown}; 2]
|
||||||
38..39 'y': &{unknown}
|
38..39 'y': &{unknown}
|
||||||
41..43 '&y': &&{unknown}
|
41..43 '&y': &&{unknown}
|
||||||
42..43 'y': &{unknown}
|
42..43 'y': &{unknown}
|
||||||
|
@ -123,7 +123,7 @@ fn recursive_vars_2() {
|
||||||
24..31 'unknown': &&{unknown}
|
24..31 'unknown': &&{unknown}
|
||||||
41..42 'y': &&{unknown}
|
41..42 'y': &&{unknown}
|
||||||
45..52 'unknown': &&{unknown}
|
45..52 'unknown': &&{unknown}
|
||||||
58..76 '[(x, y..., &x)]': [(&&&{unknown}, &&&{unknown}); _]
|
58..76 '[(x, y..., &x)]': [(&&&{unknown}, &&&{unknown}); 2]
|
||||||
59..65 '(x, y)': (&&&{unknown}, &&&{unknown})
|
59..65 '(x, y)': (&&&{unknown}, &&&{unknown})
|
||||||
60..61 'x': &&{unknown}
|
60..61 'x': &&{unknown}
|
||||||
63..64 'y': &&{unknown}
|
63..64 'y': &&{unknown}
|
||||||
|
@ -175,8 +175,8 @@ fn infer_std_crash_2() {
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
22..52 '{ ...n']; }': ()
|
22..52 '{ ...n']; }': ()
|
||||||
28..49 '&[0, b...b'\n']': &[u8; _]
|
28..49 '&[0, b...b'\n']': &[u8; 4]
|
||||||
29..49 '[0, b'...b'\n']': [u8; _]
|
29..49 '[0, b'...b'\n']': [u8; 4]
|
||||||
30..31 '0': u8
|
30..31 '0': u8
|
||||||
33..38 'b'\n'': u8
|
33..38 'b'\n'': u8
|
||||||
40..41 '1': u8
|
40..41 '1': u8
|
||||||
|
@ -336,8 +336,8 @@ fn infer_array_macro_call() {
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
!0..4 '0u32': u32
|
!0..4 '0u32': u32
|
||||||
44..69 '{ ...()]; }': ()
|
44..69 '{ ...()]; }': ()
|
||||||
54..55 'a': [u32; _]
|
54..55 'a': [u32; 1]
|
||||||
58..66 '[bar!()]': [u32; _]
|
58..66 '[bar!()]': [u32; 1]
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ fn test() {
|
||||||
let x = box 1;
|
let x = box 1;
|
||||||
let t = (x, box x, box &1, box [1]);
|
let t = (x, box x, box &1, box [1]);
|
||||||
t;
|
t;
|
||||||
} //^ (Box<i32>, Box<Box<i32>>, Box<&i32>, Box<[i32; _]>)
|
} //^ (Box<i32>, Box<Box<i32>>, Box<&i32>, Box<[i32; 1]>)
|
||||||
|
|
||||||
//- /std.rs crate:std
|
//- /std.rs crate:std
|
||||||
#[prelude_import] use prelude::*;
|
#[prelude_import] use prelude::*;
|
||||||
|
@ -36,7 +36,7 @@ fn test() {
|
||||||
let x = box 1;
|
let x = box 1;
|
||||||
let t = (x, box x, box &1, box [1]);
|
let t = (x, box x, box &1, box [1]);
|
||||||
t;
|
t;
|
||||||
} //^ (Box<i32, {unknown}>, Box<Box<i32, {unknown}>, {unknown}>, Box<&i32, {unknown}>, Box<[i32; _], {unknown}>)
|
} //^ (Box<i32, {unknown}>, Box<Box<i32, {unknown}>, {unknown}>, Box<&i32, {unknown}>, Box<[i32; 1], {unknown}>)
|
||||||
|
|
||||||
//- /std.rs crate:std
|
//- /std.rs crate:std
|
||||||
#[prelude_import] use prelude::*;
|
#[prelude_import] use prelude::*;
|
||||||
|
@ -1266,55 +1266,55 @@ fn infer_array() {
|
||||||
8..9 'x': &str
|
8..9 'x': &str
|
||||||
17..18 'y': isize
|
17..18 'y': isize
|
||||||
27..292 '{ ... []; }': ()
|
27..292 '{ ... []; }': ()
|
||||||
37..38 'a': [&str; _]
|
37..38 'a': [&str; 1]
|
||||||
41..44 '[x]': [&str; _]
|
41..44 '[x]': [&str; 1]
|
||||||
42..43 'x': &str
|
42..43 'x': &str
|
||||||
54..55 'b': [[&str; _]; _]
|
54..55 'b': [[&str; 1]; 2]
|
||||||
58..64 '[a, a]': [[&str; _]; _]
|
58..64 '[a, a]': [[&str; 1]; 2]
|
||||||
59..60 'a': [&str; _]
|
59..60 'a': [&str; 1]
|
||||||
62..63 'a': [&str; _]
|
62..63 'a': [&str; 1]
|
||||||
74..75 'c': [[[&str; _]; _]; _]
|
74..75 'c': [[[&str; 1]; 2]; 2]
|
||||||
78..84 '[b, b]': [[[&str; _]; _]; _]
|
78..84 '[b, b]': [[[&str; 1]; 2]; 2]
|
||||||
79..80 'b': [[&str; _]; _]
|
79..80 'b': [[&str; 1]; 2]
|
||||||
82..83 'b': [[&str; _]; _]
|
82..83 'b': [[&str; 1]; 2]
|
||||||
95..96 'd': [isize; _]
|
95..96 'd': [isize; 4]
|
||||||
99..111 '[y, 1, 2, 3]': [isize; _]
|
99..111 '[y, 1, 2, 3]': [isize; 4]
|
||||||
100..101 'y': isize
|
100..101 'y': isize
|
||||||
103..104 '1': isize
|
103..104 '1': isize
|
||||||
106..107 '2': isize
|
106..107 '2': isize
|
||||||
109..110 '3': isize
|
109..110 '3': isize
|
||||||
121..122 'd': [isize; _]
|
121..122 'd': [isize; 4]
|
||||||
125..137 '[1, y, 2, 3]': [isize; _]
|
125..137 '[1, y, 2, 3]': [isize; 4]
|
||||||
126..127 '1': isize
|
126..127 '1': isize
|
||||||
129..130 'y': isize
|
129..130 'y': isize
|
||||||
132..133 '2': isize
|
132..133 '2': isize
|
||||||
135..136 '3': isize
|
135..136 '3': isize
|
||||||
147..148 'e': [isize; _]
|
147..148 'e': [isize; 1]
|
||||||
151..154 '[y]': [isize; _]
|
151..154 '[y]': [isize; 1]
|
||||||
152..153 'y': isize
|
152..153 'y': isize
|
||||||
164..165 'f': [[isize; _]; _]
|
164..165 'f': [[isize; 4]; 2]
|
||||||
168..174 '[d, d]': [[isize; _]; _]
|
168..174 '[d, d]': [[isize; 4]; 2]
|
||||||
169..170 'd': [isize; _]
|
169..170 'd': [isize; 4]
|
||||||
172..173 'd': [isize; _]
|
172..173 'd': [isize; 4]
|
||||||
184..185 'g': [[isize; _]; _]
|
184..185 'g': [[isize; 1]; 2]
|
||||||
188..194 '[e, e]': [[isize; _]; _]
|
188..194 '[e, e]': [[isize; 1]; 2]
|
||||||
189..190 'e': [isize; _]
|
189..190 'e': [isize; 1]
|
||||||
192..193 'e': [isize; _]
|
192..193 'e': [isize; 1]
|
||||||
205..206 'h': [i32; _]
|
205..206 'h': [i32; 2]
|
||||||
209..215 '[1, 2]': [i32; _]
|
209..215 '[1, 2]': [i32; 2]
|
||||||
210..211 '1': i32
|
210..211 '1': i32
|
||||||
213..214 '2': i32
|
213..214 '2': i32
|
||||||
225..226 'i': [&str; _]
|
225..226 'i': [&str; 2]
|
||||||
229..239 '["a", "b"]': [&str; _]
|
229..239 '["a", "b"]': [&str; 2]
|
||||||
230..233 '"a"': &str
|
230..233 '"a"': &str
|
||||||
235..238 '"b"': &str
|
235..238 '"b"': &str
|
||||||
250..251 'b': [[&str; _]; _]
|
250..251 'b': [[&str; 1]; 2]
|
||||||
254..264 '[a, ["b"]]': [[&str; _]; _]
|
254..264 '[a, ["b"]]': [[&str; 1]; 2]
|
||||||
255..256 'a': [&str; _]
|
255..256 'a': [&str; 1]
|
||||||
258..263 '["b"]': [&str; _]
|
258..263 '["b"]': [&str; 1]
|
||||||
259..262 '"b"': &str
|
259..262 '"b"': &str
|
||||||
274..275 'x': [u8; _]
|
274..275 'x': [u8; _]
|
||||||
287..289 '[]': [u8; _]
|
287..289 '[]': [u8; 0]
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2429,20 +2429,20 @@ fn infer_operator_overload() {
|
||||||
394..395 '1': i32
|
394..395 '1': i32
|
||||||
406..408 'V2': V2([f32; _]) -> V2
|
406..408 'V2': V2([f32; _]) -> V2
|
||||||
406..416 'V2([x, y])': V2
|
406..416 'V2([x, y])': V2
|
||||||
409..415 '[x, y]': [f32; _]
|
409..415 '[x, y]': [f32; 2]
|
||||||
410..411 'x': f32
|
410..411 'x': f32
|
||||||
413..414 'y': f32
|
413..414 'y': f32
|
||||||
436..519 '{ ... vb; }': ()
|
436..519 '{ ... vb; }': ()
|
||||||
446..448 'va': V2
|
446..448 'va': V2
|
||||||
451..453 'V2': V2([f32; _]) -> V2
|
451..453 'V2': V2([f32; _]) -> V2
|
||||||
451..465 'V2([0.0, 1.0])': V2
|
451..465 'V2([0.0, 1.0])': V2
|
||||||
454..464 '[0.0, 1.0]': [f32; _]
|
454..464 '[0.0, 1.0]': [f32; 2]
|
||||||
455..458 '0.0': f32
|
455..458 '0.0': f32
|
||||||
460..463 '1.0': f32
|
460..463 '1.0': f32
|
||||||
475..477 'vb': V2
|
475..477 'vb': V2
|
||||||
480..482 'V2': V2([f32; _]) -> V2
|
480..482 'V2': V2([f32; _]) -> V2
|
||||||
480..494 'V2([0.0, 1.0])': V2
|
480..494 'V2([0.0, 1.0])': V2
|
||||||
483..493 '[0.0, 1.0]': [f32; _]
|
483..493 '[0.0, 1.0]': [f32; 2]
|
||||||
484..487 '0.0': f32
|
484..487 '0.0': f32
|
||||||
489..492 '1.0': f32
|
489..492 '1.0': f32
|
||||||
505..506 'r': V2
|
505..506 'r': V2
|
||||||
|
@ -2593,8 +2593,8 @@ fn test() {
|
||||||
658..661 'vec': Vec<i32, Global>
|
658..661 'vec': Vec<i32, Global>
|
||||||
664..679 '<[_]>::into_vec': fn into_vec<i32, Global>(Box<[i32], Global>) -> Vec<i32, Global>
|
664..679 '<[_]>::into_vec': fn into_vec<i32, Global>(Box<[i32], Global>) -> Vec<i32, Global>
|
||||||
664..691 '<[_]>:...1i32])': Vec<i32, Global>
|
664..691 '<[_]>:...1i32])': Vec<i32, Global>
|
||||||
680..690 'box [1i32]': Box<[i32; _], Global>
|
680..690 'box [1i32]': Box<[i32; 1], Global>
|
||||||
684..690 '[1i32]': [i32; _]
|
684..690 '[1i32]': [i32; 1]
|
||||||
685..689 '1i32': i32
|
685..689 '1i32': i32
|
||||||
"#]],
|
"#]],
|
||||||
)
|
)
|
||||||
|
|
|
@ -531,7 +531,7 @@ fn indexing_arrays() {
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
10..26 '{ &mut...[2]; }': ()
|
10..26 '{ &mut...[2]; }': ()
|
||||||
12..23 '&mut [9][2]': &mut {unknown}
|
12..23 '&mut [9][2]': &mut {unknown}
|
||||||
17..20 '[9]': [i32; _]
|
17..20 '[9]': [i32; 1]
|
||||||
17..23 '[9][2]': {unknown}
|
17..23 '[9][2]': {unknown}
|
||||||
18..19 '9': i32
|
18..19 '9': i32
|
||||||
21..22 '2': i32
|
21..22 '2': i32
|
||||||
|
|
|
@ -1126,7 +1126,7 @@ fn main() {
|
||||||
r#"
|
r#"
|
||||||
fn main() {
|
fn main() {
|
||||||
let data = &[1i32, 2, 3];
|
let data = &[1i32, 2, 3];
|
||||||
//^^^^ &[i32; _]
|
//^^^^ &[i32; 3]
|
||||||
for i
|
for i
|
||||||
}"#,
|
}"#,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue