diff options
| -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 | ||||
| -rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 40 | ||||
| -rw-r--r-- | crates/ra_syntax/src/grammar.ron | 2 |
7 files changed, 107 insertions, 4 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#" |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index d274b6fbc..a8a231ef3 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
| @@ -307,6 +307,33 @@ impl BlockExpr { | |||
| 307 | } | 307 | } |
| 308 | } | 308 | } |
| 309 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 309 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
| 310 | pub struct BoxExpr { | ||
| 311 | pub(crate) syntax: SyntaxNode, | ||
| 312 | } | ||
| 313 | impl AstNode for BoxExpr { | ||
| 314 | fn can_cast(kind: SyntaxKind) -> bool { | ||
| 315 | match kind { | ||
| 316 | BOX_EXPR => true, | ||
| 317 | _ => false, | ||
| 318 | } | ||
| 319 | } | ||
| 320 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
| 321 | if Self::can_cast(syntax.kind()) { | ||
| 322 | Some(Self { syntax }) | ||
| 323 | } else { | ||
| 324 | None | ||
| 325 | } | ||
| 326 | } | ||
| 327 | fn syntax(&self) -> &SyntaxNode { | ||
| 328 | &self.syntax | ||
| 329 | } | ||
| 330 | } | ||
| 331 | impl BoxExpr { | ||
| 332 | pub fn expr(&self) -> Option<Expr> { | ||
| 333 | AstChildren::new(&self.syntax).next() | ||
| 334 | } | ||
| 335 | } | ||
| 336 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
| 310 | pub struct BoxPat { | 337 | pub struct BoxPat { |
| 311 | pub(crate) syntax: SyntaxNode, | 338 | pub(crate) syntax: SyntaxNode, |
| 312 | } | 339 | } |
| @@ -649,6 +676,7 @@ pub enum Expr { | |||
| 649 | BinExpr(BinExpr), | 676 | BinExpr(BinExpr), |
| 650 | Literal(Literal), | 677 | Literal(Literal), |
| 651 | MacroCall(MacroCall), | 678 | MacroCall(MacroCall), |
| 679 | BoxExpr(BoxExpr), | ||
| 652 | } | 680 | } |
| 653 | impl From<TupleExpr> for Expr { | 681 | impl From<TupleExpr> for Expr { |
| 654 | fn from(node: TupleExpr) -> Expr { | 682 | fn from(node: TupleExpr) -> Expr { |
| @@ -800,6 +828,11 @@ impl From<MacroCall> for Expr { | |||
| 800 | Expr::MacroCall(node) | 828 | Expr::MacroCall(node) |
| 801 | } | 829 | } |
| 802 | } | 830 | } |
| 831 | impl From<BoxExpr> for Expr { | ||
| 832 | fn from(node: BoxExpr) -> Expr { | ||
| 833 | Expr::BoxExpr(node) | ||
| 834 | } | ||
| 835 | } | ||
| 803 | impl AstNode for Expr { | 836 | impl AstNode for Expr { |
| 804 | fn can_cast(kind: SyntaxKind) -> bool { | 837 | fn can_cast(kind: SyntaxKind) -> bool { |
| 805 | match kind { | 838 | match kind { |
| @@ -807,9 +840,8 @@ impl AstNode for Expr { | |||
| 807 | | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL | 840 | | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL |
| 808 | | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | RECORD_LIT | CALL_EXPR | INDEX_EXPR | 841 | | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | RECORD_LIT | CALL_EXPR | INDEX_EXPR |
| 809 | | METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | TRY_BLOCK_EXPR | 842 | | METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | TRY_BLOCK_EXPR |
| 810 | | CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL => { | 843 | | CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL |
| 811 | true | 844 | | BOX_EXPR => true, |
| 812 | } | ||
| 813 | _ => false, | 845 | _ => false, |
| 814 | } | 846 | } |
| 815 | } | 847 | } |
| @@ -845,6 +877,7 @@ impl AstNode for Expr { | |||
| 845 | BIN_EXPR => Expr::BinExpr(BinExpr { syntax }), | 877 | BIN_EXPR => Expr::BinExpr(BinExpr { syntax }), |
| 846 | LITERAL => Expr::Literal(Literal { syntax }), | 878 | LITERAL => Expr::Literal(Literal { syntax }), |
| 847 | MACRO_CALL => Expr::MacroCall(MacroCall { syntax }), | 879 | MACRO_CALL => Expr::MacroCall(MacroCall { syntax }), |
| 880 | BOX_EXPR => Expr::BoxExpr(BoxExpr { syntax }), | ||
| 848 | _ => return None, | 881 | _ => return None, |
| 849 | }; | 882 | }; |
| 850 | Some(res) | 883 | Some(res) |
| @@ -881,6 +914,7 @@ impl AstNode for Expr { | |||
| 881 | Expr::BinExpr(it) => &it.syntax, | 914 | Expr::BinExpr(it) => &it.syntax, |
| 882 | Expr::Literal(it) => &it.syntax, | 915 | Expr::Literal(it) => &it.syntax, |
| 883 | Expr::MacroCall(it) => &it.syntax, | 916 | Expr::MacroCall(it) => &it.syntax, |
| 917 | Expr::BoxExpr(it) => &it.syntax, | ||
| 884 | } | 918 | } |
| 885 | } | 919 | } |
| 886 | } | 920 | } |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 993e58e64..8f064711d 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
| @@ -483,6 +483,7 @@ Grammar( | |||
| 483 | "CastExpr": (options: ["Expr", "TypeRef"]), | 483 | "CastExpr": (options: ["Expr", "TypeRef"]), |
| 484 | "RefExpr": (options: ["Expr"]), | 484 | "RefExpr": (options: ["Expr"]), |
| 485 | "PrefixExpr": (options: ["Expr"]), | 485 | "PrefixExpr": (options: ["Expr"]), |
| 486 | "BoxExpr": (options: ["Expr"]), | ||
| 486 | "RangeExpr": (), | 487 | "RangeExpr": (), |
| 487 | "BinExpr": (), | 488 | "BinExpr": (), |
| 488 | 489 | ||
| @@ -520,6 +521,7 @@ Grammar( | |||
| 520 | "BinExpr", | 521 | "BinExpr", |
| 521 | "Literal", | 522 | "Literal", |
| 522 | "MacroCall", | 523 | "MacroCall", |
| 524 | "BoxExpr", | ||
| 523 | ], | 525 | ], |
| 524 | ), | 526 | ), |
| 525 | 527 | ||
