mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Merge #701
701: Minor type inference tweaks r=flodiebold a=marcusklaas Pass down expectation for reference expressions and type the guard in match expressions. I wasn't able to add a test for the former addition because the type variable previously introduced would always resolve to the right type in the things I tried! Co-authored-by: Marcus Klaas de Vries <mail@marcusklaas.nl>
This commit is contained in:
commit
28fdb8d03c
11 changed files with 163 additions and 63 deletions
|
@ -219,7 +219,7 @@ pub use ra_syntax::ast::BinOp as BinaryOp;
|
|||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct MatchArm {
|
||||
pub pats: Vec<PatId>,
|
||||
// guard: Option<ExprId>, // TODO
|
||||
pub guard: Option<ExprId>,
|
||||
pub expr: ExprId,
|
||||
}
|
||||
|
||||
|
@ -515,10 +515,12 @@ impl ExprCollector {
|
|||
MatchArm {
|
||||
pats: vec![pat],
|
||||
expr: then_branch,
|
||||
guard: None,
|
||||
},
|
||||
MatchArm {
|
||||
pats: vec![placeholder_pat],
|
||||
expr: else_branch,
|
||||
guard: None,
|
||||
},
|
||||
];
|
||||
self.alloc_expr(
|
||||
|
@ -617,6 +619,10 @@ impl ExprCollector {
|
|||
.map(|arm| MatchArm {
|
||||
pats: arm.pats().map(|p| self.collect_pat(p)).collect(),
|
||||
expr: self.collect_expr_opt(arm.expr()),
|
||||
guard: arm
|
||||
.guard()
|
||||
.and_then(|guard| guard.expr())
|
||||
.map(|e| self.collect_expr(e)),
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
|
|
|
@ -1488,7 +1488,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
|||
for &pat in &arm.pats {
|
||||
let _pat_ty = self.infer_pat(pat, &input_ty);
|
||||
}
|
||||
// TODO type the guard
|
||||
if let Some(guard_expr) = arm.guard {
|
||||
self.infer_expr(guard_expr, &Expectation::has_type(Ty::Bool));
|
||||
}
|
||||
self.infer_expr(arm.expr, &expected);
|
||||
}
|
||||
|
||||
|
@ -1561,9 +1563,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
|||
cast_ty
|
||||
}
|
||||
Expr::Ref { expr, mutability } => {
|
||||
// TODO pass the expectation down
|
||||
let inner_ty = self.infer_expr(*expr, &Expectation::none());
|
||||
let expectation = if let Ty::Ref(ref subty, expected_mutability) = expected.ty {
|
||||
if expected_mutability == Mutability::Mut && *mutability == Mutability::Shared {
|
||||
// TODO: throw type error - expected mut reference but found shared ref,
|
||||
// which cannot be coerced
|
||||
}
|
||||
Expectation::has_type((**subty).clone())
|
||||
} else {
|
||||
Expectation::none()
|
||||
};
|
||||
// TODO reference coercions etc.
|
||||
let inner_ty = self.infer_expr(*expr, &expectation);
|
||||
Ty::Ref(Arc::new(inner_ty), *mutability)
|
||||
}
|
||||
Expr::UnaryOp { expr, op } => {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
---
|
||||
created: "2019-01-22T14:44:59.880187500+00:00"
|
||||
creator: insta@0.4.0
|
||||
created: "2019-01-28T21:58:55.559331849+00:00"
|
||||
creator: insta@0.5.2
|
||||
expression: "&result"
|
||||
source: "crates\\ra_hir\\src\\ty\\tests.rs"
|
||||
source: crates/ra_hir/src/ty/tests.rs
|
||||
---
|
||||
[68; 262) '{ ... d; }': ()
|
||||
[68; 289) '{ ... d; }': ()
|
||||
[78; 79) 'e': E
|
||||
[82; 95) 'E::A { x: 3 }': E
|
||||
[92; 93) '3': usize
|
||||
|
@ -15,15 +15,18 @@ source: "crates\\ra_hir\\src\\ty\\tests.rs"
|
|||
[129; 148) 'E::A {..._var }': E
|
||||
[139; 146) 'new_var': usize
|
||||
[151; 152) 'e': E
|
||||
[159; 218) 'match ... }': usize
|
||||
[159; 245) 'match ... }': usize
|
||||
[165; 166) 'e': E
|
||||
[177; 187) 'E::A { x }': E
|
||||
[184; 185) 'x': usize
|
||||
[191; 192) 'x': usize
|
||||
[202; 206) 'E::B': E
|
||||
[210; 211) '1': usize
|
||||
[229; 248) 'ref d ...{ .. }': &E
|
||||
[237; 248) 'E::A { .. }': E
|
||||
[251; 252) 'e': E
|
||||
[258; 259) 'd': &E
|
||||
[210; 213) 'foo': bool
|
||||
[217; 218) '1': usize
|
||||
[228; 232) 'E::B': E
|
||||
[236; 238) '10': usize
|
||||
[256; 275) 'ref d ...{ .. }': &E
|
||||
[264; 275) 'E::A { .. }': E
|
||||
[278; 279) 'e': E
|
||||
[285; 286) 'd': &E
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
---
|
||||
created: "2019-01-22T14:44:59.880187500+00:00"
|
||||
creator: insta@0.4.0
|
||||
created: "2019-01-30T20:08:05.185312835+00:00"
|
||||
creator: insta@0.5.2
|
||||
expression: "&result"
|
||||
source: "crates\\ra_hir\\src\\ty\\tests.rs"
|
||||
source: crates/ra_hir/src/ty/tests.rs
|
||||
---
|
||||
[9; 10) 'x': &str
|
||||
[18; 19) 'y': isize
|
||||
[28; 293) '{ ... []; }': ()
|
||||
[28; 324) '{ ... 3]; }': ()
|
||||
[38; 39) 'a': [&str]
|
||||
[42; 45) '[x]': [&str]
|
||||
[43; 44) 'x': &str
|
||||
|
@ -56,4 +56,10 @@ source: "crates\\ra_hir\\src\\ty\\tests.rs"
|
|||
[260; 263) '"b"': &str
|
||||
[275; 276) 'x': [u8]
|
||||
[288; 290) '[]': [u8]
|
||||
[300; 301) 'z': &[u8]
|
||||
[311; 321) '&[1, 2, 3]': &[u8]
|
||||
[312; 321) '[1, 2, 3]': [u8]
|
||||
[313; 314) '1': u8
|
||||
[316; 317) '2': u8
|
||||
[319; 320) '3': u8
|
||||
|
||||
|
|
|
@ -371,6 +371,7 @@ fn test(x: &str, y: isize) {
|
|||
|
||||
let b = [a, ["b"]];
|
||||
let x: [u8; 0] = [];
|
||||
let z: &[u8] = &[1, 2, 3];
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
@ -426,7 +427,8 @@ fn test() {
|
|||
|
||||
match e {
|
||||
E::A { x } => x,
|
||||
E::B => 1,
|
||||
E::B if foo => 1,
|
||||
E::B => 10,
|
||||
};
|
||||
|
||||
let ref d @ E::A { .. } = e;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue