From dc63fea427280ff278bf89a8b9c78df606009910 Mon Sep 17 00:00:00 2001 From: Jade Date: Tue, 11 May 2021 05:06:33 -0700 Subject: Add basic support for array lengths in types 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? --- crates/hir_ty/src/consts.rs | 20 ++++++++ crates/hir_ty/src/display.rs | 2 +- crates/hir_ty/src/infer/expr.rs | 26 +++++++--- crates/hir_ty/src/interner.rs | 16 +++++-- crates/hir_ty/src/lib.rs | 7 ++- crates/hir_ty/src/lower.rs | 2 + crates/hir_ty/src/tests/coercion.rs | 90 +++++++++++++++++------------------ crates/hir_ty/src/tests/patterns.rs | 6 +-- crates/hir_ty/src/tests/regression.rs | 12 ++--- crates/hir_ty/src/tests/simple.rs | 80 +++++++++++++++---------------- crates/hir_ty/src/tests/traits.rs | 2 +- crates/ide/src/inlay_hints.rs | 2 +- 12 files changed, 155 insertions(+), 110 deletions(-) create mode 100644 crates/hir_ty/src/consts.rs (limited to 'crates') diff --git a/crates/hir_ty/src/consts.rs b/crates/hir_ty/src/consts.rs new file mode 100644 index 000000000..77d2a7a05 --- /dev/null +++ b/crates/hir_ty/src/consts.rs @@ -0,0 +1,20 @@ +//! 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 + Usize(usize), + + /// 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, "_"), + } + } +} diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 1f6edf7a2..8a4296697 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -308,7 +308,7 @@ impl HirDisplay for Const { let param_data = &generics.params.consts[id.local_id]; write!(f, "{}", param_data.name) } - ConstValue::Concrete(_) => write!(f, "_"), + ConstValue::Concrete(c) => write!(f, "{}", c.interned), } } } diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 50497eecb..9aec8a236 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs @@ -3,7 +3,7 @@ use std::iter::{repeat, repeat_with}; 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::{ expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, path::{GenericArg, GenericArgs}, @@ -15,7 +15,9 @@ use stdx::always; use syntax::ast::RangeOp; use crate::{ - autoderef, dummy_usize_const, + autoderef, + consts::ConstScalar, + dummy_usize_const, lower::lower_to_chalk_mutability, mapping::from_chalk, method_resolution, op, @@ -23,7 +25,7 @@ use crate::{ static_lifetime, to_chalk_trait_id, traits::FnTrait, 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, }; @@ -717,11 +719,12 @@ impl<'a> InferenceContext<'a> { _ => self.table.new_type_var(), }; - match array { + let len = match array { Array::ElementList(items) => { for expr in items.iter() { self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone())); } + Some(items.len()) } Array::Repeat { initializer, repeat } => { self.infer_expr_coerce( @@ -734,10 +737,20 @@ impl<'a> InferenceContext<'a> { 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)) + .unwrap_or(ConstScalar::Unknown), + }), + }; + TyKind::Array(elem_ty, cd.intern(&Interner)).intern(&Interner) } Expr::Literal(lit) => match lit { Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), @@ -747,6 +760,7 @@ impl<'a> InferenceContext<'a> { } Literal::ByteString(..) => { let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); + let array_type = TyKind::Array(byte_type, dummy_usize_const()).intern(&Interner); TyKind::Ref(Mutability::Not, static_lifetime(), array_type).intern(&Interner) diff --git a/crates/hir_ty/src/interner.rs b/crates/hir_ty/src/interner.rs index a1656115d..4cbc9cd4f 100644 --- a/crates/hir_ty/src/interner.rs +++ b/crates/hir_ty/src/interner.rs @@ -1,7 +1,7 @@ //! Implementation of the Chalk `Interner` trait, which allows customizing the //! 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 chalk_ir::{Goal, GoalData}; use hir_def::{ @@ -31,6 +31,7 @@ impl_internable!( InternedWrapper>, InternedWrapper>, InternedWrapper>, + InternedWrapper, InternedWrapper>>, InternedWrapper>>, InternedWrapper>>, @@ -41,7 +42,7 @@ impl chalk_ir::interner::Interner for Interner { type InternedType = Interned>>; type InternedLifetime = Interned>>; type InternedConst = Interned>>; - type InternedConcreteConst = (); + type InternedConcreteConst = ConstScalar; type InternedGenericArg = chalk_ir::GenericArgData; type InternedGoal = Arc>; type InternedGoals = Vec>; @@ -245,10 +246,15 @@ impl chalk_ir::interner::Interner for Interner { fn const_eq( &self, _ty: &Self::InternedType, - _c1: &Self::InternedConcreteConst, - _c2: &Self::InternedConcreteConst, + c1: &Self::InternedConcreteConst, + c2: &Self::InternedConcreteConst, ) -> 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( diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 0505fa4ae..d23eff513 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -12,6 +12,7 @@ mod chalk_db; mod chalk_ext; mod infer; mod interner; +mod consts; mod lower; mod mapping; mod op; @@ -39,7 +40,7 @@ use chalk_ir::{ }; 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 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); chalk_ir::ConstData { 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) } diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index c99dd8d0a..9751b45e4 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -174,6 +174,8 @@ impl<'a> TyLoweringContext<'a> { } TypeRef::Array(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) } TypeRef::Slice(inner) => { diff --git a/crates/hir_ty/src/tests/coercion.rs b/crates/hir_ty/src/tests/coercion.rs index 63d9d4e0b..aad3d610e 100644 --- a/crates/hir_ty/src/tests/coercion.rs +++ b/crates/hir_ty/src/tests/coercion.rs @@ -55,7 +55,7 @@ fn coerce_places() { impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} "#, - expect![[r" + expect![[r#" 30..31 '_': &[T] 44..55 '{ loop {} }': T 46..53 'loop {}': ! @@ -72,8 +72,8 @@ fn coerce_places() { 165..170 'gen()': *mut [U; _] 185..419 '{ ...rr); }': () 195..198 'arr': &[u8; _] - 211..215 '&[1]': &[u8; _] - 212..215 '[1]': [u8; _] + 211..215 '&[1]': &[u8; 1] + 212..215 '[1]': [u8; 1] 213..214 '1': u8 226..227 'a': &[u8] 236..239 'arr': &[u8; _] @@ -90,7 +90,7 @@ fn coerce_places() { 302..314 'S { a: arr }': S<&[u8]> 309..312 'arr': &[u8; _] 325..326 'e': [&[u8]; _] - 340..345 '[arr]': [&[u8]; _] + 340..345 '[arr]': [&[u8]; 1] 341..344 'arr': &[u8; _] 355..356 'f': [&[u8]; _] 370..378 '[arr; 2]': [&[u8]; _] @@ -100,7 +100,7 @@ fn coerce_places() { 406..416 '(arr, arr)': (&[u8], &[u8]) 407..410 'arr': &[u8; _] 412..415 'arr': &[u8; _] - "]], + "#]], ); } @@ -113,17 +113,17 @@ fn infer_let_stmt_coerce() { let x: *const [isize] = &[1]; } ", - expect![[r" + expect![[r#" 10..75 '{ ...[1]; }': () 20..21 'x': &[isize] - 34..38 '&[1]': &[isize; _] - 35..38 '[1]': [isize; _] + 34..38 '&[1]': &[isize; 1] + 35..38 '[1]': [isize; 1] 36..37 '1': isize 48..49 'x': *const [isize] - 68..72 '&[1]': &[isize; _] - 69..72 '[1]': [isize; _] + 68..72 '&[1]': &[isize; 1] + 69..72 '[1]': [isize; 1] 70..71 '1': isize - "]], + "#]], ); } @@ -208,7 +208,7 @@ fn infer_if_coerce() { #[lang = "unsize"] pub trait Unsize {} "#, - expect![[r" + expect![[r#" 10..11 'x': &[T] 27..38 '{ loop {} }': &[T] 29..36 'loop {}': ! @@ -220,14 +220,14 @@ fn infer_if_coerce() { 71..96 '{ ... }': &[i32] 81..84 'foo': fn foo(&[i32]) -> &[i32] 81..90 'foo(&[1])': &[i32] - 85..89 '&[1]': &[i32; _] - 86..89 '[1]': [i32; _] + 85..89 '&[1]': &[i32; 1] + 86..89 '[1]': [i32; 1] 87..88 '1': i32 - 102..122 '{ ... }': &[i32; _] - 112..116 '&[1]': &[i32; _] - 113..116 '[1]': [i32; _] + 102..122 '{ ... }': &[i32; 1] + 112..116 '&[1]': &[i32; 1] + 113..116 '[1]': [i32; 1] 114..115 '1': i32 - "]], + "#]], ); } @@ -254,7 +254,7 @@ fn infer_if_else_coerce() { impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} "#, - expect![[r" + expect![[r#" 10..11 'x': &[T] 27..38 '{ loop {} }': &[T] 29..36 'loop {}': ! @@ -263,17 +263,17 @@ fn infer_if_else_coerce() { 59..60 'x': &[i32] 63..122 'if tru... }': &[i32] 66..70 'true': bool - 71..91 '{ ... }': &[i32; _] - 81..85 '&[1]': &[i32; _] - 82..85 '[1]': [i32; _] + 71..91 '{ ... }': &[i32; 1] + 81..85 '&[1]': &[i32; 1] + 82..85 '[1]': [i32; 1] 83..84 '1': i32 97..122 '{ ... }': &[i32] 107..110 'foo': fn foo(&[i32]) -> &[i32] 107..116 'foo(&[1])': &[i32] - 111..115 '&[1]': &[i32; _] - 112..115 '[1]': [i32; _] + 111..115 '&[1]': &[i32; 1] + 112..115 '[1]': [i32; 1] 113..114 '1': i32 - "]], + "#]], ) } @@ -295,7 +295,7 @@ fn infer_match_first_coerce() { #[lang = "unsize"] pub trait Unsize {} "#, - expect![[r" + expect![[r#" 10..11 'x': &[T] 27..38 '{ loop {} }': &[T] 29..36 'loop {}': ! @@ -309,19 +309,19 @@ fn infer_match_first_coerce() { 87..88 '2': i32 92..95 'foo': fn foo(&[i32]) -> &[i32] 92..101 'foo(&[2])': &[i32] - 96..100 '&[2]': &[i32; _] - 97..100 '[2]': [i32; _] + 96..100 '&[2]': &[i32; 1] + 97..100 '[2]': [i32; 1] 98..99 '2': i32 111..112 '1': i32 111..112 '1': i32 - 116..120 '&[1]': &[i32; _] - 117..120 '[1]': [i32; _] + 116..120 '&[1]': &[i32; 1] + 117..120 '[1]': [i32; 1] 118..119 '1': i32 130..131 '_': i32 - 135..139 '&[3]': &[i32; _] - 136..139 '[3]': [i32; _] + 135..139 '&[3]': &[i32; 1] + 136..139 '[3]': [i32; 1] 137..138 '3': i32 - "]], + "#]], ); } @@ -348,7 +348,7 @@ fn infer_match_second_coerce() { impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} impl, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} "#, - expect![[r" + expect![[r#" 10..11 'x': &[T] 27..38 '{ loop {} }': &[T] 29..36 'loop {}': ! @@ -360,21 +360,21 @@ fn infer_match_second_coerce() { 75..76 'i': i32 87..88 '1': i32 87..88 '1': i32 - 92..96 '&[1]': &[i32; _] - 93..96 '[1]': [i32; _] + 92..96 '&[1]': &[i32; 1] + 93..96 '[1]': [i32; 1] 94..95 '1': i32 106..107 '2': i32 106..107 '2': i32 111..114 'foo': fn foo(&[i32]) -> &[i32] 111..120 'foo(&[2])': &[i32] - 115..119 '&[2]': &[i32; _] - 116..119 '[2]': [i32; _] + 115..119 '&[2]': &[i32; 1] + 116..119 '[2]': [i32; 1] 117..118 '2': i32 130..131 '_': i32 - 135..139 '&[3]': &[i32; _] - 136..139 '[3]': [i32; _] + 135..139 '&[3]': &[i32; 1] + 136..139 '[3]': [i32; 1] 137..138 '3': i32 - "]], + "#]], ); } @@ -685,15 +685,15 @@ fn coerce_unsize_array() { let f: &[usize] = &[1, 2, 3]; } "#, - expect![[r" + expect![[r#" 161..198 '{ ... 3]; }': () 171..172 'f': &[usize] - 185..195 '&[1, 2, 3]': &[usize; _] - 186..195 '[1, 2, 3]': [usize; _] + 185..195 '&[1, 2, 3]': &[usize; 3] + 186..195 '[1, 2, 3]': [usize; 3] 187..188 '1': usize 190..191 '2': usize 193..194 '3': usize - "]], + "#]], ); } diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs index f514b3efe..33305f208 100644 --- a/crates/hir_ty/src/tests/patterns.rs +++ b/crates/hir_ty/src/tests/patterns.rs @@ -243,8 +243,8 @@ fn infer_pattern_match_slice() { expect![[r#" 10..209 '{ ... } }': () 20..25 'slice': &[f64] - 36..42 '&[0.0]': &[f64; _] - 37..42 '[0.0]': [f64; _] + 36..42 '&[0.0]': &[f64; 1] + 37..42 '[0.0]': [f64; 1] 38..41 '0.0': f64 48..207 'match ... }': () 54..59 'slice': &[f64] @@ -346,7 +346,7 @@ fn infer_pattern_match_arr() { expect![[r#" 10..179 '{ ... } }': () 20..23 'arr': [f64; _] - 36..46 '[0.0, 1.0]': [f64; _] + 36..46 '[0.0, 1.0]': [f64; 2] 37..40 '0.0': f64 42..45 '1.0': f64 52..177 'match ... }': () diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs index d14f5c9bb..769809edf 100644 --- a/crates/hir_ty/src/tests/regression.rs +++ b/crates/hir_ty/src/tests/regression.rs @@ -99,7 +99,7 @@ fn recursive_vars() { 10..47 '{ ...&y]; }': () 20..21 'y': &{unknown} 24..31 'unknown': &{unknown} - 37..44 '[y, &y]': [&&{unknown}; _] + 37..44 '[y, &y]': [&&{unknown}; 2] 38..39 'y': &{unknown} 41..43 '&y': &&{unknown} 42..43 'y': &{unknown} @@ -123,7 +123,7 @@ fn recursive_vars_2() { 24..31 'unknown': &&{unknown} 41..42 'y': &&{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}) 60..61 'x': &&{unknown} 63..64 'y': &&{unknown} @@ -175,8 +175,8 @@ fn infer_std_crash_2() { "#, expect![[r#" 22..52 '{ ...n']; }': () - 28..49 '&[0, b...b'\n']': &[u8; _] - 29..49 '[0, b'...b'\n']': [u8; _] + 28..49 '&[0, b...b'\n']': &[u8; 4] + 29..49 '[0, b'...b'\n']': [u8; 4] 30..31 '0': u8 33..38 'b'\n'': u8 40..41 '1': u8 @@ -336,8 +336,8 @@ fn infer_array_macro_call() { expect![[r#" !0..4 '0u32': u32 44..69 '{ ...()]; }': () - 54..55 'a': [u32; _] - 58..66 '[bar!()]': [u32; _] + 54..55 'a': [u32; 1] + 58..66 '[bar!()]': [u32; 1] "#]], ); } diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs index 0eefd70f2..8b09f2e4a 100644 --- a/crates/hir_ty/src/tests/simple.rs +++ b/crates/hir_ty/src/tests/simple.rs @@ -11,7 +11,7 @@ fn test() { let x = box 1; let t = (x, box x, box &1, box [1]); t; -} //^ (Box, Box>, Box<&i32>, Box<[i32; _]>) +} //^ (Box, Box>, Box<&i32>, Box<[i32; 1]>) //- /std.rs crate:std #[prelude_import] use prelude::*; @@ -36,7 +36,7 @@ fn test() { let x = box 1; let t = (x, box x, box &1, box [1]); t; -} //^ (Box, Box, {unknown}>, Box<&i32, {unknown}>, Box<[i32; _], {unknown}>) +} //^ (Box, Box, {unknown}>, Box<&i32, {unknown}>, Box<[i32; 1], {unknown}>) //- /std.rs crate:std #[prelude_import] use prelude::*; @@ -1266,55 +1266,55 @@ fn infer_array() { 8..9 'x': &str 17..18 'y': isize 27..292 '{ ... []; }': () - 37..38 'a': [&str; _] - 41..44 '[x]': [&str; _] + 37..38 'a': [&str; 1] + 41..44 '[x]': [&str; 1] 42..43 'x': &str - 54..55 'b': [[&str; _]; _] - 58..64 '[a, a]': [[&str; _]; _] - 59..60 'a': [&str; _] - 62..63 'a': [&str; _] - 74..75 'c': [[[&str; _]; _]; _] - 78..84 '[b, b]': [[[&str; _]; _]; _] - 79..80 'b': [[&str; _]; _] - 82..83 'b': [[&str; _]; _] - 95..96 'd': [isize; _] - 99..111 '[y, 1, 2, 3]': [isize; _] + 54..55 'b': [[&str; 1]; 2] + 58..64 '[a, a]': [[&str; 1]; 2] + 59..60 'a': [&str; 1] + 62..63 'a': [&str; 1] + 74..75 'c': [[[&str; 1]; 2]; 2] + 78..84 '[b, b]': [[[&str; 1]; 2]; 2] + 79..80 'b': [[&str; 1]; 2] + 82..83 'b': [[&str; 1]; 2] + 95..96 'd': [isize; 4] + 99..111 '[y, 1, 2, 3]': [isize; 4] 100..101 'y': isize 103..104 '1': isize 106..107 '2': isize 109..110 '3': isize - 121..122 'd': [isize; _] - 125..137 '[1, y, 2, 3]': [isize; _] + 121..122 'd': [isize; 4] + 125..137 '[1, y, 2, 3]': [isize; 4] 126..127 '1': isize 129..130 'y': isize 132..133 '2': isize 135..136 '3': isize - 147..148 'e': [isize; _] - 151..154 '[y]': [isize; _] + 147..148 'e': [isize; 1] + 151..154 '[y]': [isize; 1] 152..153 'y': isize - 164..165 'f': [[isize; _]; _] - 168..174 '[d, d]': [[isize; _]; _] - 169..170 'd': [isize; _] - 172..173 'd': [isize; _] - 184..185 'g': [[isize; _]; _] - 188..194 '[e, e]': [[isize; _]; _] - 189..190 'e': [isize; _] - 192..193 'e': [isize; _] - 205..206 'h': [i32; _] - 209..215 '[1, 2]': [i32; _] + 164..165 'f': [[isize; 4]; 2] + 168..174 '[d, d]': [[isize; 4]; 2] + 169..170 'd': [isize; 4] + 172..173 'd': [isize; 4] + 184..185 'g': [[isize; 1]; 2] + 188..194 '[e, e]': [[isize; 1]; 2] + 189..190 'e': [isize; 1] + 192..193 'e': [isize; 1] + 205..206 'h': [i32; 2] + 209..215 '[1, 2]': [i32; 2] 210..211 '1': i32 213..214 '2': i32 - 225..226 'i': [&str; _] - 229..239 '["a", "b"]': [&str; _] + 225..226 'i': [&str; 2] + 229..239 '["a", "b"]': [&str; 2] 230..233 '"a"': &str 235..238 '"b"': &str - 250..251 'b': [[&str; _]; _] - 254..264 '[a, ["b"]]': [[&str; _]; _] - 255..256 'a': [&str; _] - 258..263 '["b"]': [&str; _] + 250..251 'b': [[&str; 1]; 2] + 254..264 '[a, ["b"]]': [[&str; 1]; 2] + 255..256 'a': [&str; 1] + 258..263 '["b"]': [&str; 1] 259..262 '"b"': &str 274..275 'x': [u8; _] - 287..289 '[]': [u8; _] + 287..289 '[]': [u8; 0] "#]], ); } @@ -2429,20 +2429,20 @@ fn infer_operator_overload() { 394..395 '1': i32 406..408 'V2': V2([f32; _]) -> V2 406..416 'V2([x, y])': V2 - 409..415 '[x, y]': [f32; _] + 409..415 '[x, y]': [f32; 2] 410..411 'x': f32 413..414 'y': f32 436..519 '{ ... vb; }': () 446..448 'va': V2 451..453 'V2': V2([f32; _]) -> 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 460..463 '1.0': f32 475..477 'vb': V2 480..482 'V2': V2([f32; _]) -> 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 489..492 '1.0': f32 505..506 'r': V2 @@ -2593,8 +2593,8 @@ fn test() { 658..661 'vec': Vec 664..679 '<[_]>::into_vec': fn into_vec(Box<[i32], Global>) -> Vec 664..691 '<[_]>:...1i32])': Vec - 680..690 'box [1i32]': Box<[i32; _], Global> - 684..690 '[1i32]': [i32; _] + 680..690 'box [1i32]': Box<[i32; 1], Global> + 684..690 '[1i32]': [i32; 1] 685..689 '1i32': i32 "#]], ) diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index ffc7c8ef4..47a1455fd 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs @@ -531,7 +531,7 @@ fn indexing_arrays() { expect![[r#" 10..26 '{ &mut...[2]; }': () 12..23 '&mut [9][2]': &mut {unknown} - 17..20 '[9]': [i32; _] + 17..20 '[9]': [i32; 1] 17..23 '[9][2]': {unknown} 18..19 '9': i32 21..22 '2': i32 diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index e0bf660c4..960d169f4 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -1126,7 +1126,7 @@ fn main() { r#" fn main() { let data = &[1i32, 2, 3]; - //^^^^ &[i32; _] + //^^^^ &[i32; 3] for i }"#, ); -- cgit v1.2.3