diff options
Diffstat (limited to 'crates/hir_def/src/body/lower.rs')
-rw-r--r-- | crates/hir_def/src/body/lower.rs | 83 |
1 files changed, 58 insertions, 25 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)) |