diff --git a/crates/hir_def/src/macro_expansion_tests/builtin.rs b/crates/hir_def/src/macro_expansion_tests/builtin.rs index 1b25caa0ff1b..6982116522c6 100644 --- a/crates/hir_def/src/macro_expansion_tests/builtin.rs +++ b/crates/hir_def/src/macro_expansion_tests/builtin.rs @@ -270,3 +270,63 @@ unsafe { "##]], ); } + +#[test] +fn test_include_bytes_expand() { + check( + r#" +#[rustc_builtin_macro] +macro_rules! include_bytes { + ($file:expr) => {{ /* compiler built-in */ }}; + ($file:expr,) => {{ /* compiler built-in */ }}; +} + +fn main() { include_bytes("foo"); } +"#, + expect![[r##" +#[rustc_builtin_macro] +macro_rules! include_bytes { + ($file:expr) => {{ /* compiler built-in */ }}; + ($file:expr,) => {{ /* compiler built-in */ }}; +} + +fn main() { include_bytes("foo"); } +"##]], + ); +} + +#[test] +fn test_concat_expand() { + check( + r##" +#[rustc_builtin_macro] +macro_rules! concat {} + +fn main() { concat!("foo", "r", 0, r#"bar"#, "\n", false); } +"##, + expect![[r##" +#[rustc_builtin_macro] +macro_rules! concat {} + +fn main() { "foor0bar\nfalse"; } +"##]], + ); +} + +#[test] +fn test_concat_idents_expand() { + check( + r##" +#[rustc_builtin_macro] +macro_rules! concat_idents {} + +fn main() { concat_idents!(foo, bar); } +"##, + expect![[r##" +#[rustc_builtin_macro] +macro_rules! concat_idents {} + +fn main() { foobar; } +"##]], + ); +} diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs index f988ffff09ee..4b801eb2a154 100644 --- a/crates/hir_expand/src/builtin_macro.rs +++ b/crates/hir_expand/src/builtin_macro.rs @@ -565,146 +565,3 @@ fn option_env_expand( ExpandResult::ok(Some(ExpandedEager::new(expanded))) } - -#[cfg(test)] -mod tests { - use std::sync::Arc; - - use base_db::{fixture::WithFixture, SourceDatabase}; - use expect_test::{expect, Expect}; - use syntax::ast::HasName; - - use crate::{ - name::AsName, test_db::TestDB, AstNode, EagerCallInfo, ExpandTo, MacroCallId, - MacroCallKind, MacroCallLoc, - }; - - use super::*; - - fn expand_builtin_macro(ra_fixture: &str) -> String { - let (db, file_id) = TestDB::with_single_file(ra_fixture); - let parsed = db.parse(file_id); - let mut macro_rules: Vec<_> = - parsed.syntax_node().descendants().filter_map(ast::MacroRules::cast).collect(); - let mut macro_calls: Vec<_> = - parsed.syntax_node().descendants().filter_map(ast::MacroCall::cast).collect(); - - let ast_id_map = db.ast_id_map(file_id.into()); - - assert_eq!(macro_rules.len(), 1, "test must contain exactly 1 `macro_rules!`"); - assert_eq!(macro_calls.len(), 1, "test must contain exactly 1 macro call"); - let macro_rules = ast::Macro::from(macro_rules.pop().unwrap()); - let macro_call = macro_calls.pop().unwrap(); - - let expander = find_by_name(¯o_rules.name().unwrap().as_name()).unwrap(); - let ast_id = AstId::new(file_id.into(), ast_id_map.ast_id(¯o_rules)); - - let krate = CrateId(0); - let file_id = match expander { - Either::Left(expander) => { - // the first one should be a macro_rules - let def = MacroDefId { - krate: CrateId(0), - kind: MacroDefKind::BuiltIn(expander, ast_id), - local_inner: false, - }; - - let loc = MacroCallLoc { - def, - krate, - eager: None, - kind: MacroCallKind::FnLike { - ast_id: AstId::new(file_id.into(), ast_id_map.ast_id(¯o_call)), - expand_to: ExpandTo::Expr, - }, - }; - - let id: MacroCallId = db.intern_macro(loc); - id.as_file() - } - Either::Right(expander) => { - // the first one should be a macro_rules - let def = MacroDefId { - krate, - kind: MacroDefKind::BuiltInEager(expander, ast_id), - local_inner: false, - }; - - let args = macro_call.token_tree().unwrap(); - let parsed_args = mbe::syntax_node_to_token_tree(args.syntax()).0; - let call_id = AstId::new(file_id.into(), ast_id_map.ast_id(¯o_call)); - - let arg_id = db.intern_macro(MacroCallLoc { - def, - krate, - eager: Some(EagerCallInfo { - arg_or_expansion: Arc::new(parsed_args.clone()), - included_file: None, - }), - kind: MacroCallKind::FnLike { ast_id: call_id, expand_to: ExpandTo::Expr }, - }); - - let expanded = expander.expand(&db, arg_id, &parsed_args).value.unwrap(); - let expand_to = crate::ExpandTo::from_call_site(¯o_call); - let loc = MacroCallLoc { - def, - krate, - eager: Some(EagerCallInfo { - arg_or_expansion: Arc::new(expanded.subtree), - included_file: expanded.included_file, - }), - kind: MacroCallKind::FnLike { ast_id: call_id, expand_to }, - }; - - let id: MacroCallId = db.intern_macro(loc); - id.as_file() - } - }; - - db.parse_or_expand(file_id).unwrap().to_string() - } - - fn check_expansion(ra_fixture: &str, expect: Expect) { - let expansion = expand_builtin_macro(ra_fixture); - expect.assert_eq(&expansion); - } - - #[test] - fn test_include_bytes_expand() { - check_expansion( - r#" - #[rustc_builtin_macro] - macro_rules! include_bytes { - ($file:expr) => {{ /* compiler built-in */ }}; - ($file:expr,) => {{ /* compiler built-in */ }}; - } - include_bytes("foo"); - "#, - expect![[r#"b"""#]], - ); - } - - #[test] - fn test_concat_expand() { - check_expansion( - r##" - #[rustc_builtin_macro] - macro_rules! concat {} - concat!("foo", "r", 0, r#"bar"#, "\n", false); - "##, - expect![[r#""foor0bar\nfalse""#]], - ); - } - - #[test] - fn test_concat_idents_expand() { - check_expansion( - r##" - #[rustc_builtin_macro] - macro_rules! concat_idents {} - concat_idents!(foo, bar); - "##, - expect![[r#"foobar"#]], - ); - } -}