Skip to content

Commit 3274507

Browse files
committed
resolve: Reserve cfg/cfg_attr/derive only in attribute sub-namespace
1 parent 920a17a commit 3274507

File tree

5 files changed

+38
-31
lines changed

5 files changed

+38
-31
lines changed

Diff for: src/librustc_resolve/build_reduced_graph.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -770,27 +770,33 @@ impl<'a> Resolver<'a> {
770770
}
771771

772772
pub fn get_macro(&mut self, res: Res) -> Lrc<SyntaxExtension> {
773+
self.opt_get_macro(res).expect("expected `DefKind::Macro` or `Res::NonMacroAttr`")
774+
}
775+
776+
crate fn opt_get_macro(&mut self, res: Res) -> Option<Lrc<SyntaxExtension>> {
773777
let def_id = match res {
778+
Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) =>
779+
return Some(self.non_macro_attr(true)), // some dummy extension
774780
Res::Def(DefKind::Macro(..), def_id) => def_id,
775781
Res::NonMacroAttr(attr_kind) =>
776-
return self.non_macro_attr(attr_kind == NonMacroAttrKind::Tool),
777-
_ => panic!("expected `DefKind::Macro` or `Res::NonMacroAttr`"),
782+
return Some(self.non_macro_attr(attr_kind == NonMacroAttrKind::Tool)),
783+
_ => return None,
778784
};
779785
if let Some(ext) = self.macro_map.get(&def_id) {
780-
return ext.clone();
786+
return Some(ext.clone());
781787
}
782788

783789
let macro_def = match self.cstore.load_macro_untracked(def_id, &self.session) {
784790
LoadedMacro::MacroDef(macro_def) => macro_def,
785-
LoadedMacro::ProcMacro(ext) => return ext,
791+
LoadedMacro::ProcMacro(ext) => return Some(ext),
786792
};
787793

788794
let ext = Lrc::new(macro_rules::compile(&self.session.parse_sess,
789795
&self.session.features_untracked(),
790796
&macro_def,
791797
self.cstore.crate_edition_untracked(def_id.krate)));
792798
self.macro_map.insert(def_id, ext.clone());
793-
ext
799+
Some(ext)
794800
}
795801

796802
/// Ensures that the reduced graph rooted at the given external module

Diff for: src/librustc_resolve/macros.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,19 @@ impl<'a> Resolver<'a> {
11061106
});
11071107
}
11081108

