aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/body/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/body/lower.rs')
-rw-r--r--crates/ra_hir_def/src/body/lower.rs63
1 files changed, 38 insertions, 25 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index e9dd65b0a..e08d62dd6 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -15,7 +15,7 @@ use ra_syntax::{
15 }, 15 },
16 AstNode, AstPtr, 16 AstNode, AstPtr,
17}; 17};
18use test_utils::tested_by; 18use test_utils::mark;
19 19
20use crate::{ 20use crate::{
21 adt::StructKind, 21 adt::StructKind,
@@ -60,13 +60,10 @@ pub(super) fn lower(
60 params: Option<ast::ParamList>, 60 params: Option<ast::ParamList>,
61 body: Option<ast::Expr>, 61 body: Option<ast::Expr>,
62) -> (Body, BodySourceMap) { 62) -> (Body, BodySourceMap) {
63 let ctx = LowerCtx::new(db, expander.current_file_id.clone());
64
65 ExprCollector { 63 ExprCollector {
66 db, 64 db,
67 def, 65 def,
68 expander, 66 expander,
69 ctx,
70 source_map: BodySourceMap::default(), 67 source_map: BodySourceMap::default(),
71 body: Body { 68 body: Body {
72 exprs: Arena::default(), 69 exprs: Arena::default(),
@@ -83,7 +80,6 @@ struct ExprCollector<'a> {
83 db: &'a dyn DefDatabase, 80 db: &'a dyn DefDatabase,
84 def: DefWithBodyId, 81 def: DefWithBodyId,
85 expander: Expander, 82 expander: Expander,
86 ctx: LowerCtx,
87 body: Body, 83 body: Body,
88 source_map: BodySourceMap, 84 source_map: BodySourceMap,
89} 85}
@@ -122,6 +118,10 @@ impl ExprCollector<'_> {
122 (self.body, self.source_map) 118 (self.body, self.source_map)
123 } 119 }
124 120
121 fn ctx(&self) -> LowerCtx {
122 LowerCtx::new(self.db, self.expander.current_file_id)
123 }
124
125 fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId { 125 fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId {
126 let src = self.expander.to_source(ptr); 126 let src = self.expander.to_source(ptr);
127 let id = self.make_expr(expr, Ok(src.clone())); 127 let id = self.make_expr(expr, Ok(src.clone()));
@@ -162,8 +162,7 @@ impl ExprCollector<'_> {
162 162
163 fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { 163 fn collect_expr(&mut self, expr: ast::Expr) -> ExprId {
164 let syntax_ptr = AstPtr::new(&expr); 164 let syntax_ptr = AstPtr::new(&expr);
165 let attrs = self.expander.parse_attrs(&expr); 165 if !self.expander.is_cfg_enabled(&expr) {
166 if !self.expander.is_cfg_enabled(&attrs) {
167 return self.missing_expr(); 166 return self.missing_expr();
168 } 167 }
169 match expr { 168 match expr {
@@ -203,6 +202,16 @@ impl ExprCollector<'_> {
203 202
204 self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) 203 self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr)
205 } 204 }
205 ast::Expr::EffectExpr(e) => match e.effect() {
206 ast::Effect::Try(_) => {
207 let body = self.collect_block_opt(e.block_expr());
208 self.alloc_expr(Expr::TryBlock { body }, syntax_ptr)
209 }
210 // FIXME: we need to record these effects somewhere...
211 ast::Effect::Async(_) | ast::Effect::Label(_) | ast::Effect::Unsafe(_) => {
212 self.collect_block_opt(e.block_expr())
213 }
214 },
206 ast::Expr::BlockExpr(e) => self.collect_block(e), 215 ast::Expr::BlockExpr(e) => self.collect_block(e),
207 ast::Expr::LoopExpr(e) => { 216 ast::Expr::LoopExpr(e) => {
208 let body = self.collect_block_opt(e.loop_body()); 217 let body = self.collect_block_opt(e.loop_body());
@@ -217,7 +226,7 @@ impl ExprCollector<'_> {
217 None => self.collect_expr_opt(condition.expr()), 226 None => self.collect_expr_opt(condition.expr()),
218 // if let -- desugar to match 227 // if let -- desugar to match
219 Some(pat) => { 228 Some(pat) => {
220 tested_by!(infer_resolve_while_let); 229 mark::hit!(infer_resolve_while_let);
221 let pat = self.collect_pat(pat); 230 let pat = self.collect_pat(pat);
222 let match_expr = self.collect_expr_opt(condition.expr()); 231 let match_expr = self.collect_expr_opt(condition.expr());
223 let placeholder_pat = self.missing_pat(); 232 let placeholder_pat = self.missing_pat();
@@ -259,7 +268,7 @@ impl ExprCollector<'_> {
259 }; 268 };
260 let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); 269 let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing);
261 let generic_args = 270 let generic_args =
262 e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx, it)); 271 e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx(), it));
263 self.alloc_expr( 272 self.alloc_expr(
264 Expr::MethodCall { receiver, method_name, args, generic_args }, 273 Expr::MethodCall { receiver, method_name, args, generic_args },
265 syntax_ptr, 274 syntax_ptr,
@@ -319,8 +328,7 @@ impl ExprCollector<'_> {
319 .fields() 328 .fields()
320 .inspect(|field| field_ptrs.push(AstPtr::new(field))) 329 .inspect(|field| field_ptrs.push(AstPtr::new(field)))
321 .filter_map(|field| { 330 .filter_map(|field| {
322 let attrs = self.expander.parse_attrs(&field); 331 if !self.expander.is_cfg_enabled(&field) {
323 if !self.expander.is_cfg_enabled(&attrs) {
324 return None; 332 return None;
325 } 333 }
326 let name = field.field_name()?.as_name(); 334 let name = field.field_name()?.as_name();
@@ -365,7 +373,7 @@ impl ExprCollector<'_> {
365 } 373 }
366 ast::Expr::CastExpr(e) => { 374 ast::Expr::CastExpr(e) => {
367 let expr = self.collect_expr_opt(e.expr()); 375 let expr = self.collect_expr_opt(e.expr());
368 let type_ref = TypeRef::from_ast_opt(&self.ctx, e.type_ref()); 376 let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.type_ref());
369 self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) 377 self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
370 } 378 }
371 ast::Expr::RefExpr(e) => { 379 ast::Expr::RefExpr(e) => {
@@ -388,7 +396,7 @@ impl ExprCollector<'_> {
388 for param in pl.params() { 396 for param in pl.params() {
389 let pat = self.collect_pat_opt(param.pat()); 397 let pat = self.collect_pat_opt(param.pat());
390 let type_ref = 398 let type_ref =
391 param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); 399 param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx(), it));
392 args.push(pat); 400 args.push(pat);
393 arg_types.push(type_ref); 401 arg_types.push(type_ref);
394 } 402 }
@@ -396,7 +404,7 @@ impl ExprCollector<'_> {
396 let ret_type = e 404 let ret_type = e
397 .ret_type() 405 .ret_type()
398 .and_then(|r| r.type_ref()) 406 .and_then(|r| r.type_ref())
399 .map(|it| TypeRef::from_ast(&self.ctx, it)); 407 .map(|it| TypeRef::from_ast(&self.ctx(), it));
400 let body = self.collect_expr_opt(e.body()); 408 let body = self.collect_expr_opt(e.body());
401 self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) 409 self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr)
402 } 410 }
@@ -456,6 +464,7 @@ impl ExprCollector<'_> {
456 krate: Some(self.expander.module.krate), 464 krate: Some(self.expander.module.krate),
457 ast_id: Some(self.expander.ast_id(&e)), 465 ast_id: Some(self.expander.ast_id(&e)),
458 kind: MacroDefKind::Declarative, 466 kind: MacroDefKind::Declarative,
467 local_inner: false,
459 }; 468 };
460 self.body.item_scope.define_legacy_macro(name, mac); 469 self.body.item_scope.define_legacy_macro(name, mac);
461 470
@@ -490,19 +499,16 @@ impl ExprCollector<'_> {
490 } 499 }
491 } 500 }
492 501
493 fn collect_block(&mut self, expr: ast::BlockExpr) -> ExprId { 502 fn collect_block(&mut self, block: ast::BlockExpr) -> ExprId {
494 let syntax_node_ptr = AstPtr::new(&expr.clone().into()); 503 let syntax_node_ptr = AstPtr::new(&block.clone().into());
495 let block = match expr.block() {
496 Some(block) => block,
497 None => return self.alloc_expr(Expr::Missing, syntax_node_ptr),
498 };
499 self.collect_block_items(&block); 504 self.collect_block_items(&block);
500 let statements = block 505 let statements = block
501 .statements() 506 .statements()
502 .map(|s| match s { 507 .map(|s| match s {
503 ast::Stmt::LetStmt(stmt) => { 508 ast::Stmt::LetStmt(stmt) => {
504 let pat = self.collect_pat_opt(stmt.pat()); 509 let pat = self.collect_pat_opt(stmt.pat());
505 let type_ref = stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); 510 let type_ref =
511 stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx(), it));
506 let initializer = stmt.initializer().map(|e| self.collect_expr(e)); 512 let initializer = stmt.initializer().map(|e| self.collect_expr(e));
507 Statement::Let { pat, type_ref, initializer } 513 Statement::Let { pat, type_ref, initializer }
508 } 514 }
@@ -513,7 +519,7 @@ impl ExprCollector<'_> {
513 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) 519 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr)
514 } 520 }
515 521
516 fn collect_block_items(&mut self, block: &ast::Block) { 522 fn collect_block_items(&mut self, block: &ast::BlockExpr) {
517 let container = ContainerId::DefWithBodyId(self.def); 523 let container = ContainerId::DefWithBodyId(self.def);
518 for item in block.items() { 524 for item in block.items() {
519 let (def, name): (ModuleDefId, Option<ast::Name>) = match item { 525 let (def, name): (ModuleDefId, Option<ast::Name>) = match item {
@@ -568,9 +574,16 @@ impl ExprCollector<'_> {
568 self.body.item_scope.define_def(def); 574 self.body.item_scope.define_def(def);
569 if let Some(name) = name { 575 if let Some(name) = name {
570 let vis = crate::visibility::Visibility::Public; // FIXME determine correctly 576 let vis = crate::visibility::Visibility::Public; // FIXME determine correctly
571 self.body 577 let has_constructor = match def {
572 .item_scope 578 ModuleDefId::AdtId(AdtId::StructId(s)) => {
573 .push_res(name.as_name(), crate::per_ns::PerNs::from_def(def, vis)); 579 self.db.struct_data(s).variant_data.kind() != StructKind::Record
580 }
581 _ => true,
582 };
583 self.body.item_scope.push_res(
584 name.as_name(),
585 crate::per_ns::PerNs::from_def(def, vis, has_constructor),
586 );
574 } 587 }
575 } 588 }
576 } 589 }