about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs26
-rw-r--r--tests/ui/test-attrs/custom-test-frameworks/issue-107454.rs10
-rw-r--r--tests/ui/test-attrs/custom-test-frameworks/issue-107454.stderr15
3 files changed, 49 insertions, 2 deletions
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index e02c7e6c01b..8d892fa4170 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -33,7 +33,23 @@ pub fn expand_test_case(
     }
 
     let sp = ecx.with_def_site_ctxt(attr_sp);
-    let mut item = anno_item.expect_item();
+    let (mut item, is_stmt) = match anno_item {
+        Annotatable::Item(item) => (item, false),
+        Annotatable::Stmt(stmt) if let ast::StmtKind::Item(_) = stmt.kind => if let ast::StmtKind::Item(i) = stmt.into_inner().kind {
+            (i, true)
+        } else {
+            unreachable!()
+        },
+        _ => {
+            ecx.struct_span_err(
+                anno_item.span(),
+                "`#[test_case]` attribute is only allowed on items",
+            )
+            .emit();
+
+            return vec![];
+        }
+    };
     item = item.map(|mut item| {
         let test_path_symbol = Symbol::intern(&item_path(
             // skip the name of the root module
@@ -50,7 +66,13 @@ pub fn expand_test_case(
         item
     });
 
-    return vec![Annotatable::Item(item)];
+    let ret = if is_stmt {
+        Annotatable::Stmt(P(ecx.stmt_item(item.span, item)))
+    } else {
+        Annotatable::Item(item)
+    };
+
+    vec![ret]
 }
 
 pub fn expand_test(
diff --git a/tests/ui/test-attrs/custom-test-frameworks/issue-107454.rs b/tests/ui/test-attrs/custom-test-frameworks/issue-107454.rs
new file mode 100644
index 00000000000..2bb133e8bfd
--- /dev/null
+++ b/tests/ui/test-attrs/custom-test-frameworks/issue-107454.rs
@@ -0,0 +1,10 @@
+// compile-flags: --test
+
+#![feature(custom_test_frameworks)]
+#![deny(unnameable_test_items)]
+
+fn foo() {
+    #[test_case]
+    //~^ ERROR cannot test inner items [unnameable_test_items]
+    fn test2() {}
+}
diff --git a/tests/ui/test-attrs/custom-test-frameworks/issue-107454.stderr b/tests/ui/test-attrs/custom-test-frameworks/issue-107454.stderr
new file mode 100644
index 00000000000..bd604afb79f
--- /dev/null
+++ b/tests/ui/test-attrs/custom-test-frameworks/issue-107454.stderr
@@ -0,0 +1,15 @@
+error: cannot test inner items
+  --> $DIR/issue-107454.rs:7:5
+   |
+LL |     #[test_case]
+   |     ^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-107454.rs:4:9
+   |
+LL | #![deny(unnameable_test_items)]
+   |         ^^^^^^^^^^^^^^^^^^^^^
+   = note: this error originates in the attribute macro `test_case` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+