about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-11-27 04:54:08 +0000
committerbors <bors@rust-lang.org>2024-11-27 04:54:08 +0000
commit83965efe6ad57a2baf3b5d5678d094bf9cd936dd (patch)
tree3b4dd763282381ba82a65d5db14fb3db54c36c53
parent48696f5bd64f58e1a3d98ccb2a801e079ddef30b (diff)
parent993e084eb1eb8bc29eae0620bbbb2c3009cec6dd (diff)
downloadrust-83965efe6ad57a2baf3b5d5678d094bf9cd936dd.tar.gz
rust-83965efe6ad57a2baf3b5d5678d094bf9cd936dd.zip
Auto merge of #133274 - ehuss:macro_rules-edition-from-pm, r=compiler-errors
Use edition of `macro_rules` when compiling the macro

This changes the edition assigned to a macro_rules macro when it is compiled to use the edition of where the macro came from instead of the local crate's edition.

This fixes a problem when a macro_rules macro is created by a proc-macro. Previously that macro would be tagged with the local edition, which would cause problems with using the correct edition behavior inside the macro. For example, the check for unsafe attributes would cause errors in 2024 when using proc-macros from older editions.

This is partially related to https://github.com/rust-lang/rust/issues/132906. Unfortunately this is only a half fix for that issue. It fixes the error that happens in 2024, but does not fix the lint firing in 2021. I'm still trying to think of some way to fix that, but I'm running low on ideas.
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs2
-rw-r--r--tests/ui/proc-macro/auxiliary/macro_rules_edition_pm.rs42
-rw-r--r--tests/ui/proc-macro/macro_rules_edition_from_pm.rs27
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm.rs22
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm.rs17
5 files changed, 109 insertions, 1 deletions
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index bf27b767a49..7536869e2fe 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -191,7 +191,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
             ItemKind::Const(..) => DefKind::Const,
             ItemKind::Fn(..) | ItemKind::Delegation(..) => DefKind::Fn,
             ItemKind::MacroDef(def) => {
-                let edition = self.resolver.tcx.sess.edition();
+                let edition = i.span.edition();
                 let macro_data =
                     self.resolver.compile_macro(def, i.ident, &i.attrs, i.span, i.id, edition);
                 let macro_kind = macro_data.ext.macro_kind();
diff --git a/tests/ui/proc-macro/auxiliary/macro_rules_edition_pm.rs b/tests/ui/proc-macro/auxiliary/macro_rules_edition_pm.rs
new file mode 100644
index 00000000000..a4fd76b9c9d
--- /dev/null
+++ b/tests/ui/proc-macro/auxiliary/macro_rules_edition_pm.rs
@@ -0,0 +1,42 @@
+//@ force-host
+//@ no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro]
+pub fn make_edition_macro(_input: TokenStream) -> TokenStream {
+    "macro_rules! edition {
+        ($_:expr) => {
+            2024
+        };
+        (const {}) => {
+            2021
+        };
+    }
+    "
+    .parse()
+    .unwrap()
+}
+
+#[proc_macro]
+pub fn make_nested_edition_macro(_input: TokenStream) -> TokenStream {
+    "macro_rules! make_inner {
+        () => {
+            macro_rules! edition_inner {
+                ($_:expr) => {
+                    2024
+                };
+                (const {}) => {
+                    2021
+                };
+            }
+        };
+    }
+    "
+    .parse()
+    .unwrap()
+}
diff --git a/tests/ui/proc-macro/macro_rules_edition_from_pm.rs b/tests/ui/proc-macro/macro_rules_edition_from_pm.rs
new file mode 100644
index 00000000000..3ba80f5177a
--- /dev/null
+++ b/tests/ui/proc-macro/macro_rules_edition_from_pm.rs
@@ -0,0 +1,27 @@
+// Tests how edition hygiene works for macro_rules macros generated from a
+// proc-macro.
+// See https://github.com/rust-lang/rust/issues/132906
+
+//@ aux-crate: macro_rules_edition_pm=macro_rules_edition_pm.rs
+//@ revisions: edition2021 edition2024
+//@[edition2021] edition:2021
+//@[edition2024] edition:2024
+//@[edition2024] compile-flags: -Zunstable-options
+//@ check-pass
+
+// This checks how the expr fragment specifier works.
+macro_rules_edition_pm::make_edition_macro!{}
+
+const _: () = {
+    assert!(edition!(const {}) == 2021);
+};
+
+// This checks how the expr fragment specifier from a nested macro.
+macro_rules_edition_pm::make_nested_edition_macro!{}
+make_inner!{}
+
+const _: () = {
+    assert!(edition_inner!(const {}) == 2021);
+};
+
+fn main() {}
diff --git a/tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm.rs b/tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm.rs
new file mode 100644
index 00000000000..557731d82d3
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm.rs
@@ -0,0 +1,22 @@
+//@ force-host
+//@ no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro]
+pub fn missing_unsafe(_input: TokenStream) -> TokenStream {
+    "#[no_mangle] pub fn abc() {}".parse().unwrap()
+}
+
+#[proc_macro]
+pub fn macro_rules_missing_unsafe(_input: TokenStream) -> TokenStream {
+    "macro_rules! make_fn {
+        () => { #[no_mangle] pub fn foo() { } };
+    }"
+    .parse()
+    .unwrap()
+}
diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm.rs
new file mode 100644
index 00000000000..782a3942236
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm.rs
@@ -0,0 +1,17 @@
+// Test for unsafe attributes generated by a proc-macro.
+// See https://github.com/rust-lang/rust/issues/132906
+
+//@ revisions: edition2021 edition2024
+//@ check-pass
+//@[edition2021] edition:2021
+//@[edition2024] edition:2024
+//@[edition2024] compile-flags: -Zunstable-options
+//@ aux-crate: unsafe_attributes_pm=unsafe-attributes-pm.rs
+
+unsafe_attributes_pm::missing_unsafe!();
+
+unsafe_attributes_pm::macro_rules_missing_unsafe!();
+
+make_fn!();
+
+fn main() {}