Skip to content
Permalink
Browse files

resolve: Fix access to extern and stdlib prelude from opaque macros

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.
  • Loading branch information...
petrochenkov committed Jul 6, 2019
1 parent f923942 commit 0ec6ea7333a8918a96f40110e014f2bbbd72281f
@@ -2247,6 +2247,7 @@ impl<'a> Resolver<'a> {
}

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));
@@ -856,6 +856,7 @@ impl<'a> Resolver<'a> {
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,
@@ -0,0 +1,3 @@
#![feature(decl_macro)]

pub macro stdlib_macro() {}
@@ -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() {}
@@ -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() {}

0 comments on commit 0ec6ea7

Please sign in to comment.
You can’t perform that action at this time.