diff options
author | oxalica <[email protected]> | 2019-11-28 19:10:16 +0000 |
---|---|---|
committer | oxalica <[email protected]> | 2019-11-28 19:10:16 +0000 |
commit | 4992d2bf79e9da6db759eb8e1715f90f31ec7eb9 (patch) | |
tree | 9396eb224a6865aa76c64937bc88c02b6ade04b8 /crates/ra_hir_def | |
parent | 8b278b1ab660df0728508e45e88ac769a2e03a58 (diff) |
Infer range types
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 22 | ||||
-rw-r--r-- | crates/ra_hir_def/src/expr.rs | 28 | ||||
-rw-r--r-- | crates/ra_hir_def/src/path.rs | 30 |
3 files changed, 76 insertions, 4 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 331736cb2..d18964d54 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -8,7 +8,7 @@ use hir_expand::{ | |||
8 | use ra_arena::Arena; | 8 | use ra_arena::Arena; |
9 | use ra_syntax::{ | 9 | use ra_syntax::{ |
10 | ast::{ | 10 | ast::{ |
11 | self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner, | 11 | self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner, RangeOp, |
12 | TypeAscriptionOwner, | 12 | TypeAscriptionOwner, |
13 | }, | 13 | }, |
14 | AstNode, AstPtr, | 14 | AstNode, AstPtr, |
@@ -429,10 +429,28 @@ where | |||
429 | let index = self.collect_expr_opt(e.index()); | 429 | let index = self.collect_expr_opt(e.index()); |
430 | self.alloc_expr(Expr::Index { base, index }, syntax_ptr) | 430 | self.alloc_expr(Expr::Index { base, index }, syntax_ptr) |
431 | } | 431 | } |
432 | ast::Expr::RangeExpr(e) => { | ||
433 | let lhs = e.start().map(|lhs| self.collect_expr(lhs)); | ||
434 | let rhs = e.end().map(|rhs| self.collect_expr(rhs)); | ||
435 | match (lhs, e.op_kind(), rhs) { | ||
436 | (None, _, None) => self.alloc_expr(Expr::RangeFull, syntax_ptr), | ||
437 | (Some(lhs), _, None) => self.alloc_expr(Expr::RangeFrom { lhs }, syntax_ptr), | ||
438 | (None, Some(RangeOp::Inclusive), Some(rhs)) => { | ||
439 | self.alloc_expr(Expr::RangeToInclusive { rhs }, syntax_ptr) | ||
440 | } | ||
441 | (Some(lhs), Some(RangeOp::Inclusive), Some(rhs)) => { | ||
442 | self.alloc_expr(Expr::RangeInclusive { lhs, rhs }, syntax_ptr) | ||
443 | } | ||
444 | // If RangeOp is missing, fallback to exclusive range. | ||
445 | (None, _, Some(rhs)) => self.alloc_expr(Expr::RangeTo { rhs }, syntax_ptr), | ||
446 | (Some(lhs), _, Some(rhs)) => { | ||
447 | self.alloc_expr(Expr::Range { lhs, rhs }, syntax_ptr) | ||
448 | } | ||
449 | } | ||
450 | } | ||
432 | 451 | ||
433 | // FIXME implement HIR for these: | 452 | // FIXME implement HIR for these: |
434 | ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 453 | ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
435 | ast::Expr::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | ||
436 | ast::Expr::MacroCall(e) => match self.expander.enter_expand(self.db, e) { | 454 | ast::Expr::MacroCall(e) => match self.expander.enter_expand(self.db, e) { |
437 | Some((mark, expansion)) => { | 455 | Some((mark, expansion)) => { |
438 | let id = self.collect_expr(expansion); | 456 | let id = self.collect_expr(expansion); |
diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs index 04c1d8f69..115090218 100644 --- a/crates/ra_hir_def/src/expr.rs +++ b/crates/ra_hir_def/src/expr.rs | |||
@@ -130,6 +130,24 @@ pub enum Expr { | |||
130 | rhs: ExprId, | 130 | rhs: ExprId, |
131 | op: Option<BinaryOp>, | 131 | op: Option<BinaryOp>, |
132 | }, | 132 | }, |
133 | RangeFull, | ||
134 | RangeFrom { | ||
135 | lhs: ExprId, | ||
136 | }, | ||
137 | RangeTo { | ||
138 | rhs: ExprId, | ||
139 | }, | ||
140 | Range { | ||
141 | lhs: ExprId, | ||
142 | rhs: ExprId, | ||
143 | }, | ||
144 | RangeToInclusive { | ||
145 | rhs: ExprId, | ||
146 | }, | ||
147 | RangeInclusive { | ||
148 | lhs: ExprId, | ||
149 | rhs: ExprId, | ||
150 | }, | ||
133 | Index { | 151 | Index { |
134 | base: ExprId, | 152 | base: ExprId, |
135 | index: ExprId, | 153 | index: ExprId, |
@@ -284,7 +302,9 @@ impl Expr { | |||
284 | Expr::Lambda { body, .. } => { | 302 | Expr::Lambda { body, .. } => { |
285 | f(*body); | 303 | f(*body); |
286 | } | 304 | } |
287 | Expr::BinaryOp { lhs, rhs, .. } => { | 305 | Expr::BinaryOp { lhs, rhs, .. } |
306 | | Expr::Range { lhs, rhs } | ||
307 | | Expr::RangeInclusive { lhs, rhs } => { | ||
288 | f(*lhs); | 308 | f(*lhs); |
289 | f(*rhs); | 309 | f(*rhs); |
290 | } | 310 | } |
@@ -292,7 +312,11 @@ impl Expr { | |||
292 | f(*base); | 312 | f(*base); |
293 | f(*index); | 313 | f(*index); |
294 | } | 314 | } |
295 | Expr::Field { expr, .. } | 315 | Expr::RangeFull => {} |
316 | Expr::RangeFrom { lhs: expr } | ||
317 | | Expr::RangeTo { rhs: expr } | ||
318 | | Expr::RangeToInclusive { rhs: expr } | ||
319 | | Expr::Field { expr, .. } | ||
296 | | Expr::Await { expr } | 320 | | Expr::Await { expr } |
297 | | Expr::Try { expr } | 321 | | Expr::Try { expr } |
298 | | Expr::Cast { expr, .. } | 322 | | Expr::Cast { expr, .. } |
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 10688df4d..ff252fe44 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs | |||
@@ -409,6 +409,36 @@ pub mod known { | |||
409 | Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::TRY_TYPE]) | 409 | Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::TRY_TYPE]) |
410 | } | 410 | } |
411 | 411 | ||
412 | pub fn std_ops_range() -> Path { | ||
413 | Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_TYPE]) | ||
414 | } | ||
415 | |||
416 | pub fn std_ops_range_from() -> Path { | ||
417 | Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_FROM_TYPE]) | ||
418 | } | ||
419 | |||
420 | pub fn std_ops_range_full() -> Path { | ||
421 | Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_FULL_TYPE]) | ||
422 | } | ||
423 | |||
424 | pub fn std_ops_range_inclusive() -> Path { | ||
425 | Path::from_simple_segments( | ||
426 | PathKind::Abs, | ||
427 | vec![name::STD, name::OPS, name::RANGE_INCLUSIVE_TYPE], | ||
428 | ) | ||
429 | } | ||
430 | |||
431 | pub fn std_ops_range_to() -> Path { | ||
432 | Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_TO_TYPE]) | ||
433 | } | ||
434 | |||
435 | pub fn std_ops_range_to_inclusive() -> Path { | ||
436 | Path::from_simple_segments( | ||
437 | PathKind::Abs, | ||
438 | vec![name::STD, name::OPS, name::RANGE_TO_INCLUSIVE_TYPE], | ||
439 | ) | ||
440 | } | ||
441 | |||
412 | pub fn std_result_result() -> Path { | 442 | pub fn std_result_result() -> Path { |
413 | Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::RESULT, name::RESULT_TYPE]) | 443 | Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::RESULT, name::RESULT_TYPE]) |
414 | } | 444 | } |