]> git.lizzy.rs Git - rust.git/commitdiff
internal: move derived tests to the unified macro infra
authorAleksey Kladov <aleksey.kladov@gmail.com>
Sun, 10 Oct 2021 13:08:01 +0000 (16:08 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Sun, 10 Oct 2021 13:10:35 +0000 (16:10 +0300)
crates/hir_def/src/macro_expansion_tests.rs
crates/hir_def/src/macro_expansion_tests/builtin_derive_macro.rs [new file with mode: 0644]
crates/hir_def/src/macro_expansion_tests/builtin_fn_macro.rs
crates/hir_expand/src/builtin_derive_macro.rs

index f29d1443b921596852c39d5d9fdeea4dfec5a449..5f8bf44cc93ba5c3a0a5722dd5ad9a2be48a887d 100644 (file)
@@ -11,6 +11,7 @@
 
 mod mbe;
 mod builtin_fn_macro;
+mod builtin_derive_macro;
 
 use std::{iter, ops::Range};
 
@@ -26,7 +27,8 @@
 };
 
 use crate::{
-    db::DefDatabase, nameres::ModuleSource, resolver::HasResolver, test_db::TestDB, AsMacroCall,
+    db::DefDatabase, nameres::ModuleSource, resolver::HasResolver, src::HasSource, test_db::TestDB,
+    AsMacroCall, Lookup,
 };
 
 #[track_caller]
@@ -43,6 +45,21 @@ fn check(ra_fixture: &str, mut expect: Expect) {
         ModuleSource::Module(_) | ModuleSource::BlockExpr(_) => panic!(),
     };
 
