Merge #520
520: Imprement tuple inference r=flodiebold a=h-michael related #394 I'm sorry I'm late. I try implementing array inference next. Co-authored-by: Hirokazu Hata <h.hata.ai.t@gmail.com>
This commit is contained in:
commit
ff09d15124
6 changed files with 74 additions and 3 deletions
|
@ -183,6 +183,9 @@ pub enum Expr {
|
|||
arg_types: Vec<Option<TypeRef>>,
|
||||
body: ExprId,
|
||||
},
|
||||
Tuple {
|
||||
exprs: Vec<ExprId>,
|
||||
},
|
||||
}
|
||||
|
||||
pub use ra_syntax::ast::PrefixOp as UnaryOp;
|
||||
|
@ -297,6 +300,11 @@ impl Expr {
|
|||
| Expr::UnaryOp { expr, .. } => {
|
||||
f(*expr);
|
||||
}
|
||||
Expr::Tuple { exprs } => {
|
||||
for expr in exprs {
|
||||
f(*expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -621,11 +629,14 @@ impl ExprCollector {
|
|||
let op = e.op();
|
||||
self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr)
|
||||
}
|
||||
ast::ExprKind::TupleExpr(e) => {
|
||||
let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect();
|
||||
self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr)
|
||||
}
|
||||
|
||||
// TODO implement HIR for these:
|
||||
ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||
ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||
ast::ExprKind::TupleExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||
ast::ExprKind::ArrayExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||
ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||
ast::ExprKind::Literal(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||
|
|
|
@ -1040,6 +1040,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
|||
}
|
||||
_ => Ty::Unknown,
|
||||
},
|
||||
Expr::Tuple { exprs } => {
|
||||
let mut ty_vec = Vec::with_capacity(exprs.len());
|
||||
for arg in exprs.iter() {
|
||||
ty_vec.push(self.infer_expr(*arg, &Expectation::none())?);
|
||||
}
|
||||
|
||||
Ty::Tuple(Arc::from(ty_vec))
|
||||
}
|
||||
};
|
||||
// use a new type variable if we got Ty::Unknown here
|
||||
let ty = self.insert_type_vars_shallow(ty);
|
||||
|
|
|
@ -268,6 +268,25 @@ fn test(a: A) {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_tuple() {
|
||||
check_inference(
|
||||
r#"
|
||||
fn test(x: &str, y: isize) {
|
||||
let a: (u32, &str) = (1, "a");
|
||||
let b = (a, x);
|
||||
let c = (y, x);
|
||||
let d = (c, x);
|
||||
|
||||
// we have not infered these case yet.
|
||||
let e = (1, "e");
|
||||
let f = (e, "d");
|
||||
}
|
||||
"#,
|
||||
"tuple.txt",
|
||||
);
|
||||
}
|
||||
|
||||
fn infer(content: &str) -> String {
|
||||
let (db, _, file_id) = MockDatabase::with_single_file(content);
|
||||
let source_file = db.source_file(file_id);
|
||||
|
|
27
crates/ra_hir/src/ty/tests/data/tuple.txt
Normal file
27
crates/ra_hir/src/ty/tests/data/tuple.txt
Normal file
|
@ -0,0 +1,27 @@
|
|||
[9; 10) 'x': &str
|
||||
[18; 19) 'y': isize
|
||||
[28; 214) '{ ...d"); }': ()
|
||||
[38; 39) 'a': (u32, &str)
|
||||
[55; 63) '(1, "a")': (u32, &str)
|
||||
[56; 57) '1': u32
|
||||
[59; 62) '"a"': &str
|
||||
[73; 74) 'b': ((u32, &str), &str)
|
||||
[77; 83) '(a, x)': ((u32, &str), &str)
|
||||
[78; 79) 'a': (u32, &str)
|
||||
[81; 82) 'x': &str
|
||||
[93; 94) 'c': (isize, &str)
|
||||
[97; 103) '(y, x)': (isize, &str)
|
||||
[98; 99) 'y': isize
|
||||
[101; 102) 'x': &str
|
||||
[113; 114) 'd': ((isize, &str), &str)
|
||||
[117; 123) '(c, x)': ((isize, &str), &str)
|
||||
[118; 119) 'c': (isize, &str)
|
||||
[121; 122) 'x': &str
|
||||
[177; 178) 'e': ([unknown], [unknown])
|
||||
[181; 189) '(1, "e")': ([unknown], [unknown])
|
||||
[182; 183) '1': [unknown]
|
||||
[185; 188) '"e"': [unknown]
|
||||
[199; 200) 'f': (([unknown], [unknown]), [unknown])
|
||||
[203; 211) '(e, "d")': (([unknown], [unknown]), [unknown])
|
||||
[204; 205) 'e': ([unknown], [unknown])
|
||||
[207; 210) '"d"': [unknown]
|
|
@ -2969,7 +2969,11 @@ impl AstNode for TupleExpr {
|
|||
}
|
||||
|
||||
|
||||
impl TupleExpr {}
|
||||
impl TupleExpr {
|
||||
pub fn exprs(&self) -> impl Iterator<Item = &Expr> {
|
||||
super::children(self)
|
||||
}
|
||||
}
|
||||
|
||||
// TuplePat
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
|
|
|
@ -357,7 +357,9 @@ Grammar(
|
|||
enum: ["FnDef", "TypeDef", "ConstDef"]
|
||||
),
|
||||
|
||||
"TupleExpr": (),
|
||||
"TupleExpr": (
|
||||
collections: [["exprs", "Expr"]]
|
||||
),
|
||||
"ArrayExpr": (),
|
||||
"ParenExpr": (options: ["Expr"]),
|
||||
"PathExpr": (options: ["Path"]),
|
||||
|
|
Loading…
Add table
Reference in a new issue