1109+
crate fn check_reserved_macro_name(&mut self, ident: Ident, res: Res) {
1110+
// Reserve some names that are not quite covered by the general check
1111+
// performed on `Resolver::builtin_attrs`.
1112+
if ident.name == sym::cfg || ident.name == sym::cfg_attr || ident.name == sym::derive {
1113+
let macro_kind = self.opt_get_macro(res).map(|ext| ext.macro_kind());
1114+
if macro_kind.is_some() && sub_namespace_match(macro_kind, Some(MacroKind::Attr)) {
1115+
self.session.span_err(
1116+
ident.span, &format!("name `{}` is reserved in attribute namespace", ident)
1117+
);
1118+
}
1119+
}
1120+
}
1121+
11091122
pub fn define_macro(&mut self,
11101123
item: &ast::Item,
11111124
expansion: Mark,
@@ -1117,13 +1130,14 @@ impl<'a> Resolver<'a> {
11171130
let ext = Lrc::new(macro_rules::compile(&self.session.parse_sess,
11181131
&self.session.features_untracked(),
11191132
item, self.session.edition()));
1133+
let macro_kind = ext.macro_kind();
1134+
let res = Res::Def(DefKind::Macro(macro_kind), def_id);
11201135
self.macro_map.insert(def_id, ext);
11211136

11221137
let def = match item.node { ast::ItemKind::MacroDef(ref def) => def, _ => unreachable!() };
11231138
if def.legacy {
11241139
let ident = ident.modern();
11251140
self.macro_names.insert(ident);
1126-
let res = Res::Def(DefKind::Macro(MacroKind::Bang), def_id);
11271141
let is_macro_export = attr::contains_name(&item.attrs, sym::macro_export);
11281142
let vis = if is_macro_export {
11291143
ty::Visibility::Public
@@ -1142,14 +1156,11 @@ impl<'a> Resolver<'a> {
11421156
self.define(module, ident, MacroNS,
11431157
(res, vis, item.span, expansion, IsMacroExport));
11441158
} else {
1145-
if !attr::contains_name(&item.attrs, sym::rustc_builtin_macro) {
1146-
self.check_reserved_macro_name(ident, MacroNS);
1147-
}
1159+
self.check_reserved_macro_name(ident, res);
11481160
self.unused_macros.insert(def_id);
11491161
}
11501162
} else {
11511163
let module = self.current_module;
1152-
let res = Res::Def(DefKind::Macro(MacroKind::Bang), def_id);
11531164
let vis = self.resolve_visibility(&item.vis);
11541165
if vis != ty::Visibility::Public {
11551166
self.unused_macros.insert(def_id);

Diff for: src/librustc_resolve/resolve_imports.rs

+5-15
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use rustc::{bug, span_bug};
2929
use syntax::ast::{self, Ident, Name, NodeId, CRATE_NODE_ID};
3030
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
3131
use syntax::ext::hygiene::Mark;
32-
use syntax::symbol::{kw, sym};
32+
use syntax::symbol::kw;
3333
use syntax::util::lev_distance::find_best_match_for_name;
3434
use syntax::{struct_span_err, unwrap_or};
3535
use syntax_pos::{MultiSpan, Span};
@@ -492,35 +492,25 @@ impl<'a> Resolver<'a> {
492492
})
493493
}
494494

495-
crate fn check_reserved_macro_name(&self, ident: Ident, ns: Namespace) {
496-
// Reserve some names that are not quite covered by the general check
497-
// performed on `Resolver::builtin_attrs`.
498-
if ns == MacroNS &&
499-
(ident.name == sym::cfg || ident.name == sym::cfg_attr ||
500-
ident.name == sym::derive) {
501-
self.session.span_err(ident.span,
502-
&format!("name `{}` is reserved in macro namespace", ident));
503-
}
504-
}
505-
506495
// Define the name or return the existing binding if there is a collision.
507496
pub fn try_define(&mut self,
508497
module: Module<'a>,
509498
ident: Ident,
510499
ns: Namespace,
511500
binding: &'a NameBinding<'a>)
512501
-> Result<(), &'a NameBinding<'a>> {
513-
self.check_reserved_macro_name(ident, ns);
502+
let res = binding.res();
503+
self.check_reserved_macro_name(ident, res);
514504
self.set_binding_parent_module(binding, module);
515505
self.update_resolution(module, ident, ns, |this, resolution| {
516506
if let Some(old_binding) = resolution.binding {
517-
if binding.res() == Res::Err {
507+
if res == Res::Err {
518508
// Do not override real bindings with `Res::Err`s from error recovery.
519509
return Ok(());
520510
}
521511
match (old_binding.is_glob_import(), binding.is_glob_import()) {
522512
(true, true) => {
523-
if binding.res() != old_binding.res() {
513+
if res != old_binding.res() {
524514
resolution.binding = Some(this.ambiguity(AmbiguityKind::GlobVsGlob,
525515
old_binding, binding));
526516
} else if !old_binding.vis.is_at_least(binding.vis, &*this) {

Diff for: src/test/ui/proc-macro/reserved-macro-names.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@ use proc_macro::*;
88

99
#[proc_macro_attribute]
1010
pub fn cfg(_: TokenStream, input: TokenStream) -> TokenStream {
11-
//~^ ERROR name `cfg` is reserved in macro namespace
11+
//~^ ERROR name `cfg` is reserved in attribute namespace
1212
input
1313
}
1414

1515
#[proc_macro_attribute]
1616
pub fn cfg_attr(_: TokenStream, input: TokenStream) -> TokenStream {
17-
//~^ ERROR name `cfg_attr` is reserved in macro namespace
17+
//~^ ERROR name `cfg_attr` is reserved in attribute namespace
1818
input
1919
}
2020

2121
#[proc_macro_attribute]
2222
pub fn derive(_: TokenStream, input: TokenStream) -> TokenStream {
23-
//~^ ERROR name `derive` is reserved in macro namespace
23+
//~^ ERROR name `derive` is reserved in attribute namespace
2424
input
2525
}

Diff for: src/test/ui/proc-macro/reserved-macro-names.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
error: name `cfg` is reserved in macro namespace
1+
error: name `cfg` is reserved in attribute namespace
22
--> $DIR/reserved-macro-names.rs:10:8
33
|
44
LL | pub fn cfg(_: TokenStream, input: TokenStream) -> TokenStream {
55
| ^^^
66

7-
error: name `cfg_attr` is reserved in macro namespace
7+
error: name `cfg_attr` is reserved in attribute namespace
88
--> $DIR/reserved-macro-names.rs:16:8
99
|
1010
LL | pub fn cfg_attr(_: TokenStream, input: TokenStream) -> TokenStream {
1111
| ^^^^^^^^
1212

13-
error: name `derive` is reserved in macro namespace
13+
error: name `derive` is reserved in attribute namespace
1414
--> $DIR/reserved-macro-names.rs:22:8
1515
|
1616
LL | pub fn derive(_: TokenStream, input: TokenStream) -> TokenStream {

0 commit comments

Comments
 (0)