]> git.lizzy.rs Git - rust.git/commitdiff
resolve: Fix access to extern and stdlib prelude from opaque macros
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Sat, 6 Jul 2019 16:45:23 +0000 (19:45 +0300)
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Wed, 10 Jul 2019 21:12:08 +0000 (00:12 +0300)
Ok, it's hard to explain what happens, but identifier's hygienic contexts need to be "adjusted" to modules/scopes before they are resolved in them.
To be resolved in all kinds on preludes the identifier needs to be adjusted to the root expansion (aka "no expansion").

Previously this was done for the `macro m() { ::my_crate::foo }` case, but forgotten for all other cases.

src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/test/ui/hygiene/auxiliary/stdlib-prelude.rs [new file with mode: 0644]
src/test/ui/hygiene/stdlib-prelude-from-opaque-early.rs [new file with mode: 0644]
src/test/ui/hygiene/stdlib-prelude-from-opaque-late.rs [new file with mode: 0644]

index 795ff3faffa333013fb6fbca8229290720305ad3..1216a083700d93839a68bb439aa5ddd7cb8f01cd 100644 (file)
@@ -2247,6 +2247,7 @@ fn resolve_ident_in_lexical_scope(&mut self,
         }
 
         if !module.no_implicit_prelude {
+            ident.span.adjust(Mark::root());
             if ns == TypeNS {
                 if let Some(binding) = self.extern_prelude_get(ident, !record_used) {
                     return Some(LexicalScopeBinding::Item(binding));
index 077c126bdee66ae89b39399826e6f5f6162f4924..7ad54d572f4e8b22a738bc8e2c7d85307e4fb0d2 100644 (file)
@@ -856,6 +856,7 @@ struct Flags: u8 {
                     match self.hygienic_lexical_parent(module, &mut ident.span) {
                         Some(parent_module) => WhereToResolve::Module(parent_module),
                         None => {
+                            ident.span.adjust(Mark::root());
                             use_prelude = !module.no_implicit_prelude;
                             match ns {
                                 TypeNS => WhereToResolve::ExternPrelude,
diff --git a/src/test/ui/hygiene/auxiliary/stdlib-prelude.rs b/src/test/ui/hygiene/auxiliary/stdlib-prelude.rs
new file mode 100644 (file)
index 0000000..81b0b7f
--- /dev/null
@@ -0,0 +1,3 @@
+#![feature(decl_macro)]
+
+pub macro stdlib_macro() {}
diff --git a/src/test/ui/hygiene/stdlib-prelude-from-opaque-early.rs b/src/test/ui/hygiene/stdlib-prelude-from-opaque-early.rs
new file mode 100644 (file)
index 0000000..c8c5c72
--- /dev/null
@@ -0,0 +1,21 @@
+// check-pass
+// aux-build:stdlib-prelude.rs
+
+#![feature(decl_macro)]
+#![feature(prelude_import)]
+
+extern crate stdlib_prelude;
+
+#[prelude_import]
+use stdlib_prelude::*;
+
+macro mac() {
+    mod m {
+        use std::mem; // OK (extern prelude)
+        stdlib_macro!(); // OK (stdlib prelude)
+    }
+}
+
+mac!();
+
+fn main() {}
diff --git a/src/test/ui/hygiene/stdlib-prelude-from-opaque-late.rs b/src/test/ui/hygiene/stdlib-prelude-from-opaque-late.rs
new file mode 100644 (file)
index 0000000..cf65de2
--- /dev/null
@@ -0,0 +1,16 @@
+// check-pass
+
+#![feature(decl_macro)]
+
+macro mac() {
+    mod m {
+        fn f() {
+            std::mem::drop(0); // OK (extern prelude)
+            drop(0); // OK (stdlib prelude)
+        }
+    }
+}
+
+mac!();
+
+fn main() {}