diff options
Diffstat (limited to 'crates/hir_def/src/body')
-rw-r--r-- | crates/hir_def/src/body/lower.rs | 63 | ||||
-rw-r--r-- | crates/hir_def/src/body/tests.rs | 2 |
2 files changed, 46 insertions, 19 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index 63e89a1f4..ed07d6928 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 | ) { |
@@ -625,7 +632,8 @@ impl ExprCollector<'_> { | |||
625 | return; | 632 | return; |
626 | } | 633 | } |
627 | let pat = self.collect_pat_opt(stmt.pat()); | 634 | let pat = self.collect_pat_opt(stmt.pat()); |
628 | let type_ref = stmt.ty().map(|it| TypeRef::from_ast(&self.ctx(), it)); | 635 | let type_ref = |
636 | stmt.ty().map(|it| Interned::new(TypeRef::from_ast(&self.ctx(), it))); | ||
629 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); | 637 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); |
630 | self.statements_in_scope.push(Statement::Let { pat, type_ref, initializer }); | 638 | self.statements_in_scope.push(Statement::Let { pat, type_ref, initializer }); |
631 | } | 639 | } |
@@ -636,10 +644,14 @@ impl ExprCollector<'_> { | |||
636 | 644 | ||
637 | // Note that macro could be expended to multiple statements | 645 | // Note that macro could be expended to multiple statements |
638 | if let Some(ast::Expr::MacroCall(m)) = stmt.expr() { | 646 | if let Some(ast::Expr::MacroCall(m)) = stmt.expr() { |
647 | let macro_ptr = AstPtr::new(&m); | ||
639 | let syntax_ptr = AstPtr::new(&stmt.expr().unwrap()); | 648 | let syntax_ptr = AstPtr::new(&stmt.expr().unwrap()); |
640 | 649 | ||
641 | self.collect_macro_call(m, syntax_ptr.clone(), false, |this, expansion| { | 650 | self.collect_macro_call( |
642 | match expansion { | 651 | m, |
652 | macro_ptr, | ||
653 | false, | ||
654 | |this, expansion| match expansion { | ||
643 | Some(expansion) => { | 655 | Some(expansion) => { |
644 | let statements: ast::MacroStmts = expansion; | 656 | let statements: ast::MacroStmts = expansion; |
645 | 657 | ||
@@ -653,8 +665,8 @@ impl ExprCollector<'_> { | |||
653 | let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone()); | 665 | let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone()); |
654 | this.statements_in_scope.push(Statement::Expr(expr)); | 666 | this.statements_in_scope.push(Statement::Expr(expr)); |
655 | } | 667 | } |
656 | } | 668 | }, |
657 | }); | 669 | ); |
658 | } else { | 670 | } else { |
659 | let expr = self.collect_expr_opt(stmt.expr()); | 671 | let expr = self.collect_expr_opt(stmt.expr()); |
660 | self.statements_in_scope.push(Statement::Expr(expr)); | 672 | self.statements_in_scope.push(Statement::Expr(expr)); |
@@ -755,7 +767,7 @@ impl ExprCollector<'_> { | |||
755 | } | 767 | } |
756 | } | 768 | } |
757 | ast::Pat::TupleStructPat(p) => { | 769 | ast::Pat::TupleStructPat(p) => { |
758 | let path = p.path().and_then(|path| self.expander.parse_path(path)); | 770 | let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new); |
759 | let (args, ellipsis) = self.collect_tuple_pat(p.fields()); | 771 | let (args, ellipsis) = self.collect_tuple_pat(p.fields()); |
760 | Pat::TupleStruct { path, args, ellipsis } | 772 | Pat::TupleStruct { path, args, ellipsis } |
761 | } | 773 | } |
@@ -765,7 +777,7 @@ impl ExprCollector<'_> { | |||
765 | Pat::Ref { pat, mutability } | 777 | Pat::Ref { pat, mutability } |
766 | } | 778 | } |
767 | ast::Pat::PathPat(p) => { | 779 | ast::Pat::PathPat(p) => { |
768 | let path = p.path().and_then(|path| self.expander.parse_path(path)); | 780 | let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new); |
769 | path.map(Pat::Path).unwrap_or(Pat::Missing) | 781 | path.map(Pat::Path).unwrap_or(Pat::Missing) |
770 | } | 782 | } |
771 | ast::Pat::OrPat(p) => { | 783 | ast::Pat::OrPat(p) => { |
@@ -779,7 +791,7 @@ impl ExprCollector<'_> { | |||
779 | } | 791 | } |
780 | ast::Pat::WildcardPat(_) => Pat::Wild, | 792 | ast::Pat::WildcardPat(_) => Pat::Wild, |
781 | ast::Pat::RecordPat(p) => { | 793 | ast::Pat::RecordPat(p) => { |
782 | let path = p.path().and_then(|path| self.expander.parse_path(path)); | 794 | let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new); |
783 | let args: Vec<_> = p | 795 | let args: Vec<_> = p |
784 | .record_pat_field_list() | 796 | .record_pat_field_list() |
785 | .expect("every struct should have a field list") | 797 | .expect("every struct should have a field list") |
@@ -841,8 +853,23 @@ impl ExprCollector<'_> { | |||
841 | Pat::Missing | 853 | Pat::Missing |
842 | } | 854 | } |
843 | } | 855 | } |
856 | ast::Pat::MacroPat(mac) => match mac.macro_call() { | ||
857 | Some(call) => { | ||
858 | let macro_ptr = AstPtr::new(&call); | ||
859 | let mut pat = None; | ||
860 | self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| { | ||
861 | pat = Some(this.collect_pat_opt(expanded_pat)); | ||
862 | }); | ||
863 | |||
864 | match pat { | ||
865 | Some(pat) => return pat, | ||
866 | None => Pat::Missing, | ||
867 | } | ||
868 | } | ||
869 | None => Pat::Missing, | ||
870 | }, | ||
844 | // FIXME: implement | 871 | // FIXME: implement |
845 | ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing, | 872 | ast::Pat::RangePat(_) => Pat::Missing, |
846 | }; | 873 | }; |
847 | let ptr = AstPtr::new(&pat); | 874 | let ptr = AstPtr::new(&pat); |
848 | self.alloc_pat(pattern, Either::Left(ptr)) | 875 | 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..c1d3e998f 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 |