aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-05-29 16:19:44 +0100
committerGitHub <[email protected]>2021-05-29 16:19:44 +0100
commit8cd98bde39c67af8a5ab742b6a688edd355f5025 (patch)
tree21c155b7d95fd393765238aa09b99a895341854a
parent247faf271b9098624cb0b09dd4914da66497dd5a (diff)
parent31588aea04aa1240fdc7b5279535f63b9f1681f8 (diff)
Merge #9046
9046: fix: make `include!` etc. work in expression position r=jonas-schievink a=jonas-schievink This PR removes determination of fragment kinds from the eager macro implementations. The fragment kind is always determined by the syntax position in which a macro is invoked, not by the macro implementation, even for eager macros. This makes `include!` work in expression position, and should have the same effect for all macros that may be used in different positions. bors r+ Co-authored-by: Jonas Schievink <[email protected]>
-rw-r--r--crates/hir_expand/src/builtin_macro.rs37
-rw-r--r--crates/hir_expand/src/eager.rs3
-rw-r--r--crates/hir_ty/src/tests/macros.rs18
3 files changed, 35 insertions, 23 deletions
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index 94d7aecb6..0b310ba2f 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -8,7 +8,6 @@ use base_db::{AnchoredPath, Edition, FileId};
8use cfg::CfgExpr; 8use cfg::CfgExpr;
9use either::Either; 9use either::Either;
10use mbe::{parse_exprs_with_sep, parse_to_token_tree, ExpandResult}; 10use mbe::{parse_exprs_with_sep, parse_to_token_tree, ExpandResult};
11use parser::FragmentKind;
12use syntax::ast::{self, AstToken}; 11use syntax::ast::{self, AstToken};
13 12
14macro_rules! register_builtin { 13macro_rules! register_builtin {
@@ -47,7 +46,7 @@ macro_rules! register_builtin {
47 let expander = match *self { 46 let expander = match *self {
48 $( EagerExpander::$e_kind => $e_expand, )* 47 $( EagerExpander::$e_kind => $e_expand, )*
49 }; 48 };
50 expander(db,arg_id,tt) 49 expander(db, arg_id, tt)
51 } 50 }
52 } 51 }
53 52
@@ -64,14 +63,13 @@ macro_rules! register_builtin {
64#[derive(Debug)] 63#[derive(Debug)]
65pub struct ExpandedEager { 64pub struct ExpandedEager {
66 pub(crate) subtree: tt::Subtree, 65 pub(crate) subtree: tt::Subtree,
67 pub(crate) fragment: FragmentKind,
68 /// The included file ID of the include macro. 66 /// The included file ID of the include macro.
69 pub(crate) included_file: Option<FileId>, 67 pub(crate) included_file: Option<FileId>,
70} 68}
71 69
72impl ExpandedEager { 70impl ExpandedEager {
73 fn new(subtree: tt::Subtree, fragment: FragmentKind) -> Self { 71 fn new(subtree: tt::Subtree) -> Self {
74 ExpandedEager { subtree, fragment, included_file: None } 72 ExpandedEager { subtree, included_file: None }
75 } 73 }
76} 74}
77 75
@@ -340,7 +338,7 @@ fn compile_error_expand(
340 _ => mbe::ExpandError::BindingError("`compile_error!` argument must be a string".into()), 338 _ => mbe::ExpandError::BindingError("`compile_error!` argument must be a string".into()),
341 }; 339 };
342 340
343 ExpandResult { value: Some(ExpandedEager::new(quote! {}, FragmentKind::Items)), err: Some(err) } 341 ExpandResult { value: Some(ExpandedEager::new(quote! {})), err: Some(err) }
344} 342}
345 343
346fn concat_expand( 344fn concat_expand(
@@ -371,7 +369,7 @@ fn concat_expand(
371 } 369 }
372 } 370 }
373 } 371 }
374 ExpandResult { value: Some(ExpandedEager::new(quote!(#text), FragmentKind::Expr)), err } 372 ExpandResult { value: Some(ExpandedEager::new(quote!(#text))), err }
375} 373}
376 374
377fn concat_idents_expand( 375fn concat_idents_expand(
@@ -393,7 +391,7 @@ fn concat_idents_expand(
393 } 391 }
394 } 392 }
395 let ident = tt::Ident { text: ident.into(), id: tt::TokenId::unspecified() }; 393 let ident = tt::Ident { text: ident.into(), id: tt::TokenId::unspecified() };
396 ExpandResult { value: Some(ExpandedEager::new(quote!(#ident), FragmentKind::Expr)), err } 394 ExpandResult { value: Some(ExpandedEager::new(quote!(#ident))), err }
397} 395}
398 396
399fn relative_file( 397fn relative_file(
@@ -442,14 +440,7 @@ fn include_expand(
442 440
443 match res { 441 match res {
444 Ok((subtree, file_id)) => { 442 Ok((subtree, file_id)) => {
445 // FIXME: 443 ExpandResult::ok(Some(ExpandedEager { subtree, included_file: Some(file_id) }))
446 // Handle include as expression
447
448 ExpandResult::ok(Some(ExpandedEager {
449 subtree,
450 fragment: FragmentKind::Items,
451 included_file: Some(file_id),
452 }))
453 } 444 }
454 Err(e) => ExpandResult::only_err(e), 445 Err(e) => ExpandResult::only_err(e),
455 } 446 }
@@ -472,7 +463,7 @@ fn include_bytes_expand(
472 id: tt::TokenId::unspecified(), 463 id: tt::TokenId::unspecified(),
473 }))], 464 }))],
474 }; 465 };
475 ExpandResult::ok(Some(ExpandedEager::new(res, FragmentKind::Expr))) 466 ExpandResult::ok(Some(ExpandedEager::new(res)))
476} 467}
477 468
478fn include_str_expand( 469fn include_str_expand(
@@ -492,14 +483,14 @@ fn include_str_expand(
492 let file_id = match relative_file(db, arg_id.into(), &path, true) { 483 let file_id = match relative_file(db, arg_id.into(), &path, true) {
493 Ok(file_id) => file_id, 484 Ok(file_id) => file_id,
494 Err(_) => { 485 Err(_) => {
495 return ExpandResult::ok(Some(ExpandedEager::new(quote!(""), FragmentKind::Expr))); 486 return ExpandResult::ok(Some(ExpandedEager::new(quote!(""))));
496 } 487 }
497 }; 488 };
498 489
499 let text = db.file_text(file_id); 490 let text = db.file_text(file_id);
500 let text = &*text; 491 let text = &*text;
501 492
502 ExpandResult::ok(Some(ExpandedEager::new(quote!(#text), FragmentKind::Expr))) 493 ExpandResult::ok(Some(ExpandedEager::new(quote!(#text))))
503} 494}
504 495
505fn get_env_inner(db: &dyn AstDatabase, arg_id: MacroCallId, key: &str) -> Option<String> { 496fn get_env_inner(db: &dyn AstDatabase, arg_id: MacroCallId, key: &str) -> Option<String> {
@@ -535,7 +526,7 @@ fn env_expand(
535 }); 526 });
536 let expanded = quote! { #s }; 527 let expanded = quote! { #s };
537 528
538 ExpandResult { value: Some(ExpandedEager::new(expanded, FragmentKind::Expr)), err } 529 ExpandResult { value: Some(ExpandedEager::new(expanded)), err }
539} 530}
540 531
541fn option_env_expand( 532fn option_env_expand(
@@ -553,7 +544,7 @@ fn option_env_expand(
553 Some(s) => quote! { std::option::Some(#s) }, 544 Some(s) => quote! { std::option::Some(#s) },
554 }; 545 };
555 546
556 ExpandResult::ok(Some(ExpandedEager::new(expanded, FragmentKind::Expr))) 547 ExpandResult::ok(Some(ExpandedEager::new(expanded)))
557} 548}
558 549
559#[cfg(test)] 550#[cfg(test)]
@@ -565,6 +556,7 @@ mod tests {
565 }; 556 };
566 use base_db::{fixture::WithFixture, SourceDatabase}; 557 use base_db::{fixture::WithFixture, SourceDatabase};
567 use expect_test::{expect, Expect}; 558 use expect_test::{expect, Expect};
559 use parser::FragmentKind;
568 use std::sync::Arc; 560 use std::sync::Arc;
569 use syntax::ast::NameOwner; 561 use syntax::ast::NameOwner;
570 562
@@ -617,6 +609,7 @@ mod tests {
617 local_inner: false, 609 local_inner: false,
618 }; 610 };
619 611
612 let fragment = crate::to_fragment_kind(&macro_call);
620 let args = macro_call.token_tree().unwrap(); 613 let args = macro_call.token_tree().unwrap();
621 let parsed_args = mbe::ast_to_token_tree(&args).0; 614 let parsed_args = mbe::ast_to_token_tree(&args).0;
622 let call_id = AstId::new(file_id.into(), ast_id_map.ast_id(&macro_call)); 615 let call_id = AstId::new(file_id.into(), ast_id_map.ast_id(&macro_call));
@@ -639,7 +632,7 @@ mod tests {
639 arg_or_expansion: Arc::new(expanded.subtree), 632 arg_or_expansion: Arc::new(expanded.subtree),
640 included_file: expanded.included_file, 633 included_file: expanded.included_file,
641 }), 634 }),
642 kind: MacroCallKind::FnLike { ast_id: call_id, fragment: expanded.fragment }, 635 kind: MacroCallKind::FnLike { ast_id: call_id, fragment },
643 }; 636 };
644 637
645 let id: MacroCallId = db.intern_macro(loc).into(); 638 let id: MacroCallId = db.intern_macro(loc).into();
diff --git a/crates/hir_expand/src/eager.rs b/crates/hir_expand/src/eager.rs
index 1464320ba..14af628a1 100644
--- a/crates/hir_expand/src/eager.rs
+++ b/crates/hir_expand/src/eager.rs
@@ -113,6 +113,7 @@ pub fn expand_eager_macro(
113 113
114 let ast_map = db.ast_id_map(macro_call.file_id); 114 let ast_map = db.ast_id_map(macro_call.file_id);
115 let call_id = InFile::new(macro_call.file_id, ast_map.ast_id(&macro_call.value)); 115 let call_id = InFile::new(macro_call.file_id, ast_map.ast_id(&macro_call.value));
116 let fragment = crate::to_fragment_kind(&macro_call.value);
116 117
117 // Note: 118 // Note:
118 // When `lazy_expand` is called, its *parent* file must be already exists. 119 // When `lazy_expand` is called, its *parent* file must be already exists.
@@ -152,7 +153,7 @@ pub fn expand_eager_macro(
152 arg_or_expansion: Arc::new(expanded.subtree), 153 arg_or_expansion: Arc::new(expanded.subtree),
153 included_file: expanded.included_file, 154 included_file: expanded.included_file,
154 }), 155 }),
155 kind: MacroCallKind::FnLike { ast_id: call_id, fragment: expanded.fragment }, 156 kind: MacroCallKind::FnLike { ast_id: call_id, fragment },
156 }; 157 };
157 158
158 Ok(db.intern_macro(loc)) 159 Ok(db.intern_macro(loc))
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs
index 6588aa46c..7647bb08b 100644
--- a/crates/hir_ty/src/tests/macros.rs
+++ b/crates/hir_ty/src/tests/macros.rs
@@ -752,6 +752,24 @@ fn bar() -> u32 {0}
752} 752}
753 753
754#[test] 754#[test]
755fn infer_builtin_macros_include_expression() {
756 check_types(
757 r#"
758//- /main.rs
759#[rustc_builtin_macro]
760macro_rules! include {() => {}}
761fn main() {
762 let i = include!("bla.rs");
763 i;
764 //^ i32
765}
766//- /bla.rs
7670
768 "#,
769 )
770}
771
772#[test]
755fn infer_builtin_macros_include_child_mod() { 773fn infer_builtin_macros_include_child_mod() {
756 check_types( 774 check_types(
757 r#" 775 r#"