Skip to content

Commit 65c8c97

Browse files
committed
resolve: Skip bang macros when resolving potentially built-in attributes
1 parent d0aaf89 commit 65c8c97

File tree

2 files changed

+29
-32
lines changed

2 files changed

+29
-32
lines changed

src/librustc_resolve/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1270,6 +1270,7 @@ impl<'a> NameBinding<'a> {
12701270
fn macro_kind(&self) -> Option<MacroKind> {
12711271
match self.def_ignoring_ambiguity() {
12721272
Def::Macro(_, kind) => Some(kind),
1273+
Def::NonMacroAttr(..) => Some(MacroKind::Attr),
12731274
_ => None,
12741275
}
12751276
}
@@ -3596,8 +3597,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
35963597
self.resolve_ident_in_module(module, ident, ns, record_used, path_span)
35973598
} else if opt_ns == Some(MacroNS) {
35983599
assert!(ns == TypeNS);
3599-
self.resolve_lexical_macro_path_segment(ident, ns, parent_expansion, record_used,
3600-
record_used, false, path_span)
3600+
self.resolve_lexical_macro_path_segment(ident, ns, None, parent_expansion,
3601+
record_used, record_used, path_span)
36013602
.map(|(binding, _)| binding)
36023603
} else {
36033604
let record_used_id =

src/librustc_resolve/macros.rs

+26-30
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ pub struct ProcMacError {
109109
warn_msg: &'static str,
110110
}
111111

112+
// For compatibility bang macros are skipped when resolving potentially built-in attributes.
113+
fn macro_kind_mismatch(name: Name, requirement: Option<MacroKind>, candidate: Option<MacroKind>)
114+
-> bool {
115+
requirement == Some(MacroKind::Attr) && candidate == Some(MacroKind::Bang) &&
116+
(name == "test" || name == "bench" || is_builtin_attr_name(name))
117+
}
118+
112119
impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
113120
fn next_node_id(&mut self) -> ast::NodeId {
114121
self.session.next_node_id()
@@ -479,13 +486,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
479486
}
480487

481488
let legacy_resolution = self.resolve_legacy_scope(
482-
path[0], parent_expansion, parent_legacy_scope, false, kind == MacroKind::Attr
489+
path[0], Some(kind), parent_expansion, parent_legacy_scope, false
483490
);
484491
let result = if let Some(legacy_binding) = legacy_resolution {
485492
Ok(legacy_binding.def())
486493
} else {
487-
match self.resolve_lexical_macro_path_segment(path[0], MacroNS, parent_expansion, false,
488-
force, kind == MacroKind::Attr, span) {
494+
match self.resolve_lexical_macro_path_segment(path[0], MacroNS, Some(kind),
495+
parent_expansion, false, force, span) {
489496
Ok((binding, _)) => Ok(binding.def_ignoring_ambiguity()),
490497
Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined),
491498
Err(Determinacy::Determined) => {
@@ -543,10 +550,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
543550
&mut self,
544551
mut ident: Ident,
545552
ns: Namespace,
553+
kind: Option<MacroKind>,
546554
parent_expansion: Mark,
547555
record_used: bool,
548556
force: bool,
549-
is_attr: bool,
550557
path_span: Span,
551558
) -> Result<(&'a NameBinding<'a>, FromPrelude), Determinacy> {
552559
// General principles:
@@ -622,19 +629,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
622629
}
623630
WhereToResolve::MacroUsePrelude => {
624631
match self.macro_use_prelude.get(&ident.name).cloned() {
625-
Some(binding) => {
626-
let mut result = Ok((binding, FromPrelude(true)));
627-
// FIXME: Keep some built-in macros working even if they are
628-
// shadowed by non-attribute macros imported with `macro_use`.
629-
// We need to come up with some more principled approach instead.
630-
if is_attr && (ident.name == "test" || ident.name == "bench") {
631-
if let Def::Macro(_, MacroKind::Bang) =
632-
binding.def_ignoring_ambiguity() {
633-
result = Err(Determinacy::Determined);
634-
}
635-
}
636-
result
637-
}
632+
Some(binding) => Ok((binding, FromPrelude(true))),
638633
None => Err(Determinacy::Determined),
639634
}
640635
}
@@ -648,7 +643,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
648643
// FIXME: Only built-in attributes are not considered as candidates for
649644
// non-attributes to fight off regressions on stable channel (#53205).
650645
// We need to come up with some more principled approach instead.
651-
if is_attr && is_builtin_attr_name(ident.name) {
646+
if kind == Some(MacroKind::Attr) && is_builtin_attr_name(ident.name) {
652647
let binding = (Def::NonMacroAttr(NonMacroAttrKind::Builtin),
653648
ty::Visibility::Public, ident.span, Mark::root())
654649
.to_name_binding(self.arenas);
@@ -748,6 +743,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
748743

749744
match result {
750745
Ok(result) => {
746+
if macro_kind_mismatch(ident.name, kind, result.0.macro_kind()) {
747+
continue_search!();
748+
}
749+
751750
if !record_used {
752751
return Ok(result);
753752
}
@@ -784,9 +783,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
784783
}
785784

786785
let determinacy = Determinacy::determined(force);
787-
if determinacy == Determinacy::Determined && is_attr {
786+
if determinacy == Determinacy::Determined && kind == Some(MacroKind::Attr) {
788787
// For single-segment attributes interpret determinate "no resolution" as a custom
789-
// attribute. (Lexical resolution implies the first segment and is_attr should imply
788+
// attribute. (Lexical resolution implies the first segment and attr kind should imply
790789
// the last segment, so we are certainly working with a single-segment attribute here.)
791790
assert!(ns == MacroNS);
792791
let binding = (Def::NonMacroAttr(NonMacroAttrKind::Custom),
@@ -800,15 +799,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
800799

801800
fn resolve_legacy_scope(&mut self,
802801
ident: Ident,
802+
kind: Option<MacroKind>,
803803
parent_expansion: Mark,
804804
parent_legacy_scope: LegacyScope<'a>,
805-
record_used: bool,
806-
is_attr: bool)
805+
record_used: bool)
807806
-> Option<&'a NameBinding<'a>> {
808-
if is_attr && (ident.name == "test" || ident.name == "bench") {
809-
// FIXME: Keep some built-in macros working even if they are
810-
// shadowed by user-defined `macro_rules`.
811-
// We need to come up with some more principled approach instead.
807+
if macro_kind_mismatch(ident.name, kind, Some(MacroKind::Bang)) {
812808
return None;
813809
}
814810

@@ -897,10 +893,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
897893
in module.legacy_macro_resolutions.borrow().iter() {
898894
let span = ident.span;
899895
let legacy_resolution = self.resolve_legacy_scope(
900-
ident, parent_expansion, parent_legacy_scope, true, kind == MacroKind::Attr
896+
ident, Some(kind), parent_expansion, parent_legacy_scope, true
901897
);
902898
let resolution = self.resolve_lexical_macro_path_segment(
903-
ident, MacroNS, parent_expansion, true, true, kind == MacroKind::Attr, span
899+
ident, MacroNS, Some(kind), parent_expansion, true, true, span
904900
);
905901

906902
let check_consistency = |this: &Self, new_def: Def| {
@@ -960,10 +956,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
960956
for &(ident, parent_expansion, parent_legacy_scope)
961957
in module.builtin_attrs.borrow().iter() {
962958
let resolve_legacy = |this: &mut Self| this.resolve_legacy_scope(
963-
ident, parent_expansion, parent_legacy_scope, true, true
959+
ident, Some(MacroKind::Attr), parent_expansion, parent_legacy_scope, true
964960
);
965961
let resolve_modern = |this: &mut Self| this.resolve_lexical_macro_path_segment(
966-
ident, MacroNS, parent_expansion, true, true, true, ident.span
962+
ident, MacroNS, Some(MacroKind::Attr), parent_expansion, true, true, ident.span
967963
).map(|(binding, _)| binding).ok();
968964

969965
if let Some(binding) = resolve_legacy(self).or_else(|| resolve_modern(self)) {

0 commit comments

Comments
 (0)