aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
authorMikhail Rakhmanov <[email protected]>2020-06-03 19:10:54 +0100
committerMikhail Rakhmanov <[email protected]>2020-06-03 19:10:54 +0100
commiteefa10bc6bff3624ddd0bbb6bc89d8beb4bed186 (patch)
tree15c38c2993c52f4065d338090ca9185cc1fcd3da /crates/ra_hir_def
parenta9d567584857b1be4ca8eaa5ef2c7d85f7b2845e (diff)
parent794f6da821c5d6e2490b996baffe162e4753262d (diff)
Merge branch 'master' into assists_extract_enum
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/src/attr.rs10
-rw-r--r--crates/ra_hir_def/src/body.rs2
-rw-r--r--crates/ra_hir_def/src/body/lower.rs87
-rw-r--r--crates/ra_hir_def/src/body/scope.rs4
-rw-r--r--crates/ra_hir_def/src/data.rs6
-rw-r--r--crates/ra_hir_def/src/docs.rs50
-rw-r--r--crates/ra_hir_def/src/expr.rs22
-rw-r--r--crates/ra_hir_def/src/lang_item.rs2
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs2
-rw-r--r--crates/ra_hir_def/src/type_ref.rs16
10 files changed, 169 insertions, 32 deletions
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index 576cd0c65..2eeba0572 100644
--- a/crates/ra_hir_def/src/attr.rs
+++ b/crates/ra_hir_def/src/attr.rs
@@ -81,18 +81,24 @@ impl Attrs {
81 } 81 }
82 } 82 }
83 83
84 fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Attrs { 84 pub fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Attrs {
85 let hygiene = Hygiene::new(db.upcast(), owner.file_id); 85 let hygiene = Hygiene::new(db.upcast(), owner.file_id);
86 Attrs::new(owner.value, &hygiene) 86 Attrs::new(owner.value, &hygiene)
87 } 87 }
88 88
89 pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs { 89 pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs {
90 let docs = ast::CommentIter::from_syntax_node(owner.syntax()).doc_comment_text().map(
91 |docs_text| Attr {
92 input: Some(AttrInput::Literal(SmolStr::new(docs_text))),
93 path: ModPath::from(hir_expand::name!(doc)),
94 },
95 );
90 let mut attrs = owner.attrs().peekable(); 96 let mut attrs = owner.attrs().peekable();
91 let entries = if attrs.peek().is_none() { 97 let entries = if attrs.peek().is_none() {
92 // Avoid heap allocation 98 // Avoid heap allocation
93 None 99 None
94 } else { 100 } else {
95 Some(attrs.flat_map(|ast| Attr::from_src(ast, hygiene)).collect()) 101 Some(attrs.flat_map(|ast| Attr::from_src(ast, hygiene)).chain(docs).collect())
96 }; 102 };
97 Attrs { entries } 103 Attrs { entries }
98 } 104 }
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index f5a7305dc..273036cee 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -29,7 +29,7 @@ use crate::{
29 AsMacroCall, DefWithBodyId, HasModule, Lookup, ModuleId, 29 AsMacroCall, DefWithBodyId, HasModule, Lookup, ModuleId,
30}; 30};
31 31
32/// A subset of Exander that only deals with cfg attributes. We only need it to 32/// A subset of Expander that only deals with cfg attributes. We only need it to
33/// avoid cyclic queries in crate def map during enum processing. 33/// avoid cyclic queries in crate def map during enum processing.
34pub(crate) struct CfgExpander { 34pub(crate) struct CfgExpander {
35 cfg_options: CfgOptions, 35 cfg_options: CfgOptions,
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index e08d62dd6..f159f80af 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};
@@ -134,7 +134,7 @@ impl ExprCollector<'_> {
134 self.make_expr(expr, Err(SyntheticSyntax)) 134 self.make_expr(expr, Err(SyntheticSyntax))
135 } 135 }
136 fn empty_block(&mut self) -> ExprId { 136 fn empty_block(&mut self) -> ExprId {
137 self.alloc_expr_desugared(Expr::Block { statements: Vec::new(), tail: None }) 137 self.alloc_expr_desugared(Expr::Block { statements: Vec::new(), tail: None, label: None })
138 } 138 }
139 fn missing_expr(&mut self) -> ExprId { 139 fn missing_expr(&mut self) -> ExprId {
140 self.alloc_expr_desugared(Expr::Missing) 140 self.alloc_expr_desugared(Expr::Missing)
@@ -215,7 +215,16 @@ impl ExprCollector<'_> {
215 ast::Expr::BlockExpr(e) => self.collect_block(e), 215 ast::Expr::BlockExpr(e) => self.collect_block(e),
216 ast::Expr::LoopExpr(e) => { 216 ast::Expr::LoopExpr(e) => {
217 let body = self.collect_block_opt(e.loop_body()); 217 let body = self.collect_block_opt(e.loop_body());
218 self.alloc_expr(Expr::Loop { body }, syntax_ptr) 218 self.alloc_expr(
219 Expr::Loop {
220 body,
221 label: e
222 .label()
223 .and_then(|l| l.lifetime_token())
224 .map(|l| Name::new_lifetime(&l)),
225 },
226 syntax_ptr,
227 )
219 } 228 }
220 ast::Expr::WhileExpr(e) => { 229 ast::Expr::WhileExpr(e) => {
221 let body = self.collect_block_opt(e.loop_body()); 230 let body = self.collect_block_opt(e.loop_body());
@@ -230,25 +239,56 @@ impl ExprCollector<'_> {
230 let pat = self.collect_pat(pat); 239 let pat = self.collect_pat(pat);
231 let match_expr = self.collect_expr_opt(condition.expr()); 240 let match_expr = self.collect_expr_opt(condition.expr());
232 let placeholder_pat = self.missing_pat(); 241 let placeholder_pat = self.missing_pat();
233 let break_ = self.alloc_expr_desugared(Expr::Break { expr: None }); 242 let break_ =
243 self.alloc_expr_desugared(Expr::Break { expr: None, label: None });
234 let arms = vec![ 244 let arms = vec![
235 MatchArm { pat, expr: body, guard: None }, 245 MatchArm { pat, expr: body, guard: None },
236 MatchArm { pat: placeholder_pat, expr: break_, guard: None }, 246 MatchArm { pat: placeholder_pat, expr: break_, guard: None },
237 ]; 247 ];
238 let match_expr = 248 let match_expr =
239 self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms }); 249 self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms });
240 return self.alloc_expr(Expr::Loop { body: match_expr }, syntax_ptr); 250 return self.alloc_expr(
251 Expr::Loop {
252 body: match_expr,
253 label: e
254 .label()
255 .and_then(|l| l.lifetime_token())
256 .map(|l| Name::new_lifetime(&l)),
257 },
258 syntax_ptr,
259 );
241 } 260 }
242 }, 261 },
243 }; 262 };
244 263
245 self.alloc_expr(Expr::While { condition, body }, syntax_ptr) 264 self.alloc_expr(
265 Expr::While {
266 condition,
267 body,
268 label: e
269 .label()
270 .and_then(|l| l.lifetime_token())
271 .map(|l| Name::new_lifetime(&l)),
272 },
273 syntax_ptr,
274 )
246 } 275 }
247 ast::Expr::ForExpr(e) => { 276 ast::Expr::ForExpr(e) => {
248 let iterable = self.collect_expr_opt(e.iterable()); 277 let iterable = self.collect_expr_opt(e.iterable());
249 let pat = self.collect_pat_opt(e.pat()); 278 let pat = self.collect_pat_opt(e.pat());
250 let body = self.collect_block_opt(e.loop_body()); 279 let body = self.collect_block_opt(e.loop_body());
251 self.alloc_expr(Expr::For { iterable, pat, body }, syntax_ptr) 280 self.alloc_expr(
281 Expr::For {
282 iterable,
283 pat,
284 body,
285 label: e
286 .label()
287 .and_then(|l| l.lifetime_token())
288 .map(|l| Name::new_lifetime(&l)),
289 },
290 syntax_ptr,
291 )
252 } 292 }
253 ast::Expr::CallExpr(e) => { 293 ast::Expr::CallExpr(e) => {
254 let callee = self.collect_expr_opt(e.expr()); 294 let callee = self.collect_expr_opt(e.expr());
@@ -301,13 +341,16 @@ impl ExprCollector<'_> {
301 .unwrap_or(Expr::Missing); 341 .unwrap_or(Expr::Missing);
302 self.alloc_expr(path, syntax_ptr) 342 self.alloc_expr(path, syntax_ptr)
303 } 343 }
304 ast::Expr::ContinueExpr(_e) => { 344 ast::Expr::ContinueExpr(e) => self.alloc_expr(
305 // FIXME: labels 345 Expr::Continue { label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) },
306 self.alloc_expr(Expr::Continue, syntax_ptr) 346 syntax_ptr,
307 } 347 ),
308 ast::Expr::BreakExpr(e) => { 348 ast::Expr::BreakExpr(e) => {
309 let expr = e.expr().map(|e| self.collect_expr(e)); 349 let expr = e.expr().map(|e| self.collect_expr(e));
310 self.alloc_expr(Expr::Break { expr }, syntax_ptr) 350 self.alloc_expr(
351 Expr::Break { expr, label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) },
352 syntax_ptr,
353 )
311 } 354 }
312 ast::Expr::ParenExpr(e) => { 355 ast::Expr::ParenExpr(e) => {
313 let inner = self.collect_expr_opt(e.expr()); 356 let inner = self.collect_expr_opt(e.expr());
@@ -378,8 +421,21 @@ impl ExprCollector<'_> {
378 } 421 }
379 ast::Expr::RefExpr(e) => { 422 ast::Expr::RefExpr(e) => {
380 let expr = self.collect_expr_opt(e.expr()); 423 let expr = self.collect_expr_opt(e.expr());
381 let mutability = Mutability::from_mutable(e.mut_token().is_some()); 424 let raw_tok = e.raw_token().is_some();
382 self.alloc_expr(Expr::Ref { expr, mutability }, syntax_ptr) 425 let mutability = if raw_tok {
426 if e.mut_token().is_some() {
427 Mutability::Mut
428 } else if e.const_token().is_some() {
429 Mutability::Shared
430 } else {
431 unreachable!("parser only remaps to raw_token() if matching mutability token follows")
432 }
433 } else {
434 Mutability::from_mutable(e.mut_token().is_some())
435 };
436 let rawness = Rawness::from_raw(raw_tok);
437
438 self.alloc_expr(Expr::Ref { expr, rawness, mutability }, syntax_ptr)
383 } 439 }
384 ast::Expr::PrefixExpr(e) => { 440 ast::Expr::PrefixExpr(e) => {
385 let expr = self.collect_expr_opt(e.expr()); 441 let expr = self.collect_expr_opt(e.expr());
@@ -516,7 +572,8 @@ impl ExprCollector<'_> {
516 }) 572 })
517 .collect(); 573 .collect();
518 let tail = block.expr().map(|e| self.collect_expr(e)); 574 let tail = block.expr().map(|e| self.collect_expr(e));
519 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) 575 let label = block.label().and_then(|l| l.lifetime_token()).map(|t| Name::new_lifetime(&t));
576 self.alloc_expr(Expr::Block { statements, tail, label }, syntax_node_ptr)
520 } 577 }
521 578
522 fn collect_block_items(&mut self, block: &ast::BlockExpr) { 579 fn collect_block_items(&mut self, block: &ast::BlockExpr) {
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs
index 09e92b74e..e48ff38f9 100644
--- a/crates/ra_hir_def/src/body/scope.rs
+++ b/crates/ra_hir_def/src/body/scope.rs
@@ -138,10 +138,10 @@ fn compute_block_scopes(
138fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope: ScopeId) { 138fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope: ScopeId) {
139 scopes.set_scope(expr, scope); 139 scopes.set_scope(expr, scope);
140 match &body[expr] { 140 match &body[expr] {
141 Expr::Block { statements, tail } => { 141 Expr::Block { statements, tail, .. } => {
142 compute_block_scopes(&statements, *tail, body, scopes, scope); 142 compute_block_scopes(&statements, *tail, body, scopes, scope);
143 } 143 }
144 Expr::For { iterable, pat, body: body_expr } => { 144 Expr::For { iterable, pat, body: body_expr, .. } => {
145 compute_expr_scopes(*iterable, body, scopes, scope); 145 compute_expr_scopes(*iterable, body, scopes, scope);
146 let scope = scopes.new_scope(scope); 146 let scope = scopes.new_scope(scope);
147 scopes.add_bindings(body, scope, *pat); 147 scopes.add_bindings(body, scope, *pat);
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
index e2130d931..807195d25 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -34,6 +34,7 @@ pub struct FunctionData {
34 /// True if the first param is `self`. This is relevant to decide whether this 34 /// True if the first param is `self`. This is relevant to decide whether this
35 /// can be called as a method. 35 /// can be called as a method.
36 pub has_self_param: bool, 36 pub has_self_param: bool,
37 pub is_unsafe: bool,
37 pub visibility: RawVisibility, 38 pub visibility: RawVisibility,
38} 39}
39 40
@@ -85,11 +86,14 @@ impl FunctionData {
85 ret_type 86 ret_type
86 }; 87 };
87 88
89 let is_unsafe = src.value.unsafe_token().is_some();
90
88 let vis_default = RawVisibility::default_for_container(loc.container); 91 let vis_default = RawVisibility::default_for_container(loc.container);
89 let visibility = 92 let visibility =
90 RawVisibility::from_ast_with_default(db, vis_default, src.map(|s| s.visibility())); 93 RawVisibility::from_ast_with_default(db, vis_default, src.map(|s| s.visibility()));
91 94
92 let sig = FunctionData { name, params, ret_type, has_self_param, visibility, attrs }; 95 let sig =
96 FunctionData { name, params, ret_type, has_self_param, is_unsafe, visibility, attrs };
93 Arc::new(sig) 97 Arc::new(sig)
94 } 98 }
95} 99}
diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs
index b221ae1ce..2630b3d89 100644
--- a/crates/ra_hir_def/src/docs.rs
+++ b/crates/ra_hir_def/src/docs.rs
@@ -29,6 +29,13 @@ impl Documentation {
29 Documentation(s.into()) 29 Documentation(s.into())
30 } 30 }
31 31
32 pub fn from_ast<N>(node: &N) -> Option<Documentation>
33 where
34 N: ast::DocCommentsOwner + ast::AttrsOwner,
35 {
36 docs_from_ast(node)
37 }
38
32 pub fn as_str(&self) -> &str { 39 pub fn as_str(&self) -> &str {
33 &*self.0 40 &*self.0
34 } 41 }
@@ -70,6 +77,45 @@ impl Documentation {
70 } 77 }
71} 78}
72 79
73pub(crate) fn docs_from_ast(node: &impl ast::DocCommentsOwner) -> Option<Documentation> { 80pub(crate) fn docs_from_ast<N>(node: &N) -> Option<Documentation>
74 node.doc_comment_text().map(|it| Documentation::new(&it)) 81where
82 N: ast::DocCommentsOwner + ast::AttrsOwner,
83{
84 let doc_comment_text = node.doc_comment_text();
85 let doc_attr_text = expand_doc_attrs(node);
86 let docs = merge_doc_comments_and_attrs(doc_comment_text, doc_attr_text);
87 docs.map(|it| Documentation::new(&it))
88}
89
90fn merge_doc_comments_and_attrs(
91 doc_comment_text: Option<String>,
92 doc_attr_text: Option<String>,
93) -> Option<String> {
94 match (doc_comment_text, doc_attr_text) {
95 (Some(mut comment_text), Some(attr_text)) => {
96 comment_text.push_str("\n\n");
97 comment_text.push_str(&attr_text);
98 Some(comment_text)
99 }
100 (Some(comment_text), None) => Some(comment_text),
101 (None, Some(attr_text)) => Some(attr_text),
102 (None, None) => None,
103 }
104}
105
106fn expand_doc_attrs(owner: &dyn ast::AttrsOwner) -> Option<String> {
107 let mut docs = String::new();
108 for attr in owner.attrs() {
109 if let Some(("doc", value)) =
110 attr.as_simple_key_value().as_ref().map(|(k, v)| (k.as_str(), v.as_str()))
111 {
112 docs.push_str(value);
113 docs.push_str("\n\n");
114 }
115 }
116 if docs.is_empty() {
117 None
118 } else {
119 Some(docs.trim_end_matches("\n\n").to_owned())
120 }
75} 121}
diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs
index a0cdad529..ca49b26d1 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>;
@@ -52,18 +52,22 @@ pub enum Expr {
52 Block { 52 Block {
53 statements: Vec<Statement>, 53 statements: Vec<Statement>,
54 tail: Option<ExprId>, 54 tail: Option<ExprId>,
55 label: Option<Name>,
55 }, 56 },
56 Loop { 57 Loop {
57 body: ExprId, 58 body: ExprId,
59 label: Option<Name>,
58 }, 60 },
59 While { 61 While {
60 condition: ExprId, 62 condition: ExprId,
61 body: ExprId, 63 body: ExprId,
64 label: Option<Name>,
62 }, 65 },
63 For { 66 For {
64 iterable: ExprId, 67 iterable: ExprId,
65 pat: PatId, 68 pat: PatId,
66 body: ExprId, 69 body: ExprId,
70 label: Option<Name>,
67 }, 71 },
68 Call { 72 Call {
69 callee: ExprId, 73 callee: ExprId,
@@ -79,9 +83,12 @@ pub enum Expr {
79 expr: ExprId, 83 expr: ExprId,
80 arms: Vec<MatchArm>, 84 arms: Vec<MatchArm>,
81 }, 85 },
82 Continue, 86 Continue {
87 label: Option<Name>,
88 },
83 Break { 89 Break {
84 expr: Option<ExprId>, 90 expr: Option<ExprId>,
91 label: Option<Name>,
85 }, 92 },
86 Return { 93 Return {
87 expr: Option<ExprId>, 94 expr: Option<ExprId>,
@@ -110,6 +117,7 @@ pub enum Expr {
110 }, 117 },
111 Ref { 118 Ref {
112 expr: ExprId, 119 expr: ExprId,
120 rawness: Rawness,
113 mutability: Mutability, 121 mutability: Mutability,
114 }, 122 },
115 Box { 123 Box {
@@ -224,7 +232,7 @@ impl Expr {
224 f(*else_branch); 232 f(*else_branch);
225 } 233 }
226 } 234 }
227 Expr::Block { statements, tail } => { 235 Expr::Block { statements, tail, .. } => {
228 for stmt in statements { 236 for stmt in statements {
229 match stmt { 237 match stmt {
230 Statement::Let { initializer, .. } => { 238 Statement::Let { initializer, .. } => {
@@ -240,8 +248,8 @@ impl Expr {
240 } 248 }
241 } 249 }
242 Expr::TryBlock { body } => f(*body), 250 Expr::TryBlock { body } => f(*body),
243 Expr::Loop { body } => f(*body), 251 Expr::Loop { body, .. } => f(*body),
244 Expr::While { condition, body } => { 252 Expr::While { condition, body, .. } => {
245 f(*condition); 253 f(*condition);
246 f(*body); 254 f(*body);
247 } 255 }
@@ -267,8 +275,8 @@ impl Expr {
267 f(arm.expr); 275 f(arm.expr);
268 } 276 }
269 } 277 }
270 Expr::Continue => {} 278 Expr::Continue { .. } => {}
271 Expr::Break { expr } | Expr::Return { expr } => { 279 Expr::Break { expr, .. } | Expr::Return { expr } => {
272 if let Some(expr) = expr { 280 if let Some(expr) = expr {
273 f(*expr); 281 f(*expr);
274 } 282 }
diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs
index d962db3cc..3516784b8 100644
--- a/crates/ra_hir_def/src/lang_item.rs
+++ b/crates/ra_hir_def/src/lang_item.rs
@@ -164,7 +164,7 @@ impl LangItems {
164 T: Into<AttrDefId> + Copy, 164 T: Into<AttrDefId> + Copy,
165 { 165 {
166 if let Some(lang_item_name) = lang_attr(db, item) { 166 if let Some(lang_item_name) = lang_attr(db, item) {
167 self.items.entry(lang_item_name.clone()).or_insert_with(|| constructor(item)); 167 self.items.entry(lang_item_name).or_insert_with(|| constructor(item));
168 } 168 }
169 } 169 }
170} 170}
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index 4e628b14d..f44baa579 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -175,7 +175,7 @@ pub(super) enum DefKind {
175} 175}
176 176
177impl DefKind { 177impl DefKind {
178 pub fn ast_id(&self) -> FileAstId<ast::ModuleItem> { 178 pub fn ast_id(self) -> FileAstId<ast::ModuleItem> {
179 match self { 179 match self {
180 DefKind::Function(it) => it.upcast(), 180 DefKind::Function(it) => it.upcast(),
181 DefKind::Struct(it, _) => it.upcast(), 181 DefKind::Struct(it, _) => it.upcast(),
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 {