Skip to content

Commit 23e9a1d

Browse files
committed
resolve: Consolidate error reporting for resolved macros in fn resolve_macro_to_def
1 parent 3a44ee6 commit 23e9a1d

18 files changed

+173
-199
lines changed

src/librustc_resolve/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1399,7 +1399,7 @@ pub struct Resolver<'a, 'b: 'a> {
13991399
proc_mac_errors: Vec<macros::ProcMacError>,
14001400
/// crate-local macro expanded `macro_export` referred to by a module-relative path
14011401
macro_expanded_macro_export_errors: BTreeSet<(Span, Span)>,
1402-
1402+
/// macro-expanded `macro_rules` shadowing existing macros
14031403
disallowed_shadowing: Vec<&'a LegacyBinding<'a>>,
14041404

14051405
arenas: &'a ResolverArenas<'a>,

src/librustc_resolve/macros.rs

Lines changed: 94 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,9 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
319319
None
320320
}
321321

322-
fn resolve_invoc(&mut self, invoc: &Invocation, scope: Mark, force: bool)
323-
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
324-
let (path, macro_kind, derives_in_scope) = match invoc.kind {
322+
fn resolve_macro_invocation(&mut self, invoc: &Invocation, scope: Mark, force: bool)
323+
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
324+
let (path, kind, derives_in_scope) = match invoc.kind {
325325
InvocationKind::Attr { attr: None, .. } =>
326326
return Ok(None),
327327
InvocationKind::Attr { attr: Some(ref attr), ref traits, .. } =>
@@ -331,90 +331,26 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
331331
InvocationKind::Derive { ref path, .. } =>
332332
(path, MacroKind::Derive, &[][..]),
333333
};
334-
let def = self.resolve_macro_to_def(scope, path, macro_kind, derives_in_scope, force)?;
335-
336-
if let Def::Macro(_, MacroKind::ProcMacroStub) = def {
337-
self.report_proc_macro_stub(invoc.span());
338-
return Err(Determinacy::Determined);
339-
} else if let Def::NonMacroAttr(attr_kind) = def {
340-
// Note that not only attributes, but anything in macro namespace can result in a
341-
// `Def::NonMacroAttr` definition (e.g. `inline!()`), so we must report the error
342-
// below for these cases.
343-
let is_attr_invoc =
344-
if let InvocationKind::Attr { .. } = invoc.kind { true } else { false };
345-
let path = invoc.path().expect("no path for non-macro attr");
346-
match attr_kind {
347-
NonMacroAttrKind::Tool | NonMacroAttrKind::DeriveHelper |
348-
NonMacroAttrKind::Custom if is_attr_invoc => {
349-
let features = self.session.features_untracked();
350-
if attr_kind == NonMacroAttrKind::Tool &&
351-
!features.tool_attributes {
352-
feature_err(&self.session.parse_sess, "tool_attributes",
353-
invoc.span(), GateIssue::Language,
354-
"tool attributes are unstable").emit();
355-
}
356-
if attr_kind == NonMacroAttrKind::Custom {
357-
assert!(path.segments.len() == 1);
358-
let name = path.segments[0].ident.name.as_str();
359-
if name.starts_with("rustc_") {
360-
if !features.rustc_attrs {
361-
let msg = "unless otherwise specified, attributes with the prefix \
362-
`rustc_` are reserved for internal compiler diagnostics";
363-
feature_err(&self.session.parse_sess, "rustc_attrs", invoc.span(),
364-
GateIssue::Language, &msg).emit();
365-
}
366-
} else if name.starts_with("derive_") {
367-
if !features.custom_derive {
368-
feature_err(&self.session.parse_sess, "custom_derive", invoc.span(),
369-
GateIssue::Language, EXPLAIN_DERIVE_UNDERSCORE).emit();
370-
}
371-
} else if !features.custom_attribute {
372-
let msg = format!("The attribute `{}` is currently unknown to the \
373-
compiler and may have meaning added to it in the \
374-
future", path);
375-
feature_err(&self.session.parse_sess, "custom_attribute", invoc.span(),
376-
GateIssue::Language, &msg).emit();
377-
}
378-
}
379334

380-
return Ok(Some(Lrc::new(SyntaxExtension::NonMacroAttr {
381-
mark_used: attr_kind == NonMacroAttrKind::Tool,
382-
})));
383-
}
384-
_ => {
385-
self.report_non_macro_attr(path.span, def);
386-
return Err(Determinacy::Determined);
387-
}
388-
}
335+
let (def, ext) = self.resolve_macro_to_def(path, kind, scope, derives_in_scope, force)?;
336+
337+
if let Def::Macro(def_id, _) = def {
338+
self.macro_defs.insert(invoc.expansion_data.mark, def_id);
339+
let normal_module_def_id =
340+
self.macro_def_scope(invoc.expansion_data.mark).normal_ancestor_id;
341+
self.definitions.add_parent_module_of_macro_def(invoc.expansion_data.mark,
342+
normal_module_def_id);
343+
invoc.expansion_data.mark.set_default_transparency(ext.default_transparency());
344+
invoc.expansion_data.mark.set_is_builtin(def_id.krate == BUILTIN_MACROS_CRATE);
389345
}
390-
let def_id = def.def_id();
391-
392-
self.macro_defs.insert(invoc.expansion_data.mark, def_id);
393-
let normal_module_def_id =
394-
self.macro_def_scope(invoc.expansion_data.mark).normal_ancestor_id;
395-
self.definitions.add_parent_module_of_macro_def(invoc.expansion_data.mark,
396-
normal_module_def_id);
397-
398-
self.unused_macros.remove(&def_id);
399-
let ext = self.get_macro(def);
400-
invoc.expansion_data.mark.set_default_transparency(ext.default_transparency());
401-
invoc.expansion_data.mark.set_is_builtin(def_id.krate == BUILTIN_MACROS_CRATE);
346+
402347
Ok(Some(ext))
403348
}
404349

405-
fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
406-
-> Result<Lrc<SyntaxExtension>, Determinacy> {
407-
self.resolve_macro_to_def(scope, path, kind, &[], force).and_then(|def| {
408-
if let Def::Macro(_, MacroKind::ProcMacroStub) = def {
409-
self.report_proc_macro_stub(path.span);
410-
return Err(Determinacy::Determined);
411-
} else if let Def::NonMacroAttr(..) = def {
412-
self.report_non_macro_attr(path.span, def);
413-
return Err(Determinacy::Determined);
414-
}
415-
self.unused_macros.remove(&def.def_id());
416-
Ok(self.get_macro(def))
417-
})
350+
fn resolve_macro_path(&mut self, path: &ast::Path, kind: MacroKind, scope: Mark,
351+
derives_in_scope: &[ast::Path], force: bool)
352+
-> Result<Lrc<SyntaxExtension>, Determinacy> {
353+
Ok(self.resolve_macro_to_def(path, kind, scope, derives_in_scope, force)?.1)
418354
}
419355

420356
fn check_unused_macros(&self) {
@@ -436,43 +372,89 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
436372
}
437373

438374
impl<'a, 'cl> Resolver<'a, 'cl> {
439-
fn report_proc_macro_stub(&self, span: Span) {
440-
self.session.span_err(span,
441-
"can't use a procedural macro from the same crate that defines it");
442-
}
443-
444-
fn report_non_macro_attr(&self, span: Span, def: Def) {
445-
self.session.span_err(span, &format!("expected a macro, found {}", def.kind_name()));
446-
}
447-
448-
fn resolve_macro_to_def(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind,
375+
fn resolve_macro_to_def(&mut self, path: &ast::Path, kind: MacroKind, scope: Mark,
449376
derives_in_scope: &[ast::Path], force: bool)
450-
-> Result<Def, Determinacy> {
451-
let def = self.resolve_macro_to_def_inner(scope, path, kind, derives_in_scope, force);
377+
-> Result<(Def, Lrc<SyntaxExtension>), Determinacy> {
378+
let def = self.resolve_macro_to_def_inner(path, kind, scope, derives_in_scope, force);
379+
380+
// Report errors and enforce feature gates for the resolved macro.
452381
if def != Err(Determinacy::Undetermined) {
453382
// Do not report duplicated errors on every undetermined resolution.
454-
path.segments.iter().find(|segment| segment.args.is_some()).map(|segment| {
455-
self.session.span_err(segment.args.as_ref().unwrap().span(),
456-
"generic arguments in macro path");
457-
});
383+
for segment in &path.segments {
384+
if let Some(args) = &segment.args {
385+
self.session.span_err(args.span(), "generic arguments in macro path");
386+
}
387+
}
458388
}
459-
if kind != MacroKind::Bang && path.segments.len() > 1 &&
460-
def != Ok(Def::NonMacroAttr(NonMacroAttrKind::Tool)) {
461-
if !self.session.features_untracked().proc_macro_path_invoc {
462-
emit_feature_err(
463-
&self.session.parse_sess,
464-
"proc_macro_path_invoc",
465-
path.span,
466-
GateIssue::Language,
467-
"paths of length greater than one in macro invocations are \
468-
currently unstable",
469-
);
389+
390+
let def = def?;
391+
392+
if path.segments.len() > 1 {
393+
if kind != MacroKind::Bang {
394+
if def != Def::NonMacroAttr(NonMacroAttrKind::Tool) &&
395+
!self.session.features_untracked().proc_macro_path_invoc {
396+
let msg = format!("non-ident {} paths are unstable", kind.descr());
397+
emit_feature_err(&self.session.parse_sess, "proc_macro_path_invoc",
398+
path.span, GateIssue::Language, &msg);
399+
}
470400
}
471401
}
472-
def
402+
403+
match def {
404+
Def::Macro(def_id, macro_kind) => {
405+
self.unused_macros.remove(&def_id);
406+
if macro_kind == MacroKind::ProcMacroStub {
407+
let msg = "can't use a procedural macro from the same crate that defines it";
408+
self.session.span_err(path.span, msg);
409+
return Err(Determinacy::Determined);
410+
}
411+
}
412+
Def::NonMacroAttr(attr_kind) => {
413+
if kind == MacroKind::Attr {
414+
let features = self.session.features_untracked();
415+
if attr_kind == NonMacroAttrKind::Tool && !features.tool_attributes {
416+
feature_err(&self.session.parse_sess, "tool_attributes", path.span,
417+
GateIssue::Language, "tool attributes are unstable").emit();
418+
}
419+
if attr_kind == NonMacroAttrKind::Custom {
420+
assert!(path.segments.len() == 1);
421+
let name = path.segments[0].ident.name.as_str();
422+
if name.starts_with("rustc_") {
423+
if !features.rustc_attrs {
424+
let msg = "unless otherwise specified, attributes with the prefix \
425+
`rustc_` are reserved for internal compiler diagnostics";
426+
feature_err(&self.session.parse_sess, "rustc_attrs", path.span,
427+
GateIssue::Language, &msg).emit();
428+
}
429+
} else if name.starts_with("derive_") {
430+
if !features.custom_derive {
431+
feature_err(&self.session.parse_sess, "custom_derive", path.span,
432+
GateIssue::Language, EXPLAIN_DERIVE_UNDERSCORE).emit();
433+
}
434+
} else if !features.custom_attribute {
435+
let msg = format!("The attribute `{}` is currently unknown to the \
436+
compiler and may have meaning added to it in the \
437+
future", path);
438+
feature_err(&self.session.parse_sess, "custom_attribute", path.span,
439+
GateIssue::Language, &msg).emit();
440+
}
441+
}
442+
} else {
443+
// Not only attributes, but anything in macro namespace can result in
444+
// `Def::NonMacroAttr` definition (e.g. `inline!()`), so we must report
445+
// an error for those cases.
446+
let msg = format!("expected a macro, found {}", def.kind_name());
447+
self.session.span_err(path.span, &msg);
448+
return Err(Determinacy::Determined);
449+
}
450+
}
451+
_ => panic!("expected `Def::Macro` or `Def::NonMacroAttr`"),
452+
}
453+
454+
Ok((def, self.get_macro(def)))
473455
}
474456

475-
pub fn resolve_macro_to_def_inner(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind,
457+
pub fn resolve_macro_to_def_inner(&mut self, path: &ast::Path, kind: MacroKind, scope: Mark,
476458
derives_in_scope: &[ast::Path], force: bool)
477459
-> Result<Def, Determinacy> {
478460
let ast::Path { ref segments, span } = *path;
@@ -550,7 +532,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
550532
enum ConvertToDeriveHelper { Yes, No, DontKnow }
551533
let mut convert_to_derive_helper = ConvertToDeriveHelper::No;
552534
for derive in derives_in_scope {
553-
match self.resolve_macro(scope, derive, MacroKind::Derive, force) {
535+
match self.resolve_macro_path(derive, MacroKind::Derive, scope, &[], force) {
554536
Ok(ext) => if let SyntaxExtension::ProcMacroDerive(_, ref inert_attrs, _) = *ext {
555537
if inert_attrs.contains(&path[0].name) {
556538
convert_to_derive_helper = ConvertToDeriveHelper::Yes;

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -403,9 +403,7 @@ fn macro_resolve(cx: &DocContext, path_str: &str) -> Option<Def> {
403403
let path = ast::Path { segments: vec![segment], span: DUMMY_SP };
404404
let mut resolver = cx.resolver.borrow_mut();
405405
let mark = Mark::root();
406-
let res = resolver
407-
.resolve_macro_to_def_inner(mark, &path, MacroKind::Bang, &[], false);
408-
if let Ok(def) = res {
406+
if let Ok(def) = resolver.resolve_macro_to_def_inner(&path, MacroKind::Bang, mark, &[], false) {
409407
if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(def) {
410408
return Some(def);
411409
}

src/libsyntax/ext/base.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -727,10 +727,12 @@ pub trait Resolver {
727727
fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<Attribute>, allow_derive: bool)
728728
-> Option<Attribute>;
729729

730-
fn resolve_invoc(&mut self, invoc: &Invocation, scope: Mark, force: bool)
731-
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy>;
732-
fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
733-
-> Result<Lrc<SyntaxExtension>, Determinacy>;
730+
fn resolve_macro_invocation(&mut self, invoc: &Invocation, scope: Mark, force: bool)
731+
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy>;
732+
fn resolve_macro_path(&mut self, path: &ast::Path, kind: MacroKind, scope: Mark,
733+
derives_in_scope: &[ast::Path], force: bool)
734+
-> Result<Lrc<SyntaxExtension>, Determinacy>;
735+
734736
fn check_unused_macros(&self);
735737
}
736738

@@ -761,12 +763,13 @@ impl Resolver for DummyResolver {
761763
fn resolve_imports(&mut self) {}
762764
fn find_legacy_attr_invoc(&mut self, _attrs: &mut Vec<Attribute>, _allow_derive: bool)
763765
-> Option<Attribute> { None }
764-
fn resolve_invoc(&mut self, _invoc: &Invocation, _scope: Mark, _force: bool)
765-
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
766+
fn resolve_macro_invocation(&mut self, _invoc: &Invocation, _scope: Mark, _force: bool)
767+
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
766768
Err(Determinacy::Determined)
767769
}
768-
fn resolve_macro(&mut self, _scope: Mark, _path: &ast::Path, _kind: MacroKind,
769-
_force: bool) -> Result<Lrc<SyntaxExtension>, Determinacy> {
770+
fn resolve_macro_path(&mut self, _path: &ast::Path, _kind: MacroKind, _scope: Mark,
771+
_derives_in_scope: &[ast::Path], _force: bool)
772+
-> Result<Lrc<SyntaxExtension>, Determinacy> {
770773
Err(Determinacy::Determined)
771774
}
772775
fn check_unused_macros(&self) {}

src/libsyntax/ext/expand.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -243,15 +243,6 @@ impl Invocation {
243243
InvocationKind::Derive { ref path, .. } => path.span,
244244
}
245245
}
246-
247-
pub fn path(&self) -> Option<&Path> {
248-
match self.kind {
249-
InvocationKind::Bang { ref mac, .. } => Some(&mac.node.path),
250-
InvocationKind::Attr { attr: Some(ref attr), .. } => Some(&attr.path),
251-
InvocationKind::Attr { attr: None, .. } => None,
252-
InvocationKind::Derive { ref path, .. } => Some(path),
253-
}
254-
}
255246
}
256247

257248
pub struct MacroExpander<'a, 'b:'a> {
@@ -343,7 +334,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
343334

344335
let scope =
345336
if self.monotonic { invoc.expansion_data.mark } else { orig_expansion_data.mark };
346-
let ext = match self.cx.resolver.resolve_invoc(&invoc, scope, force) {
337+
let ext = match self.cx.resolver.resolve_macro_invocation(&invoc, scope, force) {
347338
Ok(ext) => Some(ext),
348339
Err(Determinacy::Determined) => None,
349340
Err(Determinacy::Undetermined) => {
@@ -393,8 +384,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
393384
for path in &traits {
394385
let mark = Mark::fresh(self.cx.current_expansion.mark);
395386
derives.push(mark);
396-
let item = match self.cx.resolver.resolve_macro(
397-
Mark::root(), path, MacroKind::Derive, false) {
387+
let item = match self.cx.resolver.resolve_macro_path(
388+
path, MacroKind::Derive, Mark::root(), &[], false) {
398389
Ok(ext) => match *ext {
399390
BuiltinDerive(..) => item_with_markers.clone(),
400391
_ => item.clone(),

src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ extern crate proc_macro_gates as foo;
2222

2323
use foo::*;
2424

25-
#[foo::a] //~ ERROR: paths of length greater than one
25+
#[foo::a] //~ ERROR: non-ident attribute macro paths are unstable
2626
fn _test() {}
2727

2828
fn _test_inner() {

0 commit comments

Comments
 (0)