Skip to content

Commit 1e2178e

Browse files
bors[bot]Lapz
andcommitted
Merge #1103
1103: Array inference r=flodiebold a=Lapz Fixes the final item in #394. The only problem is that infering the repeat cause some types to be infered twices. i.e ```rust fn test() { let y = unknown; [y, &y]; } ``` results in the following diff: ```diff [11; 48) '{ ...&y]; }': () [21; 22) 'y': &{unknown} [25; 32) 'unknown': &{unknown} -[38; 45) '[y, &y]': [&&{unknown}] +[38; 45) '[y, &y]': [&&{unknown};usize] [39; 40) 'y': &{unknown} +[39; 40) 'y': &{unknown} [42; 44) '&y': &&{unknown} [43; 44) 'y': &{unknown} ``` Should the code produce two inference results for 'y' and if not could any tell me what needs to change. Co-authored-by: Lenard Pratt <l3np27@gmail.com>
2 parents 36f5d99 + b27fa33 commit 1e2178e

File tree

6 files changed

+124
-55
lines changed

6 files changed

+124
-55
lines changed

crates/ra_hir/src/expr.rs

+37-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_hash::FxHashMap;
66
use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
77
use ra_syntax::{
88
SyntaxNodePtr, AstPtr, AstNode,
9-
ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralKind, TypeAscriptionOwner}
9+
ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralKind,ArrayExprKind, TypeAscriptionOwner}
1010
};
1111

