diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/expr.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/expr/lower.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/name.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 26 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 31 |
5 files changed, 68 insertions, 1 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 698fa671b..b1bec2a68 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -237,6 +237,9 @@ pub enum Expr { | |||
237 | expr: ExprId, | 237 | expr: ExprId, |
238 | mutability: Mutability, | 238 | mutability: Mutability, |
239 | }, | 239 | }, |
240 | Box { | ||
241 | expr: ExprId, | ||
242 | }, | ||
240 | UnaryOp { | 243 | UnaryOp { |
241 | expr: ExprId, | 244 | expr: ExprId, |
242 | op: UnaryOp, | 245 | op: UnaryOp, |
@@ -413,7 +416,8 @@ impl Expr { | |||
413 | | Expr::Try { expr } | 416 | | Expr::Try { expr } |
414 | | Expr::Cast { expr, .. } | 417 | | Expr::Cast { expr, .. } |
415 | | Expr::Ref { expr, .. } | 418 | | Expr::Ref { expr, .. } |
416 | | Expr::UnaryOp { expr, .. } => { | 419 | | Expr::UnaryOp { expr, .. } |
420 | | Expr::Box { expr } => { | ||
417 | f(*expr); | 421 | f(*expr); |
418 | } | 422 | } |
419 | Expr::Tuple { exprs } => { | 423 | Expr::Tuple { exprs } => { |
diff --git a/crates/ra_hir/src/expr/lower.rs b/crates/ra_hir/src/expr/lower.rs index 8bd041ff0..2be6f5421 100644 --- a/crates/ra_hir/src/expr/lower.rs +++ b/crates/ra_hir/src/expr/lower.rs | |||
@@ -389,6 +389,10 @@ where | |||
389 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); | 389 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); |
390 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) | 390 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) |
391 | } | 391 | } |
392 | ast::Expr::BoxExpr(e) => { | ||
393 | let expr = self.collect_expr_opt(e.expr()); | ||
394 | self.alloc_expr(Expr::Box { expr }, syntax_ptr) | ||
395 | } | ||
392 | 396 | ||
393 | ast::Expr::ArrayExpr(e) => { | 397 | ast::Expr::ArrayExpr(e) => { |
394 | let kind = e.kind(); | 398 | let kind = e.kind(); |
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs index 13bc901bc..abdfec296 100644 --- a/crates/ra_hir/src/name.rs +++ b/crates/ra_hir/src/name.rs | |||
@@ -119,6 +119,8 @@ pub(crate) const RESULT_MOD: Name = Name::new(SmolStr::new_inline_from_ascii(6, | |||
119 | pub(crate) const RESULT_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Result")); | 119 | pub(crate) const RESULT_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Result")); |
120 | pub(crate) const OUTPUT: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Output")); | 120 | pub(crate) const OUTPUT: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Output")); |
121 | pub(crate) const TARGET: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Target")); | 121 | pub(crate) const TARGET: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Target")); |
122 | pub(crate) const BOXED_MOD: Name = Name::new(SmolStr::new_inline_from_ascii(5, b"boxed")); | ||
123 | pub(crate) const BOX_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"Box")); | ||
122 | 124 | ||
123 | fn resolve_name(text: &SmolStr) -> SmolStr { | 125 | fn resolve_name(text: &SmolStr) -> SmolStr { |
124 | let raw_start = "r#"; | 126 | let raw_start = "r#"; |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 9244ff3cb..1057bbbec 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -1259,6 +1259,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1259 | let inner_ty = self.infer_expr(*expr, &expectation); | 1259 | let inner_ty = self.infer_expr(*expr, &expectation); |
1260 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) | 1260 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) |
1261 | } | 1261 | } |
1262 | Expr::Box { expr } => { | ||
1263 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); | ||
1264 | if let Some(box_) = self.resolve_boxed_box() { | ||
1265 | Ty::apply_one(TypeCtor::Adt(box_), inner_ty) | ||
1266 | } else { | ||
1267 | Ty::Unknown | ||
1268 | } | ||
1269 | } | ||
1262 | Expr::UnaryOp { expr, op } => { | 1270 | Expr::UnaryOp { expr, op } => { |
1263 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); | 1271 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); |
1264 | match op { | 1272 | match op { |
@@ -1499,6 +1507,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1499 | _ => None, | 1507 | _ => None, |
1500 | } | 1508 | } |
1501 | } | 1509 | } |
1510 | |||
1511 | fn resolve_boxed_box(&self) -> Option<AdtDef> { | ||
1512 | let boxed_box_path = Path { | ||
1513 | kind: PathKind::Abs, | ||
1514 | segments: vec![ | ||
1515 | PathSegment { name: name::STD, args_and_bindings: None }, | ||
1516 | PathSegment { name: name::BOXED_MOD, args_and_bindings: None }, | ||
1517 | PathSegment { name: name::BOX_TYPE, args_and_bindings: None }, | ||
1518 | ], | ||
1519 | }; | ||
1520 | |||
1521 | match self.resolver.resolve_path_segments(self.db, &boxed_box_path).into_fully_resolved() { | ||
1522 | PerNs { types: Some(Def(ModuleDef::Struct(struct_))), .. } => { | ||
1523 | Some(AdtDef::Struct(struct_)) | ||
1524 | } | ||
1525 | _ => None, | ||
1526 | } | ||
1527 | } | ||
1502 | } | 1528 | } |
1503 | 1529 | ||
1504 | /// The ID of a type variable. | 1530 | /// The ID of a type variable. |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 869ae13f1..9a5f6949d 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -56,6 +56,37 @@ mod future { | |||
56 | } | 56 | } |
57 | 57 | ||
58 | #[test] | 58 | #[test] |
59 | fn infer_box() { | ||
60 | let (mut db, pos) = MockDatabase::with_position( | ||
61 | r#" | ||
62 | //- /main.rs | ||
63 | |||
64 | fn test() { | ||
65 | let x = box 1; | ||
66 | let t = (x, box x, box &1, box [1]); | ||
67 | t<|>; | ||
68 | } | ||
69 | |||
70 | //- /std.rs | ||
71 | #[prelude_import] use prelude::*; | ||
72 | mod prelude {} | ||
73 | |||
74 | mod boxed { | ||
75 | pub struct Box<T: ?Sized> { | ||
76 | inner: *mut T, | ||
77 | } | ||
78 | } | ||
79 | |||
80 | "#, | ||
81 | ); | ||
82 | db.set_crate_graph_from_fixture(crate_graph! { | ||
83 | "main": ("/main.rs", ["std"]), | ||
84 | "std": ("/std.rs", []), | ||
85 | }); | ||
86 | assert_eq!("(Box<i32>, Box<Box<i32>>, Box<&i32>, Box<[i32;_]>)", type_at_pos(&db, pos)); | ||
87 | } | ||
88 | |||
89 | #[test] | ||
59 | fn infer_try() { | 90 | fn infer_try() { |
60 | let (mut db, pos) = MockDatabase::with_position( | 91 | let (mut db, pos) = MockDatabase::with_position( |
61 | r#" | 92 | r#" |