+    // What we want to do is to replace all macros (fn-like, derive, attr) with
+    // their expansions. Turns out, we don't actually store enough information
+    // to do this precisely though! Specifically, if a macro expands to nothing,
+    // it leaves zero traces in def-map, so we can't get its expansion after the
+    // fact.
+    //
+    // This is the usual
+    // <https://github.com/rust-analyzer/rust-analyzer/issues/3407>
+    // resolve/record tension!
+    //
+    // So here we try to do a resolve, which is necessary a heuristic. For macro
+    // calls, we use `as_call_id_with_errors`. For derives, we look at the impls
+    // in the module and assume that, if impls's source is a different
+    // `HirFileId`, than it came from macro expansion.
+
     let mut expansions = Vec::new();
     for macro_call in source_file.syntax().descendants().filter_map(ast::MacroCall::cast) {
         let macro_call = InFile::new(source.file_id, &macro_call);
@@ -63,6 +80,7 @@ fn check(ra_fixture: &str, mut expect: Expect) {
     }
 
     let mut expanded_text = source_file.to_string();
+
     for (call, exp) in expansions.into_iter().rev() {
         let mut tree = false;
         let mut expect_errors = false;
@@ -106,6 +124,14 @@ fn check(ra_fixture: &str, mut expect: Expect) {
         expanded_text.replace_range(range, &expn_text)
     }
 
+    for impl_id in def_map[local_id].scope.impls() {
+        let src = impl_id.lookup(&db).source(&db);
+        if src.file_id.is_builtin_derive(&db).is_some() {
+            let pp = pretty_print_macro_expansion(src.value.syntax().clone());
+            format_to!(expanded_text, "\n{}", pp)
+        }
+    }
+
     expect.indent(false);
     expect.assert_eq(&expanded_text);
 }
diff --git a/crates/hir_def/src/macro_expansion_tests/builtin_derive_macro.rs b/crates/hir_def/src/macro_expansion_tests/builtin_derive_macro.rs
new file mode 100644 (file)
index 0000000..177409d
--- /dev/null
@@ -0,0 +1,70 @@
+//! Tests for `builtin_derive_macro.rs` from `hir_expand`.
+
+use expect_test::expect;
+
+use crate::macro_expansion_tests::check;
+
+#[test]
+fn test_copy_expand_simple() {
+    check(
+        r#"
+//- minicore: derive, copy
+#[derive(Copy)]
+struct Foo;
+"#,
+        expect![[r##"
+#[derive(Copy)]
+struct Foo;
+
+impl < > core::marker::Copy for Foo< > {}"##]],
+    );
+}
+
+#[test]
+fn test_copy_expand_with_type_params() {
+    check(
+        r#"
+//- minicore: derive, copy
+#[derive(Copy)]
+struct Foo<A, B>;
+"#,
+        expect![[r##"
+#[derive(Copy)]
+struct Foo<A, B>;
+
+impl <T0: core::marker::Copy, T1: core::marker::Copy> core::marker::Copy for Foo<T0, T1> {}"##]],
+    );
+}
+
+#[test]
+fn test_copy_expand_with_lifetimes() {
+    // We currently just ignore lifetimes
+    check(
+        r#"
+//- minicore: derive, copy
+#[derive(Copy)]
+struct Foo<A, B, 'a, 'b>;
+"#,
+        expect![[r##"
+#[derive(Copy)]
+struct Foo<A, B, 'a, 'b>;
+
+impl <T0: core::marker::Copy, T1: core::marker::Copy> core::marker::Copy for Foo<T0, T1> {}"##]],
+    );
+}
+
+#[test]
+fn test_clone_expand() {
+    check(
+        r#"
+//- minicore: derive, clone
+#[derive(Clone)]
+struct Foo<A, B>;
+"#,
+        expect![[r##"
+#[derive(Clone)]
+struct Foo<A, B>;
+
+impl <T0: core::clone::Clone, T1: core::clone::Clone> core::clone::Clone for Foo<T0, T1> {}"##]],
+    );
+}
index 6982116522c6ce6fddfc6b7355ed73b391e49a7f..06039e95c5f059bad1ed3bc931c2987a1b2731a8 100644 (file)
@@ -1,4 +1,4 @@
-//! Tests for builtin macros (see `builtin_macro.rs` in `hir_expand`).
+//! Tests for `builtin_fn_macro.rs` from `hir_expand`.
 
 use expect_test::expect;
 
index eeebe87acd64e712d2c37bcf97bdc2934c0e7fb8..d4fcf42dd3f483572f335b116581b455a72d2529 100644 (file)
@@ -258,128 +258,3 @@ fn partial_ord_expand(
     let krate = find_builtin_crate(db, id);
     expand_simple_derive(tt, quote! { #krate::cmp::PartialOrd })
 }
-
-#[cfg(test)]
-mod tests {
-    use base_db::{fixture::WithFixture, CrateId, SourceDatabase};
-    use expect_test::{expect, Expect};
-    use name::AsName;
-
-    use crate::{test_db::TestDB, AstId, MacroCallId, MacroCallKind, MacroCallLoc};
-
-    use super::*;
-
-    fn expand_builtin_derive(ra_fixture: &str) -> String {
-        let fixture = format!(
-            r#"//- /main.rs crate:main deps:core
-$0
-{}
-//- /lib.rs crate:core
-// empty
-"#,
-            ra_fixture
-        );
-
-        let (db, file_pos) = TestDB::with_position(&fixture);
-        let file_id = file_pos.file_id;
-        let ast_id_map = db.ast_id_map(file_id.into());
-        let parsed = db.parse(file_id);
-        let macros: Vec<_> =
-            parsed.syntax_node().descendants().filter_map(ast::Macro::cast).collect();
-        let items: Vec<_> = parsed
-            .syntax_node()
-            .descendants()
-            .filter(|node| !ast::Macro::can_cast(node.kind()))
-            .filter_map(ast::Item::cast)
-            .collect();
-
-        assert_eq!(macros.len(), 1, "test must contain exactly 1 macro definition");
-        assert_eq!(items.len(), 1, "test must contain exactly 1 item");
-
-        let macro_ast_id = AstId::new(file_id.into(), ast_id_map.ast_id(&macros[0]));
-        let name = match &macros[0] {
-            ast::Macro::MacroRules(rules) => rules.name().unwrap().as_name(),
-            ast::Macro::MacroDef(def) => def.name().unwrap().as_name(),
-        };
-
-        let expander = BuiltinDeriveExpander::find_by_name(&name).unwrap();
-
-        let ast_id = AstId::new(file_id.into(), ast_id_map.ast_id(&items[0]));
-
-        let loc = MacroCallLoc {
-            def: MacroDefId {
-                krate: CrateId(0),
-                kind: MacroDefKind::BuiltInDerive(expander, macro_ast_id),
-                local_inner: false,
-            },
-            krate: CrateId(0),
-            eager: None,
-            kind: MacroCallKind::Derive {
-                ast_id,
-                derive_name: name.to_string(),
-                derive_attr_index: 0,
-            },
-        };
-
-        let id: MacroCallId = db.intern_macro(loc);
-        let parsed = db.parse_or_expand(id.as_file()).unwrap();
-
-        // FIXME text() for syntax nodes parsed from token tree looks weird
-        // because there's no whitespace, see below
-        parsed.text().to_string()
-    }
-
-    fn check_derive(ra_fixture: &str, expected: Expect) {
-        let expanded = expand_builtin_derive(ra_fixture);
-        expected.assert_eq(&expanded);
-    }
-
-    #[test]
-    fn test_copy_expand_simple() {
-        check_derive(
-            r#"
-            macro Copy {}
-            #[derive(Copy)]
-            struct Foo;
-            "#,
-            expect![["impl< >core::marker::CopyforFoo< >{}"]],
-        );
-    }
-
-    #[test]
-    fn test_copy_expand_with_type_params() {
-        check_derive(
-            r#"
-            macro Copy {}
-            #[derive(Copy)]
-            struct Foo<A, B>;
-            "#,
-            expect![["impl<T0:core::marker::Copy,T1:core::marker::Copy>core::marker::CopyforFoo<T0,T1>{}"]],
-        );
-    }
-
-    #[test]
-    fn test_copy_expand_with_lifetimes() {
-        check_derive(
-            r#"
-            macro Copy {}
-            #[derive(Copy)]
-            struct Foo<A, B, 'a, 'b>;
-            "#,
-            // We currently just ignore lifetimes
-            expect![["impl<T0:core::marker::Copy,T1:core::marker::Copy>core::marker::CopyforFoo<T0,T1>{}"]],
-        );
-    }
-
-    #[test]
-    fn test_clone_expand() {
-        check_derive(
-            r#"
-            macro Clone {}
-            #[derive(Clone)]
-            struct Foo<A, B>;
-            "#,
-            expect![["impl<T0:core::clone::Clone,T1:core::clone::Clone>core::clone::CloneforFoo<T0,T1>{}"]],
-        );
-    }
-}