aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
authoroxalica <[email protected]>2019-11-28 19:10:16 +0000
committeroxalica <[email protected]>2019-11-28 19:10:16 +0000
commit4992d2bf79e9da6db759eb8e1715f90f31ec7eb9 (patch)
tree9396eb224a6865aa76c64937bc88c02b6ade04b8 /crates/ra_hir_def
parent8b278b1ab660df0728508e45e88ac769a2e03a58 (diff)
Infer range types
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/src/body/lower.rs22
-rw-r--r--crates/ra_hir_def/src/expr.rs28
-rw-r--r--crates/ra_hir_def/src/path.rs30
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::{
8use ra_arena::Arena; 8use ra_arena::Arena;
9use ra_syntax::{ 9use 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 }