1212
use crate::{
@@ -238,14 +238,17 @@ pub enum Expr {
238238
Tuple {
239239
exprs: Vec<ExprId>,
240240
},
241-
Array {
242-
exprs: Vec<ExprId>,
243-
},
241+
Array(Array),
244242
Literal(Literal),
245243
}
246244

247245
pub use ra_syntax::ast::PrefixOp as UnaryOp;
248246
pub use ra_syntax::ast::BinOp as BinaryOp;
247+
#[derive(Debug, Clone, Eq, PartialEq)]
248+
pub enum Array {
249+
ElementList(Vec<ExprId>),
250+
Repeat { initializer: ExprId, repeat: ExprId },
251+
}
249252

250253
#[derive(Debug, Clone, Eq, PartialEq)]
251254
pub struct MatchArm {
@@ -348,11 +351,22 @@ impl Expr {
348351
| Expr::UnaryOp { expr, .. } => {
349352
f(*expr);
350353
}
351-
Expr::Tuple { exprs } | Expr::Array { exprs } => {
354+
Expr::Tuple { exprs } => {
352355
for expr in exprs {
353356
f(*expr);
354357
}
355358
}
359+
Expr::Array(a) => match a {
360+
Array::ElementList(exprs) => {
361+
for expr in exprs {
362+
f(*expr);
363+
}
364+
}
365+
Array::Repeat { initializer, repeat } => {
366+
f(*initializer);
367+
f(*repeat)
368+
}
369+
},
356370
Expr::Literal(_) => {}
357371
}
358372
}
@@ -723,10 +737,26 @@ impl ExprCollector {
723737
let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect();
724738
self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr)
725739
}
740+
726741
ast::ExprKind::ArrayExpr(e) => {
727-
let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect();
728-
self.alloc_expr(Expr::Array { exprs }, syntax_ptr)
742+
let kind = e.kind();
743+
744+
match kind {
745+
ArrayExprKind::ElementList(e) => {
746+
let exprs = e.map(|expr| self.collect_expr(expr)).collect();
747+
self.alloc_expr(Expr::Array(Array::ElementList(exprs)), syntax_ptr)
748+
}
749+
ArrayExprKind::Repeat { initializer, repeat } => {
750+
let initializer = self.collect_expr_opt(initializer);
751+
let repeat = self.collect_expr_opt(repeat);
752+
self.alloc_expr(
753+
Expr::Array(Array::Repeat { initializer, repeat }),
754+
syntax_ptr,
755+
)
756+
}
757+
}
729758
}
759+
730760
ast::ExprKind::Literal(e) => {
731761
let lit = match e.kind() {
732762
LiteralKind::IntNumber { suffix } => {

crates/ra_hir/src/ty.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -353,10 +353,14 @@ impl HirDisplay for ApplicationTy {
353353
TypeCtor::Int(t) => write!(f, "{}", t)?,
354354
TypeCtor::Float(t) => write!(f, "{}", t)?,
355355
TypeCtor::Str => write!(f, "str")?,
356-
TypeCtor::Slice | TypeCtor::Array => {
356+
TypeCtor::Slice => {
357357
let t = self.parameters.as_single();
358358
write!(f, "[{}]", t.display(f.db))?;
359359
}
360+
TypeCtor::Array => {
361+
let t = self.parameters.as_single();
362+
write!(f, "[{};_]", t.display(f.db))?;
363+
}
360364
TypeCtor::RawPtr(m) => {
361365
let t = self.parameters.as_single();
362366
write!(f, "*{}{}", m.as_keyword_for_ptr(), t.display(f.db))?;

crates/ra_hir/src/ty/infer.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use crate::{
3232
DefWithBody,
3333
ImplItem,
3434
type_ref::{TypeRef, Mutability},
35-
expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self},
35+
expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat,Array, self},
3636
generics::GenericParams,
3737
path::{GenericArgs, GenericArg},
3838
adt::VariantDef,
@@ -1074,7 +1074,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
10741074

10751075
Ty::apply(TypeCtor::Tuple, Substs(ty_vec.into()))
10761076
}
1077-
Expr::Array { exprs } => {
1077+
Expr::Array(array) => {
10781078
let elem_ty = match &expected.ty {
10791079
Ty::Apply(a_ty) => match a_ty.ctor {
10801080
TypeCtor::Slice | TypeCtor::Array => {
@@ -1085,8 +1085,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
10851085
_ => self.new_type_var(),
10861086
};
10871087

1088-
for expr in exprs.iter() {
1089-
self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone()));
1088+
match array {
1089+
Array::ElementList(items) => {
1090+
for expr in items.iter() {
1091+
self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone()));
1092+
}
1093+
}
1094+
Array::Repeat { initializer, repeat } => {
1095+
self.infer_expr(*initializer, &Expectation::has_type(elem_ty.clone()));
1096+
self.infer_expr(
1097+
*repeat,
1098+
&Expectation::has_type(Ty::simple(TypeCtor::Int(
1099+
primitive::UncertainIntTy::Known(primitive::IntTy::usize()),
1100+
))),
1101+
);
1102+
}
10901103
}
10911104

10921105
Ty::apply_one(TypeCtor::Array, elem_ty)

crates/ra_hir/src/ty/tests.rs

+41-41
Original file line numberDiff line numberDiff line change
@@ -697,58 +697,58 @@ fn test(x: &str, y: isize) {
697697
[9; 10) 'x': &str
698698
[18; 19) 'y': isize
699699
[28; 324) '{ ... 3]; }': ()
700-
[38; 39) 'a': [&str]
701-
[42; 45) '[x]': [&str]
700+
[38; 39) 'a': [&str;_]
701+
[42; 45) '[x]': [&str;_]
702702
[43; 44) 'x': &str
703-
[55; 56) 'b': [[&str]]
704-
[59; 65) '[a, a]': [[&str]]
705-
[60; 61) 'a': [&str]
706-
[63; 64) 'a': [&str]
707-
[75; 76) 'c': [[[&str]]]
708-
[79; 85) '[b, b]': [[[&str]]]
709-
[80; 81) 'b': [[&str]]
710-
[83; 84) 'b': [[&str]]
711-
[96; 97) 'd': [isize]
712-
[100; 112) '[y, 1, 2, 3]': [isize]
703+
[55; 56) 'b': [[&str;_];_]
704+
[59; 65) '[a, a]': [[&str;_];_]
705+
[60; 61) 'a': [&str;_]
706+
[63; 64) 'a': [&str;_]
707+
[75; 76) 'c': [[[&str;_];_];_]
708+
[79; 85) '[b, b]': [[[&str;_];_];_]
709+
[80; 81) 'b': [[&str;_];_]
710+
[83; 84) 'b': [[&str;_];_]
711+
[96; 97) 'd': [isize;_]
712+
[100; 112) '[y, 1, 2, 3]': [isize;_]
713713
[101; 102) 'y': isize
714714
[104; 105) '1': isize
715715
[107; 108) '2': isize
716716
[110; 111) '3': isize
717-
[122; 123) 'd': [isize]
718-
[126; 138) '[1, y, 2, 3]': [isize]
717+
[122; 123) 'd': [isize;_]
718+
[126; 138) '[1, y, 2, 3]': [isize;_]
719719
[127; 128) '1': isize
720720
[130; 131) 'y': isize
721721
[133; 134) '2': isize
722722
[136; 137) '3': isize
723-
[148; 149) 'e': [isize]
724-
[152; 155) '[y]': [isize]
723+
[148; 149) 'e': [isize;_]
724+
[152; 155) '[y]': [isize;_]
725725
[153; 154) 'y': isize
726-
[165; 166) 'f': [[isize]]
727-
[169; 175) '[d, d]': [[isize]]
728-
[170; 171) 'd': [isize]
729-
[173; 174) 'd': [isize]
730-
[185; 186) 'g': [[isize]]
731-
[189; 195) '[e, e]': [[isize]]
732-
[190; 191) 'e': [isize]
733-
[193; 194) 'e': [isize]
734-
[206; 207) 'h': [i32]
735-
[210; 216) '[1, 2]': [i32]
726+
[165; 166) 'f': [[isize;_];_]
727+
[169; 175) '[d, d]': [[isize;_];_]
728+
[170; 171) 'd': [isize;_]
729+
[173; 174) 'd': [isize;_]
730+
[185; 186) 'g': [[isize;_];_]
731+
[189; 195) '[e, e]': [[isize;_];_]
732+
[190; 191) 'e': [isize;_]
733+
[193; 194) 'e': [isize;_]
734+
[206; 207) 'h': [i32;_]
735+
[210; 216) '[1, 2]': [i32;_]
736736
[211; 212) '1': i32
737737
[214; 215) '2': i32
738-
[226; 227) 'i': [&str]
739-
[230; 240) '["a", "b"]': [&str]
738+
[226; 227) 'i': [&str;_]
739+
[230; 240) '["a", "b"]': [&str;_]
740740
[231; 234) '"a"': &str
741741
[236; 239) '"b"': &str
742-
[251; 252) 'b': [[&str]]
743-
[255; 265) '[a, ["b"]]': [[&str]]
744-
[256; 257) 'a': [&str]
745-
[259; 264) '["b"]': [&str]
742+
[251; 252) 'b': [[&str;_];_]
743+
[255; 265) '[a, ["b"]]': [[&str;_];_]
744+
[256; 257) 'a': [&str;_]
745+
[259; 264) '["b"]': [&str;_]
746746
[260; 263) '"b"': &str
747-
[275; 276) 'x': [u8]
748-
[288; 290) '[]': [u8]
749-
[300; 301) 'z': &[u8]
750-
[311; 321) '&[1, 2, 3]': &[u8]
751-
[312; 321) '[1, 2, 3]': [u8]
747+
[275; 276) 'x': [u8;_]
748+
[288; 290) '[]': [u8;_]
749+
[300; 301) 'z': &[u8;_]
750+
[311; 321) '&[1, 2, 3]': &[u8;_]
751+
[312; 321) '[1, 2, 3]': [u8;_]
752752
[313; 314) '1': u8
753753
[316; 317) '2': u8
754754
[319; 320) '3': u8"###
@@ -1553,7 +1553,7 @@ fn test() {
15531553
[11; 48) '{ ...&y]; }': ()
15541554
[21; 22) 'y': &{unknown}
15551555
[25; 32) 'unknown': &{unknown}
1556-
[38; 45) '[y, &y]': [&&{unknown}]
1556+
[38; 45) '[y, &y]': [&&{unknown};_]
15571557
[39; 40) 'y': &{unknown}
15581558
[42; 44) '&y': &&{unknown}
15591559
[43; 44) 'y': &{unknown}"###
@@ -1578,7 +1578,7 @@ fn test() {
15781578
[25; 32) 'unknown': &&{unknown}
15791579
[42; 43) 'y': &&{unknown}
15801580
[46; 53) 'unknown': &&{unknown}
1581-
[59; 77) '[(x, y..., &x)]': [(&&{unknown}, &&{unknown})]
1581+
[59; 77) '[(x, y..., &x)]': [(&&{unknown}, &&{unknown});_]
15821582
[60; 66) '(x, y)': (&&{unknown}, &&{unknown})
15831583
[61; 62) 'x': &&{unknown}
15841584
[64; 65) 'y': &&{unknown}
@@ -1670,8 +1670,8 @@ fn test_line_buffer() {
16701670
"#),
16711671
@r###"
16721672
[23; 53) '{ ...n']; }': ()
1673-
[29; 50) '&[0, b...b'\n']': &[u8]
1674-
[30; 50) '[0, b'...b'\n']': [u8]
1673+
[29; 50) '&[0, b...b'\n']': &[u8;_]
1674+
[30; 50) '[0, b'...b'\n']': [u8;_]
16751675
[31; 32) '0': u8
16761676
[34; 39) 'b'\n'': u8
16771677
[41; 42) '1': u8

crates/ra_syntax/src/ast.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ pub use self::{
1717
generated::*,
1818
traits::*,
1919
tokens::*,
20-
extensions::{PathSegmentKind, StructKind, FieldKind, SelfParamKind},
21-
expr_extensions::{ElseBranch, PrefixOp, BinOp, LiteralKind},
20+
extensions::{PathSegmentKind, StructKind,FieldKind, SelfParamKind},
21+
expr_extensions::{ElseBranch, PrefixOp, BinOp, LiteralKind,ArrayExprKind},
2222
};
2323

2424
/// The main trait to go from untyped `SyntaxNode` to a typed ast. The

crates/ra_syntax/src/ast/expr_extensions.rs

+22
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,28 @@ impl ast::BinExpr {
193193
}
194194
}
195195

196+
pub enum ArrayExprKind<'a> {
197+
Repeat { initializer: Option<&'a ast::Expr>, repeat: Option<&'a ast::Expr> },
198+
ElementList(AstChildren<'a, ast::Expr>),
199+
}
200+
201+
impl ast::ArrayExpr {
202+
pub fn kind(&self) -> ArrayExprKind {
203+
if self.is_repeat() {
204+
ArrayExprKind::Repeat {
205+
initializer: children(self).nth(0),
206+
repeat: children(self).nth(1),
207+
}
208+
} else {
209+
ArrayExprKind::ElementList(children(self))
210+
}
211+
}
212+
213+
fn is_repeat(&self) -> bool {
214+
self.syntax().children_with_tokens().any(|it| it.kind() == SEMI)
215+
}
216+
}
217+
196218
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
197219
pub enum LiteralKind {
198220
String,

0 commit comments

Comments
 (0)