aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_expand/src/builtin_macro.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_expand/src/builtin_macro.rs')
-rw-r--r--crates/hir_expand/src/builtin_macro.rs92
1 files changed, 49 insertions, 43 deletions
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index eb57ea7d6..2a79c892b 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -5,6 +5,7 @@ use crate::{
5}; 5};
6 6
7use base_db::{AnchoredPath, FileId}; 7use base_db::{AnchoredPath, FileId};
8use cfg::CfgExpr;
8use either::Either; 9use either::Either;
9use mbe::{parse_exprs_with_sep, parse_to_token_tree, ExpandResult}; 10use mbe::{parse_exprs_with_sep, parse_to_token_tree, ExpandResult};
10use parser::FragmentKind; 11use parser::FragmentKind;
@@ -97,6 +98,7 @@ register_builtin! {
97 (format_args_nl, FormatArgsNl) => format_args_expand, 98 (format_args_nl, FormatArgsNl) => format_args_expand,
98 (llvm_asm, LlvmAsm) => asm_expand, 99 (llvm_asm, LlvmAsm) => asm_expand,
99 (asm, Asm) => asm_expand, 100 (asm, Asm) => asm_expand,
101 (cfg, Cfg) => cfg_expand,
100 102
101 EAGER: 103 EAGER:
102 (compile_error, CompileError) => compile_error_expand, 104 (compile_error, CompileError) => compile_error_expand,
@@ -258,6 +260,18 @@ fn asm_expand(
258 ExpandResult::ok(expanded) 260 ExpandResult::ok(expanded)
259} 261}
260 262
263fn cfg_expand(
264 db: &dyn AstDatabase,
265 id: LazyMacroId,
266 tt: &tt::Subtree,
267) -> ExpandResult<tt::Subtree> {
268 let loc = db.lookup_intern_macro(id);
269 let expr = CfgExpr::parse(tt);
270 let enabled = db.crate_graph()[loc.krate].cfg_options.check(&expr) != Some(false);
271 let expanded = if enabled { quote!(true) } else { quote!(false) };
272 ExpandResult::ok(expanded)
273}
274
261fn unquote_str(lit: &tt::Literal) -> Option<String> { 275fn unquote_str(lit: &tt::Literal) -> Option<String> {
262 let lit = ast::make::tokens::literal(&lit.to_string()); 276 let lit = ast::make::tokens::literal(&lit.to_string());
263 let token = ast::String::cast(lit)?; 277 let token = ast::String::cast(lit)?;
@@ -477,6 +491,7 @@ mod tests {
477 MacroCallLoc, 491 MacroCallLoc,
478 }; 492 };
479 use base_db::{fixture::WithFixture, SourceDatabase}; 493 use base_db::{fixture::WithFixture, SourceDatabase};
494 use expect_test::{expect, Expect};
480 use std::sync::Arc; 495 use std::sync::Arc;
481 use syntax::ast::NameOwner; 496 use syntax::ast::NameOwner;
482 497
@@ -560,87 +575,86 @@ mod tests {
560 db.parse_or_expand(file_id).unwrap().to_string() 575 db.parse_or_expand(file_id).unwrap().to_string()
561 } 576 }
562 577
578 fn check_expansion(ra_fixture: &str, expect: Expect) {
579 let expansion = expand_builtin_macro(ra_fixture);
580 expect.assert_eq(&expansion);
581 }
582
563 #[test] 583 #[test]
564 fn test_column_expand() { 584 fn test_column_expand() {
565 let expanded = expand_builtin_macro( 585 check_expansion(
566 r#" 586 r#"
567 #[rustc_builtin_macro] 587 #[rustc_builtin_macro]
568 macro_rules! column {() => {}} 588 macro_rules! column {() => {}}
569 column!() 589 column!()
570 "#, 590 "#,
591 expect![["0"]],
571 ); 592 );
572
573 assert_eq!(expanded, "0");
574 } 593 }
575 594
576 #[test] 595 #[test]
577 fn test_line_expand() { 596 fn test_line_expand() {
578 let expanded = expand_builtin_macro( 597 check_expansion(
579 r#" 598 r#"
580 #[rustc_builtin_macro] 599 #[rustc_builtin_macro]
581 macro_rules! line {() => {}} 600 macro_rules! line {() => {}}
582 line!() 601 line!()
583 "#, 602 "#,
603 expect![["0"]],
584 ); 604 );
585
586 assert_eq!(expanded, "0");
587 } 605 }
588 606
589 #[test] 607 #[test]
590 fn test_stringify_expand() { 608 fn test_stringify_expand() {
591 let expanded = expand_builtin_macro( 609 check_expansion(
592 r#" 610 r#"
593 #[rustc_builtin_macro] 611 #[rustc_builtin_macro]
594 macro_rules! stringify {() => {}} 612 macro_rules! stringify {() => {}}
595 stringify!(a b c) 613 stringify!(a b c)
596 "#, 614 "#,
615 expect![["\"a b c\""]],
597 ); 616 );
598
599 assert_eq!(expanded, "\"a b c\"");
600 } 617 }
601 618
602 #[test] 619 #[test]
603 fn test_env_expand() { 620 fn test_env_expand() {
604 let expanded = expand_builtin_macro( 621 check_expansion(
605 r#" 622 r#"
606 #[rustc_builtin_macro] 623 #[rustc_builtin_macro]
607 macro_rules! env {() => {}} 624 macro_rules! env {() => {}}
608 env!("TEST_ENV_VAR") 625 env!("TEST_ENV_VAR")
609 "#, 626 "#,
627 expect![["\"__RA_UNIMPLEMENTED__\""]],
610 ); 628 );
611
612 assert_eq!(expanded, "\"__RA_UNIMPLEMENTED__\"");
613 } 629 }
614 630
615 #[test] 631 #[test]
616 fn test_option_env_expand() { 632 fn test_option_env_expand() {
617 let expanded = expand_builtin_macro( 633 check_expansion(
618 r#" 634 r#"
619 #[rustc_builtin_macro] 635 #[rustc_builtin_macro]
620 macro_rules! option_env {() => {}} 636 macro_rules! option_env {() => {}}
621 option_env!("TEST_ENV_VAR") 637 option_env!("TEST_ENV_VAR")
622 "#, 638 "#,
639 expect![["std::option::Option::None:: < &str>"]],
623 ); 640 );
624
625 assert_eq!(expanded, "std::option::Option::None:: < &str>");
626 } 641 }
627 642
628 #[test] 643 #[test]
629 fn test_file_expand() { 644 fn test_file_expand() {
630 let expanded = expand_builtin_macro( 645 check_expansion(
631 r#" 646 r#"
632 #[rustc_builtin_macro] 647 #[rustc_builtin_macro]
633 macro_rules! file {() => {}} 648 macro_rules! file {() => {}}
634 file!() 649 file!()
635 "#, 650 "#,
651 expect![[r#""""#]],
636 ); 652 );
637
638 assert_eq!(expanded, "\"\"");
639 } 653 }
640 654
641 #[test] 655 #[test]
642 fn test_assert_expand() { 656 fn test_assert_expand() {
643 let expanded = expand_builtin_macro( 657 check_expansion(
644 r#" 658 r#"
645 #[rustc_builtin_macro] 659 #[rustc_builtin_macro]
646 macro_rules! assert { 660 macro_rules! assert {
@@ -649,14 +663,13 @@ mod tests {
649 } 663 }
650 assert!(true, "{} {:?}", arg1(a, b, c), arg2); 664 assert!(true, "{} {:?}", arg1(a, b, c), arg2);
651 "#, 665 "#,
666 expect![["{{(&(true), &(\"{} {:?}\"), &(arg1(a,b,c)), &(arg2),);}}"]],
652 ); 667 );
653
654 assert_eq!(expanded, "{{(&(true), &(\"{} {:?}\"), &(arg1(a,b,c)), &(arg2),);}}");
655 } 668 }
656 669
657 #[test] 670 #[test]
658 fn test_compile_error_expand() { 671 fn test_compile_error_expand() {
659 let expanded = expand_builtin_macro( 672 check_expansion(
660 r#" 673 r#"
661 #[rustc_builtin_macro] 674 #[rustc_builtin_macro]
662 macro_rules! compile_error { 675 macro_rules! compile_error {
@@ -665,15 +678,14 @@ mod tests {
665 } 678 }
666 compile_error!("error!"); 679 compile_error!("error!");
667 "#, 680 "#,
681 // This expands to nothing (since it's in item position), but emits an error.
682 expect![[""]],
668 ); 683 );
669
670 // This expands to nothing (since it's in item position), but emits an error.
671 assert_eq!(expanded, "");
672 } 684 }
673 685
674 #[test] 686 #[test]
675 fn test_format_args_expand() { 687 fn test_format_args_expand() {
676 let expanded = expand_builtin_macro( 688 check_expansion(
677 r#" 689 r#"
678 #[rustc_builtin_macro] 690 #[rustc_builtin_macro]
679 macro_rules! format_args { 691 macro_rules! format_args {
@@ -682,17 +694,15 @@ mod tests {
682 } 694 }
683 format_args!("{} {:?}", arg1(a, b, c), arg2); 695 format_args!("{} {:?}", arg1(a, b, c), arg2);
684 "#, 696 "#,
685 ); 697 expect![[
686 698 r#"std::fmt::Arguments::new_v1(&[], &[std::fmt::ArgumentV1::new(&(arg1(a,b,c)),std::fmt::Display::fmt),std::fmt::ArgumentV1::new(&(arg2),std::fmt::Display::fmt),])"#
687 assert_eq!( 699 ]],
688 expanded,
689 r#"std::fmt::Arguments::new_v1(&[], &[std::fmt::ArgumentV1::new(&(arg1(a,b,c)),std::fmt::Display::fmt),std::fmt::ArgumentV1::new(&(arg2),std::fmt::Display::fmt),])"#
690 ); 700 );
691 } 701 }
692 702
693 #[test] 703 #[test]
694 fn test_format_args_expand_with_comma_exprs() { 704 fn test_format_args_expand_with_comma_exprs() {
695 let expanded = expand_builtin_macro( 705 check_expansion(
696 r#" 706 r#"
697 #[rustc_builtin_macro] 707 #[rustc_builtin_macro]
698 macro_rules! format_args { 708 macro_rules! format_args {
@@ -701,17 +711,15 @@ mod tests {
701 } 711 }
702 format_args!("{} {:?}", a::<A,B>(), b); 712 format_args!("{} {:?}", a::<A,B>(), b);
703 "#, 713 "#,
704 ); 714 expect![[
705 715 r#"std::fmt::Arguments::new_v1(&[], &[std::fmt::ArgumentV1::new(&(a::<A,B>()),std::fmt::Display::fmt),std::fmt::ArgumentV1::new(&(b),std::fmt::Display::fmt),])"#
706 assert_eq!( 716 ]],
707 expanded,
708 r#"std::fmt::Arguments::new_v1(&[], &[std::fmt::ArgumentV1::new(&(a::<A,B>()),std::fmt::Display::fmt),std::fmt::ArgumentV1::new(&(b),std::fmt::Display::fmt),])"#
709 ); 717 );
710 } 718 }
711 719
712 #[test] 720 #[test]
713 fn test_include_bytes_expand() { 721 fn test_include_bytes_expand() {
714 let expanded = expand_builtin_macro( 722 check_expansion(
715 r#" 723 r#"
716 #[rustc_builtin_macro] 724 #[rustc_builtin_macro]
717 macro_rules! include_bytes { 725 macro_rules! include_bytes {
@@ -720,21 +728,19 @@ mod tests {
720 } 728 }
721 include_bytes("foo"); 729 include_bytes("foo");
722 "#, 730 "#,
731 expect![[r#"b"""#]],
723 ); 732 );
724
725 assert_eq!(expanded, r#"b"""#);
726 } 733 }
727 734
728 #[test] 735 #[test]
729 fn test_concat_expand() { 736 fn test_concat_expand() {
730 let expanded = expand_builtin_macro( 737 check_expansion(
731 r##" 738 r##"
732 #[rustc_builtin_macro] 739 #[rustc_builtin_macro]
733 macro_rules! concat {} 740 macro_rules! concat {}
734 concat!("foo", "r", 0, r#"bar"#, false); 741 concat!("foo", "r", 0, r#"bar"#, false);
735 "##, 742 "##,
743 expect![[r#""foor0barfalse""#]],
736 ); 744 );
737
738 assert_eq!(expanded, r#""foor0barfalse""#);
739 } 745 }
740} 746}