aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir_def/src/body/lower.rs19
-rw-r--r--crates/ra_hir_def/src/expr.rs3
-rw-r--r--crates/ra_hir_def/src/type_ref.rs16
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs37
-rw-r--r--crates/ra_hir_ty/src/lib.rs18
-rw-r--r--crates/ra_hir_ty/src/tests/coercion.rs17
-rw-r--r--crates/ra_hir_ty/src/tests/simple.rs20
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs16
-rw-r--r--crates/ra_syntax/src/ast/generated/nodes.rs3
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rast172
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rs6
-rw-r--r--xtask/src/ast_src.rs4
12 files changed, 259 insertions, 72 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index e08d62dd6..905c0cf5d 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -28,7 +28,7 @@ use crate::{
28 }, 28 },
29 item_scope::BuiltinShadowMode, 29 item_scope::BuiltinShadowMode,
30 path::{GenericArgs, Path}, 30 path::{GenericArgs, Path},
31 type_ref::{Mutability, TypeRef}, 31 type_ref::{Mutability, Rawness, TypeRef},
32 AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, 32 AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId,
33 StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, 33 StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
34}; 34};
@@ -378,8 +378,21 @@ impl ExprCollector<'_> {
378 } 378 }
379 ast::Expr::RefExpr(e) => { 379 ast::Expr::RefExpr(e) => {
380 let expr = self.collect_expr_opt(e.expr()); 380 let expr = self.collect_expr_opt(e.expr());
381 let mutability = Mutability::from_mutable(e.mut_token().is_some()); 381 let raw_tok = e.raw_token().is_some();
382 self.alloc_expr(Expr::Ref { expr, mutability }, syntax_ptr) 382 let mutability = if raw_tok {
383 if e.mut_token().is_some() {
384 Mutability::Mut
385 } else if e.const_token().is_some() {
386 Mutability::Shared
387 } else {
388 unreachable!("parser only remaps to raw_token() if matching mutability token follows")
389 }
390 } else {
391 Mutability::from_mutable(e.mut_token().is_some())
392 };
393 let rawness = Rawness::from_raw(raw_tok);
394
395 self.alloc_expr(Expr::Ref { expr, rawness, mutability }, syntax_ptr)
383 } 396 }
384 ast::Expr::PrefixExpr(e) => { 397 ast::Expr::PrefixExpr(e) => {
385 let expr = self.collect_expr_opt(e.expr()); 398 let expr = self.collect_expr_opt(e.expr());
diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs
index a0cdad529..f25c6f958 100644
--- a/crates/ra_hir_def/src/expr.rs
+++ b/crates/ra_hir_def/src/expr.rs
@@ -19,7 +19,7 @@ use ra_syntax::ast::RangeOp;
19use crate::{ 19use crate::{
20 builtin_type::{BuiltinFloat, BuiltinInt}, 20 builtin_type::{BuiltinFloat, BuiltinInt},
21 path::{GenericArgs, Path}, 21 path::{GenericArgs, Path},
22 type_ref::{Mutability, TypeRef}, 22 type_ref::{Mutability, Rawness, TypeRef},
23}; 23};
24 24
25pub type ExprId = Idx<Expr>; 25pub type ExprId = Idx<Expr>;
@@ -110,6 +110,7 @@ pub enum Expr {
110 }, 110 },
111 Ref { 111 Ref {
112 expr: ExprId, 112 expr: ExprId,
113 rawness: Rawness,
113 mutability: Mutability, 114 mutability: Mutability,
114 }, 115 },
115 Box { 116 Box {
diff --git a/crates/ra_hir_def/src/type_ref.rs b/crates/ra_hir_def/src/type_ref.rs
index 5bdad9efd..86a77b704 100644
--- a/crates/ra_hir_def/src/type_ref.rs
+++ b/crates/ra_hir_def/src/type_ref.rs
@@ -35,6 +35,22 @@ impl Mutability {
35 } 35 }
36} 36}
37 37
38#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
39pub enum Rawness {
40 RawPtr,
41 Ref,
42}
43
44impl Rawness {
45 pub fn from_raw(is_raw: bool) -> Rawness {
46 if is_raw {
47 Rawness::RawPtr
48 } else {
49 Rawness::Ref
50 }
51 }
52}
53
38/// Compare ty::Ty 54/// Compare ty::Ty
39#[derive(Clone, PartialEq, Eq, Hash, Debug)] 55#[derive(Clone, PartialEq, Eq, Hash, Debug)]
40pub enum TypeRef { 56pub enum TypeRef {
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index b28724f0e..54bab3476 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -17,8 +17,8 @@ use crate::{
17 autoderef, method_resolution, op, 17 autoderef, method_resolution, op,
18 traits::InEnvironment, 18 traits::InEnvironment,
19 utils::{generics, variant_data, Generics}, 19 utils::{generics, variant_data, Generics},
20 ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef, 20 ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Rawness, Substs,
21 Ty, TypeCtor, Uncertain, 21 TraitRef, Ty, TypeCtor, Uncertain,
22}; 22};
23 23
24use super::{ 24use super::{
@@ -350,19 +350,28 @@ impl<'a> InferenceContext<'a> {
350 // FIXME check the cast... 350 // FIXME check the cast...
351 cast_ty 351 cast_ty
352 } 352 }
353 Expr::Ref { expr, mutability } => { 353 Expr::Ref { expr, rawness, mutability } => {
354 let expectation = 354 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) =
355 if let Some((exp_inner, exp_mutability)) = &expected.ty.as_reference() { 355 &expected.ty.as_reference_or_ptr()
356 if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { 356 {
357 // FIXME: throw type error - expected mut reference but found shared ref, 357 if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared {
358 // which cannot be coerced 358 // FIXME: throw type error - expected mut reference but found shared ref,
359 } 359 // which cannot be coerced
360 Expectation::rvalue_hint(Ty::clone(exp_inner)) 360 }
361 } else { 361 if *exp_rawness == Rawness::Ref && *rawness == Rawness::RawPtr {
362 Expectation::none() 362 // FIXME: throw type error - expected reference but found ptr,
363 }; 363 // which cannot be coerced
364 }
365 Expectation::rvalue_hint(Ty::clone(exp_inner))
366 } else {
367 Expectation::none()
368 };
364 let inner_ty = self.infer_expr_inner(*expr, &expectation); 369 let inner_ty = self.infer_expr_inner(*expr, &expectation);
365 Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) 370 let ty = match rawness {
371 Rawness::RawPtr => TypeCtor::RawPtr(*mutability),
372 Rawness::Ref => TypeCtor::Ref(*mutability),
373 };
374 Ty::apply_one(ty, inner_ty)
366 } 375 }
367 Expr::Box { expr } => { 376 Expr::Box { expr } => {
368 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 377 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index 93cb45a64..9fa8d3bdc 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -49,8 +49,10 @@ use std::sync::Arc;
49use std::{iter, mem}; 49use std::{iter, mem};
50 50
51use hir_def::{ 51use hir_def::{
52 expr::ExprId, type_ref::Mutability, AdtId, AssocContainerId, DefWithBodyId, GenericDefId, 52 expr::ExprId,
53 HasModule, Lookup, TraitId, TypeAliasId, TypeParamId, 53 type_ref::{Mutability, Rawness},
54 AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId,
55 TypeParamId,
54}; 56};
55use ra_db::{impl_intern_key, salsa, CrateId}; 57use ra_db::{impl_intern_key, salsa, CrateId};
56 58
@@ -709,6 +711,18 @@ impl Ty {
709 } 711 }
710 } 712 }
711 713
714 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
715 match self {
716 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => {
717 Some((parameters.as_single(), Rawness::Ref, *mutability))
718 }
719 Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => {
720 Some((parameters.as_single(), Rawness::RawPtr, *mutability))
721 }
722 _ => None,
723 }
724 }
725
712 pub fn strip_references(&self) -> &Ty { 726 pub fn strip_references(&self) -> &Ty {
713 let mut t: &Ty = self; 727 let mut t: &Ty = self;
714 728
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs
index 2cc4f4bf9..6f777ed8c 100644
--- a/crates/ra_hir_ty/src/tests/coercion.rs
+++ b/crates/ra_hir_ty/src/tests/coercion.rs
@@ -116,15 +116,20 @@ fn infer_let_stmt_coerce() {
116 assert_snapshot!( 116 assert_snapshot!(
117 infer(r#" 117 infer(r#"
118fn test() { 118fn test() {
119 let x: &[i32] = &[1]; 119 let x: &[isize] = &[1];
120 let x: *const [isize] = &[1];
120} 121}
121"#), 122"#),
122 @r###" 123 @r###"
123 11..40 '{ ...[1]; }': () 124 11..76 '{ ...[1]; }': ()
124 21..22 'x': &[i32] 125 21..22 'x': &[isize]
125 33..37 '&[1]': &[i32; _] 126 35..39 '&[1]': &[isize; _]
126 34..37 '[1]': [i32; _] 127 36..39 '[1]': [isize; _]
127 35..36 '1': i32 128 37..38 '1': isize
129 49..50 'x': *const [isize]
130 69..73 '&[1]': &[isize; _]
131 70..73 '[1]': [isize; _]
132 71..72 '1': isize
128 "###); 133 "###);
129} 134}
130 135
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs
index fd2208af2..f1db34160 100644
--- a/crates/ra_hir_ty/src/tests/simple.rs
+++ b/crates/ra_hir_ty/src/tests/simple.rs
@@ -385,6 +385,26 @@ fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) {
385} 385}
386 386
387#[test] 387#[test]
388fn infer_raw_ref() {
389 assert_snapshot!(
390 infer(r#"
391fn test(a: i32) {
392 &raw mut a;
393 &raw const a;
394}
395"#),
396 @r###"
397 9..10 'a': i32
398 17..54 '{ ...t a; }': ()
399 23..33 '&raw mut a': *mut i32
400 32..33 'a': i32
401 39..51 '&raw const a': *const i32
402 50..51 'a': i32
403 "###
404 );
405}
406
407#[test]
388fn infer_literals() { 408fn infer_literals() {
389 assert_snapshot!( 409 assert_snapshot!(
390 infer(r##" 410 infer(r##"
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index 34f039768..d6e8df32a 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -325,13 +325,27 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)>
325 let kind = match p.current() { 325 let kind = match p.current() {
326 // test ref_expr 326 // test ref_expr
327 // fn foo() { 327 // fn foo() {
328 // // reference operator
328 // let _ = &1; 329 // let _ = &1;
329 // let _ = &mut &f(); 330 // let _ = &mut &f();
331 // let _ = &raw;
332 // let _ = &raw.0;
333 // // raw reference operator
334 // let _ = &raw mut foo;
335 // let _ = &raw const foo;
330 // } 336 // }
331 T![&] => { 337 T![&] => {
332 m = p.start(); 338 m = p.start();
333 p.bump(T![&]); 339 p.bump(T![&]);
334 p.eat(T![mut]); 340 if p.at(IDENT)
341 && p.at_contextual_kw("raw")
342 && (p.nth_at(1, T![mut]) || p.nth_at(1, T![const]))
343 {
344 p.bump_remap(T![raw]);
345 p.bump_any();
346 } else {
347 p.eat(T![mut]);
348 }
335 REF_EXPR 349 REF_EXPR
336 } 350 }
337 // test unary_expr 351 // test unary_expr
diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs
index cf6067e57..255402fbc 100644
--- a/crates/ra_syntax/src/ast/generated/nodes.rs
+++ b/crates/ra_syntax/src/ast/generated/nodes.rs
@@ -1235,6 +1235,8 @@ impl CastExpr {
1235/// ``` 1235/// ```
1236/// ❰ &foo ❱; 1236/// ❰ &foo ❱;
1237/// ❰ &mut bar ❱; 1237/// ❰ &mut bar ❱;
1238/// ❰ &raw const bar ❱;
1239/// ❰ &raw mut bar ❱;
1238/// ``` 1240/// ```
1239/// 1241///
1240/// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#borrow-operators) 1242/// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#borrow-operators)
@@ -1247,6 +1249,7 @@ impl RefExpr {
1247 pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) } 1249 pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) }
1248 pub fn raw_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![raw]) } 1250 pub fn raw_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![raw]) }
1249 pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) } 1251 pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
1252 pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
1250 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } 1253 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
1251} 1254}
1252/// Prefix operator call. This is either `!` or `*` or `-`. 1255/// Prefix operator call. This is either `!` or `*` or `-`.
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rast b/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rast
index 7fe96e17d..58bdf7e34 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rast
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rast
@@ -1,5 +1,5 @@
1SOURCE_FILE@0..52 1[email protected]00
2 FN_DEF@0..51 2 [email protected]99
3 [email protected] "fn" 3 [email protected] "fn"
4 [email protected] " " 4 [email protected] " "
5 [email protected] 5 [email protected]
@@ -8,47 +8,131 @@ [email protected]
8 [email protected] "(" 8 [email protected] "("
9 [email protected] ")" 9 [email protected] ")"
10 [email protected] " " 10 [email protected] " "
11 BLOCK_EXPR@9..51 11 [email protected]99
12 [email protected] "{" 12 [email protected] "{"
13 [email protected] "\n " 13 [email protected] "\n "
14 [email protected] 14 [email protected] "// reference operator"
15 [email protected] "let" 15 [email protected] "\n "
16 [email protected] " " 16 [email protected]
17 [email protected] 17 [email protected] "let"
18 [email protected] "_" 18 [email protected] " "
19 [email protected] " " 19 [email protected]
20 [email protected] "=" 20 [email protected] "_"
21 [email protected] " " 21 [email protected] " "
22 [email protected] 22 [email protected] "="
23 [email protected] "&" 23 [email protected] " "
24 [email protected] 24 [email protected]
25 [email protected] "1" 25 [email protected] "&"
26 [email protected] ";" 26 [email protected]
27 [email protected] "\n " 27 [email protected] "1"
28 [email protected] 28 [email protected] ";"
29 [email protected] "let" 29 [email protected] "\n "
30 [email protected] " " 30 [email protected]
31 [email protected] 31 [email protected] "let"
32 [email protected] "_" 32 [email protected] " "
33 [email protected] " " 33 [email protected]
34 [email protected] "=" 34 [email protected] "_"
35 [email protected] " " 35 [email protected] " "
36 [email protected] 36 [email protected] "="
37 [email protected] "&" 37 [email protected] " "
38 [email protected] "mut" 38 [email protected]
39 [email protected] " " 39 [email protected] "&"
40 [email protected] 40 [email protected] "mut"
41 [email protected] "&" 41 [email protected] " "
42 [email protected] 42 [email protected]
43 [email protected] 43 [email protected] "&"
44 [email protected] 44 [email protected]
45 [email protected] 45 [email protected]
46 [email protected] 46 [email protected]
47 [email protected] "f" 47 [email protected]
48 [email protected] 48 [email protected]
49 [email protected] "(" 49 [email protected] "f"
50 [email protected] ")" 50 [email protected]
51 [email protected] ";" 51 [email protected] "("
52 [email protected] "\n" 52 [email protected] ")"
53 [email protected] "}" 53 [email protected] ";"
54 [email protected] "\n" 54 [email protected] "\n "
55 [email protected]
56 [email protected] "let"
57 [email protected] " "
58 [email protected]
59 [email protected] "_"
60 [email protected] " "
61 [email protected] "="
62 [email protected] " "
63 [email protected]
64 [email protected] "&"
65 [email protected]
66 [email protected]
67 [email protected]
68 [email protected]
69 [email protected] "raw"
70 [email protected] ";"
71 [email protected] "\n "
72 [email protected]
73 [email protected] "let"
74 [email protected] " "
75 [email protected]
76 [email protected] "_"
77 [email protected] " "
78 [email protected] "="
79 [email protected] " "
80 [email protected]
81 [email protected] "&"
82 [email protected]
83 [email protected]
84 [email protected]
85 [email protected]
86 [email protected]
87 [email protected] "raw"
88 [email protected] "."
89 [email protected]
90 [email protected] "0"
91 [email protected] ";"
92 [email protected] "\n "
93 [email protected] "// raw reference oper ..."
94 [email protected] "\n "
95 [email protected]
96 [email protected] "let"
97 [email protected] " "
98 [email protected]
99 [email protected] "_"
100 [email protected] " "
101 [email protected] "="
102 [email protected] " "
103 [email protected]
104 [email protected] "&"
105 [email protected] "raw"
106 [email protected] " "
107 [email protected] "mut"
108 [email protected] " "
109 [email protected]
110 [email protected]
111 [email protected]
112 [email protected]
113 [email protected] "foo"
114 [email protected] ";"
115 [email protected] "\n "
116 [email protected]
117 [email protected] "let"
118 [email protected] " "
119 [email protected]
120 [email protected] "_"
121 [email protected] " "
122 [email protected] "="
123 [email protected] " "
124 [email protected]
125 [email protected] "&"
126 [email protected] "raw"
127 [email protected] " "
128 [email protected] "const"
129 [email protected] " "
130 [email protected]
131 [email protected]
132 [email protected]
133 [email protected]
134 [email protected] "foo"
135 [email protected] ";"
136 [email protected] "\n"
137 [email protected] "}"
138 [email protected] "\n"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rs b/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rs
index 2dac6be95..c5262f446 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rs
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0082_ref_expr.rs
@@ -1,4 +1,10 @@
1fn foo() { 1fn foo() {
2 // reference operator
2 let _ = &1; 3 let _ = &1;
3 let _ = &mut &f(); 4 let _ = &mut &f();
5 let _ = &raw;
6 let _ = &raw.0;
7 // raw reference operator
8 let _ = &raw mut foo;
9 let _ = &raw const foo;
4} 10}
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index 394a7bc88..d4621930e 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -1153,10 +1153,12 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
1153 /// ``` 1153 /// ```
1154 /// ❰ &foo ❱; 1154 /// ❰ &foo ❱;
1155 /// ❰ &mut bar ❱; 1155 /// ❰ &mut bar ❱;
1156 /// ❰ &raw const bar ❱;
1157 /// ❰ &raw mut bar ❱;
1156 /// ``` 1158 /// ```
1157 /// 1159 ///
1158 /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#borrow-operators) 1160 /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#borrow-operators)
1159 struct RefExpr: AttrsOwner { T![&], T![raw], T![mut], Expr } 1161 struct RefExpr: AttrsOwner { T![&], T![raw], T![mut], T![const], Expr }
1160 1162
1161 /// Prefix operator call. This is either `!` or `*` or `-`. 1163 /// Prefix operator call. This is either `!` or `*` or `-`.
1162 /// 1164 ///