Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

macros: hygienize use of core/std in builtin macros #46550

Merged
merged 4 commits into from
Dec 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ pub fn lower_crate(sess: &Session,
let _ignore = dep_graph.in_ignore();

LoweringContext {
crate_root: std_inject::injected_crate_name(krate),
crate_root: std_inject::injected_crate_name(),
sess,
cstore,
parent_def: None,
Expand Down
8 changes: 6 additions & 2 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ use syntax::ext::base::Determinacy::Undetermined;
use syntax::ext::hygiene::Mark;
use syntax::ext::tt::macro_rules;
use syntax::parse::token::{self, Token};
use syntax::std_inject::injected_crate_name;
use syntax::symbol::keywords;
use syntax::symbol::Symbol;
use syntax::visit::{self, Visitor};
Expand Down Expand Up @@ -262,6 +263,10 @@ impl<'a> Resolver<'a> {
let module =
self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
self.populate_module_if_necessary(module);
if injected_crate_name().map_or(false, |name| item.ident.name == name) {
self.injected_crate = Some(module);
}

let used = self.process_legacy_macro_imports(item, module, expansion);
let binding =
(module, ty::Visibility::Public, sp, expansion).to_name_binding(self.arenas);
Expand Down Expand Up @@ -561,8 +566,7 @@ impl<'a> Resolver<'a> {
if let Some(id) = self.definitions.as_local_node_id(def_id) {
self.local_macro_def_scopes[&id]
} else if def_id.krate == BUILTIN_MACROS_CRATE {
// FIXME(jseyfried): This happens when `include!()`ing a `$crate::` path, c.f, #40469.
self.graph_root
self.injected_crate.unwrap_or(self.graph_root)
} else {
let module_def_id = ty::DefIdTree::parent(&*self, def_id).unwrap();
self.get_module(module_def_id)
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,8 @@ pub struct Resolver<'a> {

// Only used for better errors on `fn(): fn()`
current_type_ascription: Vec<Span>,

injected_crate: Option<Module<'a>>,
}

pub struct ResolverArenas<'a> {
Expand Down Expand Up @@ -1532,6 +1534,7 @@ impl<'a> Resolver<'a> {
found_unresolved_macro: false,
unused_macros: FxHashSet(),
current_type_ascription: Vec::new(),
injected_crate: None,
}
}

Expand Down
11 changes: 7 additions & 4 deletions src/librustc_resolve/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use syntax::errors::DiagnosticBuilder;
use syntax::ext::base::{self, Annotatable, Determinacy, MultiModifier, MultiDecorator};
use syntax::ext::base::{MacroKind, SyntaxExtension, Resolver as SyntaxResolver};
use syntax::ext::expand::{Expansion, ExpansionKind, Invocation, InvocationKind, find_attr_invoc};
use syntax::ext::hygiene::Mark;
use syntax::ext::hygiene::{Mark, MarkKind};
use syntax::ext::placeholders::placeholder;
use syntax::ext::tt::macro_rules;
use syntax::feature_gate::{self, emit_feature_err, GateIssue};
Expand Down Expand Up @@ -297,16 +297,19 @@ impl<'a> base::Resolver for Resolver<'a> {
InvocationKind::Attr { attr: None, .. } => return Ok(None),
_ => self.resolve_invoc_to_def(invoc, scope, force)?,
};
let def_id = def.def_id();

self.macro_defs.insert(invoc.expansion_data.mark, def.def_id());
self.macro_defs.insert(invoc.expansion_data.mark, def_id);
let normal_module_def_id =
self.macro_def_scope(invoc.expansion_data.mark).normal_ancestor_id;
self.definitions.add_macro_def_scope(invoc.expansion_data.mark, normal_module_def_id);

self.unused_macros.remove(&def.def_id());
self.unused_macros.remove(&def_id);
let ext = self.get_macro(def);
if ext.is_modern() {
invoc.expansion_data.mark.set_modern();
invoc.expansion_data.mark.set_kind(MarkKind::Modern);
} else if def_id.krate == BUILTIN_MACROS_CRATE {
invoc.expansion_data.mark.set_kind(MarkKind::Builtin);
}
Ok(Some(ext))
}
Expand Down
15 changes: 6 additions & 9 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ use fold::{self, Folder};
use parse::{self, parser, DirectoryOwnership};
use parse::token;
use ptr::P;
use symbol::Symbol;
use symbol::{keywords, Ident, Symbol};
use util::small_vector::SmallVector;

use std::collections::HashMap;
use std::iter;
use std::path::PathBuf;
use std::rc::Rc;
use std::default::Default;
Expand Down Expand Up @@ -664,7 +665,6 @@ pub struct ExpansionData {
pub struct ExtCtxt<'a> {
pub parse_sess: &'a parse::ParseSess,
pub ecfg: expand::ExpansionConfig<'a>,
pub crate_root: Option<&'static str>,
pub root_path: PathBuf,
pub resolver: &'a mut Resolver,
pub resolve_err_count: usize,
Expand All @@ -680,7 +680,6 @@ impl<'a> ExtCtxt<'a> {
ExtCtxt {
parse_sess,
ecfg,
crate_root: None,
root_path: PathBuf::new(),
resolver,
resolve_err_count: 0,
Expand Down Expand Up @@ -822,12 +821,10 @@ impl<'a> ExtCtxt<'a> {
ast::Ident::from_str(st)
}
pub fn std_path(&self, components: &[&str]) -> Vec<ast::Ident> {
let mut v = Vec::new();
if let Some(s) = self.crate_root {
v.push(self.ident_of(s));
}
v.extend(components.iter().map(|s| self.ident_of(s)));
v
let def_site = SyntaxContext::empty().apply_mark(self.current_expansion.mark);
iter::once(Ident { ctxt: def_site, ..keywords::DollarCrate.ident() })
.chain(components.iter().map(|s| self.ident_of(s)))
.collect()
}
pub fn name_of(&self, st: &str) -> ast::Name {
Symbol::intern(st)
Expand Down
5 changes: 4 additions & 1 deletion src/libsyntax/ext/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,12 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
types: Vec<P<ast::Ty>>,
bindings: Vec<ast::TypeBinding> )
-> ast::Path {
use syntax::parse::token;

let last_identifier = idents.pop().unwrap();
let mut segments: Vec<ast::PathSegment> = Vec::new();
if global {
if global &&
!idents.first().map_or(false, |&ident| token::Ident(ident).is_path_segment_keyword()) {
segments.push(ast::PathSegment::crate_root(span));
}

Expand Down
2 changes: 0 additions & 2 deletions src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ use parse::{DirectoryOwnership, PResult};
use parse::token::{self, Token};
use parse::parser::Parser;
use ptr::P;
use std_inject;
use symbol::Symbol;
use symbol::keywords;
use syntax_pos::{Span, DUMMY_SP};
Expand Down Expand Up @@ -219,7 +218,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}

pub fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
self.cx.crate_root = std_inject::injected_crate_name(&krate);
let mut module = ModuleData {
mod_path: vec![Ident::from_str(&self.cx.ecfg.crate_name)],
directory: self.cx.codemap().span_to_unmapped_path(krate.span),
Expand Down
20 changes: 19 additions & 1 deletion src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use util::parser::{self, AssocOp, Fixity};
use attr;
use codemap::{self, CodeMap};
use syntax_pos::{self, BytePos};
use syntax_pos::hygiene::{Mark, MarkKind, SyntaxContext};
use parse::token::{self, BinOpToken, Token};
use parse::lexer::comments;
use parse::{self, ParseSess};
Expand Down Expand Up @@ -93,7 +94,7 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
is_expanded: bool) -> io::Result<()> {
let mut s = State::new_from_input(cm, sess, filename, input, out, ann, is_expanded);

if is_expanded && !std_inject::injected_crate_name(krate).is_none() {
if is_expanded && !std_inject::injected_crate_name().is_none() {
// We need to print `#![no_std]` (and its feature gate) so that
// compiling pretty-printed source won't inject libstd again.
// However we don't want these attributes in the AST because
Expand Down Expand Up @@ -734,6 +735,8 @@ pub trait PrintState<'a> {
if segment.identifier.name != keywords::CrateRoot.name() &&
segment.identifier.name != keywords::DollarCrate.name() {
self.writer().word(&segment.identifier.name.as_str())?;
} else if segment.identifier.name == keywords::DollarCrate.name() {
self.print_dollar_crate(segment.identifier.ctxt)?;
}
}
self.writer().space()?;
Expand Down Expand Up @@ -822,6 +825,19 @@ pub trait PrintState<'a> {
}

fn nbsp(&mut self) -> io::Result<()> { self.writer().word(" ") }

fn print_dollar_crate(&mut self, mut ctxt: SyntaxContext) -> io::Result<()> {
if let Some(mark) = ctxt.adjust(Mark::root()) {
// Make a best effort to print something that complies
if mark.kind() == MarkKind::Builtin {
if let Some(name) = std_inject::injected_crate_name() {
self.writer().word("::")?;
self.writer().word(name)?;
}
}
}
Ok(())
}
}

impl<'a> PrintState<'a> for State<'a> {
Expand Down Expand Up @@ -2411,6 +2427,8 @@ impl<'a> State<'a> {
if let Some(ref parameters) = segment.parameters {
self.print_path_parameters(parameters, colons_before_params)?;
}
} else if segment.identifier.name == keywords::DollarCrate.name() {
self.print_dollar_crate(segment.identifier.ctxt)?;
}
Ok(())
}
Expand Down
26 changes: 15 additions & 11 deletions src/libsyntax/std_inject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use ast;
use attr;
use std::cell::Cell;
use ext::hygiene::{Mark, SyntaxContext};
use symbol::{Symbol, keywords};
use syntax_pos::{DUMMY_SP, Span};
Expand All @@ -34,22 +35,25 @@ fn ignored_span(sp: Span) -> Span {
sp.with_ctxt(SyntaxContext::empty().apply_mark(mark))
}

pub fn injected_crate_name(krate: &ast::Crate) -> Option<&'static str> {
if attr::contains_name(&krate.attrs, "no_core") {
None
} else if attr::contains_name(&krate.attrs, "no_std") {
Some("core")
} else {
Some("std")
}
pub fn injected_crate_name() -> Option<&'static str> {
INJECTED_CRATE_NAME.with(|name| name.get())
}

thread_local! {
static INJECTED_CRATE_NAME: Cell<Option<&'static str>> = Cell::new(None);
}

pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<String>) -> ast::Crate {
let name = match injected_crate_name(&krate) {
Some(name) => name,
None => return krate,
let name = if attr::contains_name(&krate.attrs, "no_core") {
return krate;
} else if attr::contains_name(&krate.attrs, "no_std") {
"core"
} else {
"std"
};

INJECTED_CRATE_NAME.with(|opt_name| opt_name.set(Some(name)));

let crate_name = Symbol::intern(&alt_std_name.unwrap_or_else(|| name.to_string()));

krate.module.items.insert(0, P(ast::Item {
Expand Down
3 changes: 1 addition & 2 deletions src/libsyntax/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ fn generate_test_harness(sess: &ParseSess,

let mark = Mark::fresh(Mark::root());

let mut cx: TestCtxt = TestCtxt {
let cx = TestCtxt {
span_diagnostic: sd,
ext_cx: ExtCtxt::new(sess, ExpansionConfig::default("test".to_string()), resolver),
path: Vec::new(),
Expand All @@ -283,7 +283,6 @@ fn generate_test_harness(sess: &ParseSess,
toplevel_reexport: None,
ctxt: SyntaxContext::empty().apply_mark(mark),
};
cx.ext_cx.crate_root = Some("std");

mark.set_expn_info(ExpnInfo {
call_site: DUMMY_SP,
Expand Down
9 changes: 2 additions & 7 deletions src/libsyntax_ext/deriving/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use deriving::path_std;
use deriving::generic::*;
use deriving::generic::ty::*;

use syntax::ast::MetaItem;
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax_pos::Span;
Expand All @@ -28,15 +28,10 @@ pub fn expand_deriving_copy(cx: &mut ExtCtxt,
mitem: &MetaItem,
item: &Annotatable,
push: &mut FnMut(Annotatable)) {
let mut v = cx.crate_root.map(|s| vec![s]).unwrap_or(Vec::new());
v.push("marker");
v.push("Copy");
let path = Path::new(v);

let trait_def = TraitDef {
span,
attributes: Vec::new(),
path,
path: path_std!(cx, marker::Copy),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
is_unsafe: false,
Expand Down
5 changes: 3 additions & 2 deletions src/libsyntax_ext/deriving/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use deriving::path_std;
use deriving::generic::*;
use deriving::generic::ty::*;

Expand Down Expand Up @@ -55,7 +56,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
}));
}
ItemKind::Union(..) => {
bounds = vec![Literal(path_std!(cx, core::marker::Copy))];
bounds = vec![Literal(path_std!(cx, marker::Copy))];
is_shallow = true;
substructure = combine_substructure(Box::new(|c, s, sub| {
cs_clone_shallow("Clone", c, s, sub, true)
Expand All @@ -79,7 +80,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span,
attributes: Vec::new(),
path: path_std!(cx, core::clone::Clone),
path: path_std!(cx, clone::Clone),
additional_bounds: bounds,
generics: LifetimeBounds::empty(),
is_unsafe: false,
Expand Down
3 changes: 2 additions & 1 deletion src/libsyntax_ext/deriving/cmp/eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use deriving::path_std;
use deriving::generic::*;
use deriving::generic::ty::*;

Expand All @@ -30,7 +31,7 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span,
attributes: Vec::new(),
path: path_std!(cx, core::cmp::Eq),
path: path_std!(cx, cmp::Eq),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
is_unsafe: false,
Expand Down
5 changes: 3 additions & 2 deletions src/libsyntax_ext/deriving/cmp/ord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use deriving::path_std;
use deriving::generic::*;
use deriving::generic::ty::*;

Expand All @@ -28,7 +29,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span,
attributes: Vec::new(),
path: path_std!(cx, core::cmp::Ord),
path: path_std!(cx, cmp::Ord),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
is_unsafe: false,
Expand All @@ -38,7 +39,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(),
args: vec![borrowed_self()],
ret_ty: Literal(path_std!(cx, core::cmp::Ordering)),
ret_ty: Literal(path_std!(cx, cmp::Ordering)),
attributes: attrs,
is_unsafe: false,
unify_fieldless_variants: true,
Expand Down
3 changes: 2 additions & 1 deletion src/libsyntax_ext/deriving/cmp/partial_eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use deriving::{path_local, path_std};
use deriving::generic::*;
use deriving::generic::ty::*;

Expand Down Expand Up @@ -93,7 +94,7 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span,
attributes: Vec::new(),
path: path_std!(cx, core::cmp::PartialEq),
path: path_std!(cx, cmp::PartialEq),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
is_unsafe: false,
Expand Down
Loading