aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/body
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/body')
-rw-r--r--crates/hir_def/src/body/lower.rs83
-rw-r--r--crates/hir_def/src/body/tests.rs4
2 files changed, 60 insertions, 27 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index 229e81dd4..c0b0b7841 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -30,6 +30,7 @@ use crate::{
30 LabelId, Literal, LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, 30 LabelId, Literal, LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField,
31 Statement, 31 Statement,
32 }, 32 },
33 intern::Interned,
33 item_scope::BuiltinShadowMode, 34 item_scope::BuiltinShadowMode,
34 path::{GenericArgs, Path}, 35 path::{GenericArgs, Path},
35 type_ref::{Mutability, Rawness, TypeRef}, 36 type_ref::{Mutability, Rawness, TypeRef},
@@ -322,8 +323,10 @@ impl ExprCollector<'_> {
322 Vec::new() 323 Vec::new()
323 }; 324 };
324 let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); 325 let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing);
325 let generic_args = 326 let generic_args = e
326 e.generic_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx(), it)); 327 .generic_arg_list()
328 .and_then(|it| GenericArgs::from_ast(&self.ctx(), it))
329 .map(Box::new);
327 self.alloc_expr( 330 self.alloc_expr(
328 Expr::MethodCall { receiver, method_name, args, generic_args }, 331 Expr::MethodCall { receiver, method_name, args, generic_args },
329 syntax_ptr, 332 syntax_ptr,
@@ -385,7 +388,7 @@ impl ExprCollector<'_> {
385 self.alloc_expr(Expr::Yield { expr }, syntax_ptr) 388 self.alloc_expr(Expr::Yield { expr }, syntax_ptr)
386 } 389 }
387 ast::Expr::RecordExpr(e) => { 390 ast::Expr::RecordExpr(e) => {
388 let path = e.path().and_then(|path| self.expander.parse_path(path)); 391 let path = e.path().and_then(|path| self.expander.parse_path(path)).map(Box::new);
389 let record_lit = if let Some(nfl) = e.record_expr_field_list() { 392 let record_lit = if let Some(nfl) = e.record_expr_field_list() {
390 let fields = nfl 393 let fields = nfl
391 .fields() 394 .fields()
@@ -430,7 +433,7 @@ impl ExprCollector<'_> {
430 } 433 }
431 ast::Expr::CastExpr(e) => { 434 ast::Expr::CastExpr(e) => {
432 let expr = self.collect_expr_opt(e.expr()); 435 let expr = self.collect_expr_opt(e.expr());
433 let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.ty()); 436 let type_ref = Interned::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
434 self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) 437 self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
435 } 438 }
436 ast::Expr::RefExpr(e) => { 439 ast::Expr::RefExpr(e) => {
@@ -464,13 +467,16 @@ impl ExprCollector<'_> {
464 if let Some(pl) = e.param_list() { 467 if let Some(pl) = e.param_list() {
465 for param in pl.params() { 468 for param in pl.params() {
466 let pat = self.collect_pat_opt(param.pat()); 469 let pat = self.collect_pat_opt(param.pat());
467 let type_ref = param.ty().map(|it| TypeRef::from_ast(&self.ctx(), it)); 470 let type_ref =
471 param.ty().map(|it| Interned::new(TypeRef::from_ast(&self.ctx(), it)));
468 args.push(pat); 472 args.push(pat);
469 arg_types.push(type_ref); 473 arg_types.push(type_ref);
470 } 474 }
471 } 475 }
472 let ret_type = 476 let ret_type = e
473 e.ret_type().and_then(|r| r.ty()).map(|it| TypeRef::from_ast(&self.ctx(), it)); 477 .ret_type()
478 .and_then(|r| r.ty())
479 .map(|it| Interned::new(TypeRef::from_ast(&self.ctx(), it)));
474 let body = self.collect_expr_opt(e.body()); 480 let body = self.collect_expr_opt(e.body());
475 self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) 481 self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr)
476 } 482 }
@@ -525,8 +531,9 @@ impl ExprCollector<'_> {
525 } 531 }
526 } 532 }
527 ast::Expr::MacroCall(e) => { 533 ast::Expr::MacroCall(e) => {
534 let macro_ptr = AstPtr::new(&e);
528 let mut ids = vec![]; 535 let mut ids = vec![];
529 self.collect_macro_call(e, syntax_ptr.clone(), true, |this, expansion| { 536 self.collect_macro_call(e, macro_ptr, true, |this, expansion| {
530 ids.push(match expansion { 537 ids.push(match expansion {
531 Some(it) => this.collect_expr(it), 538 Some(it) => this.collect_expr(it),
532 None => this.alloc_expr(Expr::Missing, syntax_ptr.clone()), 539 None => this.alloc_expr(Expr::Missing, syntax_ptr.clone()),
@@ -549,7 +556,7 @@ impl ExprCollector<'_> {
549 fn collect_macro_call<F: FnMut(&mut Self, Option<T>), T: ast::AstNode>( 556 fn collect_macro_call<F: FnMut(&mut Self, Option<T>), T: ast::AstNode>(
550 &mut self, 557 &mut self,
551 e: ast::MacroCall, 558 e: ast::MacroCall,
552 syntax_ptr: AstPtr<ast::Expr>, 559 syntax_ptr: AstPtr<ast::MacroCall>,
553 is_error_recoverable: bool, 560 is_error_recoverable: bool,
554 mut collector: F, 561 mut collector: F,
555 ) { 562 ) {
@@ -561,9 +568,13 @@ impl ExprCollector<'_> {
561 568
562 let res = match res { 569 let res = match res {
563 Ok(res) => res, 570 Ok(res) => res,
564 Err(UnresolvedMacro) => { 571 Err(UnresolvedMacro { path }) => {
565 self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedMacroCall( 572 self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedMacroCall(
566 UnresolvedMacroCall { file: outer_file, node: syntax_ptr.cast().unwrap() }, 573 UnresolvedMacroCall {
574 file: outer_file,
575 node: syntax_ptr.cast().unwrap(),
576 path,
577 },
567 )); 578 ));
568 collector(self, None); 579 collector(self, None);
569 return; 580 return;
@@ -625,7 +636,8 @@ impl ExprCollector<'_> {
625 return; 636 return;
626 } 637 }
627 let pat = self.collect_pat_opt(stmt.pat()); 638 let pat = self.collect_pat_opt(stmt.pat());
628 let type_ref = stmt.ty().map(|it| TypeRef::from_ast(&self.ctx(), it)); 639 let type_ref =
640 stmt.ty().map(|it| Interned::new(TypeRef::from_ast(&self.ctx(), it)));
629 let initializer = stmt.initializer().map(|e| self.collect_expr(e)); 641 let initializer = stmt.initializer().map(|e| self.collect_expr(e));
630 self.statements_in_scope.push(Statement::Let { pat, type_ref, initializer }); 642 self.statements_in_scope.push(Statement::Let { pat, type_ref, initializer });
631 } 643 }
@@ -636,10 +648,14 @@ impl ExprCollector<'_> {
636 648
637 // Note that macro could be expended to multiple statements 649 // Note that macro could be expended to multiple statements
638 if let Some(ast::Expr::MacroCall(m)) = stmt.expr() { 650 if let Some(ast::Expr::MacroCall(m)) = stmt.expr() {
651 let macro_ptr = AstPtr::new(&m);
639 let syntax_ptr = AstPtr::new(&stmt.expr().unwrap()); 652 let syntax_ptr = AstPtr::new(&stmt.expr().unwrap());
640 653
641 self.collect_macro_call(m, syntax_ptr.clone(), false, |this, expansion| { 654 self.collect_macro_call(
642 match expansion { 655 m,
656 macro_ptr,
657 false,
658 |this, expansion| match expansion {
643 Some(expansion) => { 659 Some(expansion) => {
644 let statements: ast::MacroStmts = expansion; 660 let statements: ast::MacroStmts = expansion;
645 661
@@ -653,8 +669,8 @@ impl ExprCollector<'_> {
653 let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone()); 669 let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone());
654 this.statements_in_scope.push(Statement::Expr(expr)); 670 this.statements_in_scope.push(Statement::Expr(expr));
655 } 671 }
656 } 672 },
657 }); 673 );
658 } else { 674 } else {
659 let expr = self.collect_expr_opt(stmt.expr()); 675 let expr = self.collect_expr_opt(stmt.expr());
660 self.statements_in_scope.push(Statement::Expr(expr)); 676 self.statements_in_scope.push(Statement::Expr(expr));
@@ -673,12 +689,14 @@ impl ExprCollector<'_> {
673 let block_loc = 689 let block_loc =
674 BlockLoc { ast_id, module: self.expander.def_map.module_id(self.expander.module) }; 690 BlockLoc { ast_id, module: self.expander.def_map.module_id(self.expander.module) };
675 let block_id = self.db.intern_block(block_loc); 691 let block_id = self.db.intern_block(block_loc);
676 self.body.block_scopes.push(block_id);
677 692
678 let opt_def_map = self.db.block_def_map(block_id); 693 let (module, def_map) = match self.db.block_def_map(block_id) {
679 let has_def_map = opt_def_map.is_some(); 694 Some(def_map) => {
680 let def_map = opt_def_map.unwrap_or_else(|| self.expander.def_map.clone()); 695 self.body.block_scopes.push(block_id);
681 let module = if has_def_map { def_map.root() } else { self.expander.module }; 696 (def_map.root(), def_map)
697 }
698 None => (self.expander.module, self.expander.def_map.clone()),
699 };
682 let prev_def_map = mem::replace(&mut self.expander.def_map, def_map); 700 let prev_def_map = mem::replace(&mut self.expander.def_map, def_map);
683 let prev_local_module = mem::replace(&mut self.expander.module, module); 701 let prev_local_module = mem::replace(&mut self.expander.module, module);
684 let prev_statements = std::mem::take(&mut self.statements_in_scope); 702 let prev_statements = std::mem::take(&mut self.statements_in_scope);
@@ -753,7 +771,7 @@ impl ExprCollector<'_> {
753 } 771 }
754 } 772 }
755 ast::Pat::TupleStructPat(p) => { 773 ast::Pat::TupleStructPat(p) => {
756 let path = p.path().and_then(|path| self.expander.parse_path(path)); 774 let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new);
757 let (args, ellipsis) = self.collect_tuple_pat(p.fields()); 775 let (args, ellipsis) = self.collect_tuple_pat(p.fields());
758 Pat::TupleStruct { path, args, ellipsis } 776 Pat::TupleStruct { path, args, ellipsis }
759 } 777 }
@@ -763,7 +781,7 @@ impl ExprCollector<'_> {
763 Pat::Ref { pat, mutability } 781 Pat::Ref { pat, mutability }
764 } 782 }
765 ast::Pat::PathPat(p) => { 783 ast::Pat::PathPat(p) => {
766 let path = p.path().and_then(|path| self.expander.parse_path(path)); 784 let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new);
767 path.map(Pat::Path).unwrap_or(Pat::Missing) 785 path.map(Pat::Path).unwrap_or(Pat::Missing)
768 } 786 }
769 ast::Pat::OrPat(p) => { 787 ast::Pat::OrPat(p) => {
@@ -777,7 +795,7 @@ impl ExprCollector<'_> {
777 } 795 }
778 ast::Pat::WildcardPat(_) => Pat::Wild, 796 ast::Pat::WildcardPat(_) => Pat::Wild,
779 ast::Pat::RecordPat(p) => { 797 ast::Pat::RecordPat(p) => {
780 let path = p.path().and_then(|path| self.expander.parse_path(path)); 798 let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new);
781 let args: Vec<_> = p 799 let args: Vec<_> = p
782 .record_pat_field_list() 800 .record_pat_field_list()
783 .expect("every struct should have a field list") 801 .expect("every struct should have a field list")
@@ -839,8 +857,23 @@ impl ExprCollector<'_> {
839 Pat::Missing 857 Pat::Missing
840 } 858 }
841 } 859 }
860 ast::Pat::MacroPat(mac) => match mac.macro_call() {
861 Some(call) => {
862 let macro_ptr = AstPtr::new(&call);
863 let mut pat = None;
864 self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| {
865 pat = Some(this.collect_pat_opt(expanded_pat));
866 });
867
868 match pat {
869 Some(pat) => return pat,
870 None => Pat::Missing,
871 }
872 }
873 None => Pat::Missing,
874 },
842 // FIXME: implement 875 // FIXME: implement
843 ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing, 876 ast::Pat::RangePat(_) => Pat::Missing,
844 }; 877 };
845 let ptr = AstPtr::new(&pat); 878 let ptr = AstPtr::new(&pat);
846 self.alloc_pat(pattern, Either::Left(ptr)) 879 self.alloc_pat(pattern, Either::Left(ptr))
diff --git a/crates/hir_def/src/body/tests.rs b/crates/hir_def/src/body/tests.rs
index faa133297..63f5fe88d 100644
--- a/crates/hir_def/src/body/tests.rs
+++ b/crates/hir_def/src/body/tests.rs
@@ -143,7 +143,7 @@ fn f() {
143 //^^^^^^^^^^^^^ could not convert tokens 143 //^^^^^^^^^^^^^ could not convert tokens
144 144
145 env!("OUT_DIR"); 145 env!("OUT_DIR");
146 //^^^^^^^^^^^^^^^ `OUT_DIR` not set, enable "load out dirs from check" to fix 146 //^^^^^^^^^^^^^^^ `OUT_DIR` not set, enable "run build scripts" to fix
147 147
148 compile_error!("compile_error works"); 148 compile_error!("compile_error works");
149 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ compile_error works 149 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ compile_error works
@@ -180,7 +180,7 @@ fn unresolved_macro_diag() {
180 r#" 180 r#"
181fn f() { 181fn f() {
182 m!(); 182 m!();
183 //^^^^ unresolved macro call 183 //^^^^ unresolved macro `m!`
184} 184}
185 "#, 185 "#,
186 ); 186 );