diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 9b43c11f0f3d364a02252fcdf0064d2701666889..a97cac7e514c98082c8591acaa441840ac9edacc 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -14,31 +14,31 @@ pub fn expand( ecx: &mut ExtCtxt<'_>, _span: Span, meta_item: &ast::MetaItem, - mut item: Annotatable, + item: Annotatable, ) -> Vec { check_builtin_macro_attribute(ecx, meta_item, sym::global_allocator); - let not_static = |item: Annotatable| { + let orig_item = item.clone(); + let not_static = || { ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "allocators must be statics"); - vec![item] + vec![orig_item.clone()] }; - let orig_item = item.clone(); - let mut is_stmt = false; // Allow using `#[global_allocator]` on an item statement - if let Annotatable::Stmt(stmt) = &item { - if let StmtKind::Item(item_) = &stmt.kind { - item = Annotatable::Item(item_.clone()); - is_stmt = true; - } - } - - let item = match item { + // FIXME - if we get deref patterns, use them to reduce duplication here + let (item, is_stmt) = match &item { Annotatable::Item(item) => match item.kind { - ItemKind::Static(..) => item, - _ => return not_static(Annotatable::Item(item)), + ItemKind::Static(..) => (item, false), + _ => return not_static(), + }, + Annotatable::Stmt(stmt) => match &stmt.kind { + StmtKind::Item(item_) => match item_.kind { + ItemKind::Static(..) => (item_, true), + _ => return not_static(), + }, + _ => return not_static(), }, - _ => return not_static(item), + _ => return not_static(), }; // Generate a bunch of new items using the AllocFnFactory diff --git a/src/test/ui/proc-macro/issue-83469-global-alloc-invalid-stmt.rs b/src/test/ui/proc-macro/issue-83469-global-alloc-invalid-stmt.rs new file mode 100644 index 0000000000000000000000000000000000000000..25adc5d25780b1f0e1bc6895258f85dd4cacca1d --- /dev/null +++ b/src/test/ui/proc-macro/issue-83469-global-alloc-invalid-stmt.rs @@ -0,0 +1,10 @@ +// Regression test for issue #83469 +// Ensures that we recover from `#[global_alloc]` on an invalid +// stmt without an ICE + +fn outer() { + #[global_allocator] + fn inner() {} //~ ERROR allocators must be statics +} + +fn main() {} diff --git a/src/test/ui/proc-macro/issue-83469-global-alloc-invalid-stmt.stderr b/src/test/ui/proc-macro/issue-83469-global-alloc-invalid-stmt.stderr new file mode 100644 index 0000000000000000000000000000000000000000..ec0e3c4c7546f8c28f9a3f647f1e85a8d25ac733 --- /dev/null +++ b/src/test/ui/proc-macro/issue-83469-global-alloc-invalid-stmt.stderr @@ -0,0 +1,8 @@ +error: allocators must be statics + --> $DIR/issue-83469-global-alloc-invalid-stmt.rs:7:5 + | +LL | fn inner() {} + | ^^^^^^^^^^^^^ + +error: aborting due to previous error +