Skip to content

Commit 3a44ee6

Browse files
committed
resolve: Move derive attribute detection closer to other macro ident resolution code
Refactor away `fn resolve_invoc_to_def`
1 parent 1558ae7 commit 3a44ee6

File tree

2 files changed

+54
-62
lines changed

2 files changed

+54
-62
lines changed

src/librustc_resolve/macros.rs

Lines changed: 53 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -321,10 +321,18 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
321321

322322
fn resolve_invoc(&mut self, invoc: &Invocation, scope: Mark, force: bool)
323323
-> Result<Option<Lrc<SyntaxExtension>>, Determinacy> {
324-
let def = match invoc.kind {
325-
InvocationKind::Attr { attr: None, .. } => return Ok(None),
326-
_ => self.resolve_invoc_to_def(invoc, scope, force)?,
324+
let (path, macro_kind, derives_in_scope) = match invoc.kind {
325+
InvocationKind::Attr { attr: None, .. } =>
326+
return Ok(None),
327+
InvocationKind::Attr { attr: Some(ref attr), ref traits, .. } =>
328+
(&attr.path, MacroKind::Attr, &traits[..]),
329+
InvocationKind::Bang { ref mac, .. } =>
330+
(&mac.node.path, MacroKind::Bang, &[][..]),
331+
InvocationKind::Derive { ref path, .. } =>
332+
(path, MacroKind::Derive, &[][..]),
327333
};
334+
let def = self.resolve_macro_to_def(scope, path, macro_kind, derives_in_scope, force)?;
335+
328336
if let Def::Macro(_, MacroKind::ProcMacroStub) = def {
329337
self.report_proc_macro_stub(invoc.span());
330338
return Err(Determinacy::Determined);
@@ -396,7 +404,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
396404

397405
fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
398406
-> Result<Lrc<SyntaxExtension>, Determinacy> {
399-
self.resolve_macro_to_def(scope, path, kind, force).and_then(|def| {
407+
self.resolve_macro_to_def(scope, path, kind, &[], force).and_then(|def| {
400408
if let Def::Macro(_, MacroKind::ProcMacroStub) = def {
401409
self.report_proc_macro_stub(path.span);
402410
return Err(Determinacy::Determined);
@@ -437,60 +445,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
437445
self.session.span_err(span, &format!("expected a macro, found {}", def.kind_name()));
438446
}
439447

440-
fn resolve_invoc_to_def(&mut self, invoc: &Invocation, scope: Mark, force: bool)
448+
fn resolve_macro_to_def(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind,
449+
derives_in_scope: &[ast::Path], force: bool)
441450
-> Result<Def, Determinacy> {
442-
let (attr, traits) = match invoc.kind {
443-
InvocationKind::Attr { ref attr, ref traits, .. } => (attr, traits),
444-
InvocationKind::Bang { ref mac, .. } => {
445-
return self.resolve_macro_to_def(scope, &mac.node.path, MacroKind::Bang, force);
446-
}
447-
InvocationKind::Derive { ref path, .. } => {
448-
return self.resolve_macro_to_def(scope, path, MacroKind::Derive, force);
449-
}
450-
};
451-
452-
let path = attr.as_ref().unwrap().path.clone();
453-
let def = self.resolve_macro_to_def(scope, &path, MacroKind::Attr, force);
454-
if let Ok(Def::NonMacroAttr(NonMacroAttrKind::Custom)) = def {} else {
455-
return def;
456-
}
457-
458-
// At this point we've found that the `attr` is determinately unresolved and thus can be
459-
// interpreted as a custom attribute. Normally custom attributes are feature gated, but
460-
// it may be a custom attribute whitelisted by a derive macro and they do not require
461-
// a feature gate.
462-
//
463-
// So here we look through all of the derive annotations in scope and try to resolve them.
464-
// If they themselves successfully resolve *and* one of the resolved derive macros
465-
// whitelists this attribute's name, then this is a registered attribute and we can convert
466-
// it from a "generic custom attrite" into a "known derive helper attribute".
467-
enum ConvertToDeriveHelper { Yes, No, DontKnow }
468-
let mut convert_to_derive_helper = ConvertToDeriveHelper::No;
469-
let attr_name = path.segments[0].ident.name;
470-
for path in traits {
471-
match self.resolve_macro(scope, path, MacroKind::Derive, force) {
472-
Ok(ext) => if let SyntaxExtension::ProcMacroDerive(_, ref inert_attrs, _) = *ext {
473-
if inert_attrs.contains(&attr_name) {
474-
convert_to_derive_helper = ConvertToDeriveHelper::Yes;
475-
break
476-
}
477-
},
478-
Err(Determinacy::Undetermined) =>
479-
convert_to_derive_helper = ConvertToDeriveHelper::DontKnow,
480-
Err(Determinacy::Determined) => {}
481-
}
482-
}
483-
484-
match convert_to_derive_helper {
485-
ConvertToDeriveHelper::Yes => Ok(Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper)),
486-
ConvertToDeriveHelper::No => def,
487-
ConvertToDeriveHelper::DontKnow => Err(Determinacy::determined(force)),
488-
}
489-
}
490-
491-
fn resolve_macro_to_def(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
492-
-> Result<Def, Determinacy> {
493-
let def = self.resolve_macro_to_def_inner(scope, path, kind, force);
451+
let def = self.resolve_macro_to_def_inner(scope, path, kind, derives_in_scope, force);
494452
if def != Err(Determinacy::Undetermined) {
495453
// Do not report duplicated errors on every undetermined resolution.
496454
path.segments.iter().find(|segment| segment.args.is_some()).map(|segment| {
@@ -514,9 +472,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
514472
def
515473
}
516474

517-
pub fn resolve_macro_to_def_inner(&mut self, scope: Mark, path: &ast::Path,
518-
kind: MacroKind, force: bool)
519-
-> Result<Def, Determinacy> {
475+
pub fn resolve_macro_to_def_inner(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind,
476+
derives_in_scope: &[ast::Path], force: bool)
477+
-> Result<Def, Determinacy> {
520478
let ast::Path { ref segments, span } = *path;
521479
let mut path: Vec<_> = segments.iter().map(|seg| seg.ident).collect();
522480
let invocation = self.invocations[&scope];
@@ -575,7 +533,41 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
575533
self.current_module.nearest_item_scope().legacy_macro_resolutions.borrow_mut()
576534
.push((scope, path[0], kind, result.ok()));
577535

578-
result
536+
if let Ok(Def::NonMacroAttr(NonMacroAttrKind::Custom)) = result {} else {
537+
return result;
538+
}
539+
540+
// At this point we've found that the `attr` is determinately unresolved and thus can be
541+
// interpreted as a custom attribute. Normally custom attributes are feature gated, but
542+
// it may be a custom attribute whitelisted by a derive macro and they do not require
543+
// a feature gate.
544+
//
545+
// So here we look through all of the derive annotations in scope and try to resolve them.
546+
// If they themselves successfully resolve *and* one of the resolved derive macros
547+
// whitelists this attribute's name, then this is a registered attribute and we can convert
548+
// it from a "generic custom attrite" into a "known derive helper attribute".
549+
assert!(kind == MacroKind::Attr);
550+
enum ConvertToDeriveHelper { Yes, No, DontKnow }
551+
let mut convert_to_derive_helper = ConvertToDeriveHelper::No;
552+
for derive in derives_in_scope {
553+
match self.resolve_macro(scope, derive, MacroKind::Derive, force) {
554+
Ok(ext) => if let SyntaxExtension::ProcMacroDerive(_, ref inert_attrs, _) = *ext {
555+
if inert_attrs.contains(&path[0].name) {
556+
convert_to_derive_helper = ConvertToDeriveHelper::Yes;
557+
break
558+
}
559+
},
560+
Err(Determinacy::Undetermined) =>
561+
convert_to_derive_helper = ConvertToDeriveHelper::DontKnow,
562+
Err(Determinacy::Determined) => {}
563+
}
564+
}
565+
566+
match convert_to_derive_helper {
567+
ConvertToDeriveHelper::Yes => Ok(Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper)),
568+
ConvertToDeriveHelper::No => result,
569+
ConvertToDeriveHelper::DontKnow => Err(Determinacy::determined(force)),
570+
}
579571
}
580572

581573
// Resolve the initial segment of a non-global macro path

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ fn macro_resolve(cx: &DocContext, path_str: &str) -> Option<Def> {
404404
let mut resolver = cx.resolver.borrow_mut();
405405
let mark = Mark::root();
406406
let res = resolver
407-
.resolve_macro_to_def_inner(mark, &path, MacroKind::Bang, false);
407+
.resolve_macro_to_def_inner(mark, &path, MacroKind::Bang, &[], false);
408408
if let Ok(def) = res {
409409
if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(def) {
410410
return Some(def);

0 commit comments

Comments
 (0)