aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-09-12 11:53:29 +0100
committerGitHub <[email protected]>2019-09-12 11:53:29 +0100
commita1261631a89f7169a3f84dec33aff61758c601e3 (patch)
tree773c687fe89b8cec009de17142b3a59e80468b21 /crates/ra_hir/src
parent561e7aea5bdaf6c51e0a87da9ff1d73e2df52be1 (diff)
parent8c078a01641518a6b093922d4b1d27d1a98bad08 (diff)
Merge #1818
1818: Infer box expression r=matklad a=uHOOCCOOHu Infer `box e` to be `std::boxed::Box<T>` where `e: T` Co-authored-by: uHOOCCOOHu <[email protected]>
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/expr.rs6
-rw-r--r--crates/ra_hir/src/expr/lower.rs4
-rw-r--r--crates/ra_hir/src/name.rs2
-rw-r--r--crates/ra_hir/src/ty/infer.rs26
-rw-r--r--crates/ra_hir/src/ty/tests.rs31
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,
119pub(crate) const RESULT_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Result")); 119pub(crate) const RESULT_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Result"));
120pub(crate) const OUTPUT: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Output")); 120pub(crate) const OUTPUT: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Output"));
121pub(crate) const TARGET: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Target")); 121pub(crate) const TARGET: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Target"));
122pub(crate) const BOXED_MOD: Name = Name::new(SmolStr::new_inline_from_ascii(5, b"boxed"));
123pub(crate) const BOX_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"Box"));
122 124
123fn resolve_name(text: &SmolStr) -> SmolStr { 125fn 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]
59fn infer_box() {
60 let (mut db, pos) = MockDatabase::with_position(
61 r#"
62//- /main.rs
63
64fn 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::*;
72mod prelude {}
73
74mod 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]
59fn infer_try() { 90fn infer_try() {
60 let (mut db, pos) = MockDatabase::with_position( 91 let (mut db, pos) = MockDatabase::with_position(
61 r#" 92 r#"