resolve: Introduce a separate NonMacroAttrKind for legacy derive helpers

This commit is contained in:
Vadim Petrochenkov 2020-11-19 01:45:10 +03:00
parent e7ee4d66ce
commit 69894ce9ac
3 changed files with 21 additions and 20 deletions

View File

@ -39,6 +39,9 @@ pub enum NonMacroAttrKind {
Tool,
/// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`).
DeriveHelper,
/// Single-segment custom attribute registered by a derive macro
/// but used before that derive macro was expanded (deprecated).
DeriveHelperCompat,
/// Single-segment custom attribute registered with `#[register_attr]`.
Registered,
}
@ -370,7 +373,9 @@ impl NonMacroAttrKind {
match self {
NonMacroAttrKind::Builtin => "built-in attribute",
NonMacroAttrKind::Tool => "tool attribute",
NonMacroAttrKind::DeriveHelper => "derive helper attribute",
NonMacroAttrKind::DeriveHelper | NonMacroAttrKind::DeriveHelperCompat => {
"derive helper attribute"
}
NonMacroAttrKind::Registered => "explicitly registered attribute",
}
}
@ -385,7 +390,9 @@ impl NonMacroAttrKind {
/// Users of some attributes cannot mark them as used, so they are considered always used.
pub fn is_used(self) -> bool {
match self {
NonMacroAttrKind::Tool | NonMacroAttrKind::DeriveHelper => true,
NonMacroAttrKind::Tool
| NonMacroAttrKind::DeriveHelper
| NonMacroAttrKind::DeriveHelperCompat => true,
NonMacroAttrKind::Builtin | NonMacroAttrKind::Registered => false,
}
}

View File

@ -609,7 +609,7 @@ impl<'a> Resolver<'a> {
}
}
Scope::DeriveHelpersCompat => {
let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
if filter_fn(res) {
for derive in parent_scope.derives {
let parent_scope = &ParentScope { derives: &[], ..*parent_scope };

View File

@ -568,10 +568,9 @@ impl<'a> Resolver<'a> {
struct Flags: u8 {
const MACRO_RULES = 1 << 0;
const MODULE = 1 << 1;
const DERIVE_HELPER_COMPAT = 1 << 2;
const MISC_SUGGEST_CRATE = 1 << 3;
const MISC_SUGGEST_SELF = 1 << 4;
const MISC_FROM_PRELUDE = 1 << 5;
const MISC_SUGGEST_CRATE = 1 << 2;
const MISC_SUGGEST_SELF = 1 << 3;
const MISC_FROM_PRELUDE = 1 << 4;
}
}
@ -646,14 +645,11 @@ impl<'a> Resolver<'a> {
) {
Ok((Some(ext), _)) => {
if ext.helper_attrs.contains(&ident.name) {
let binding = (
Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
ty::Visibility::Public,
result = ok(
Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat),
derive.span,
ExpnId::root(),
)
.to_name_binding(this.arenas);
result = Ok((binding, Flags::DERIVE_HELPER_COMPAT));
this.arenas,
);
break;
}
}
@ -799,17 +795,15 @@ impl<'a> Resolver<'a> {
let (res, innermost_res) = (binding.res(), innermost_binding.res());
if res != innermost_res {
let builtin = Res::NonMacroAttr(NonMacroAttrKind::Builtin);
let is_derive_helper_compat = |res, flags: Flags| {
res == Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper)
&& flags.contains(Flags::DERIVE_HELPER_COMPAT)
};
let derive_helper_compat =
Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
let ambiguity_error_kind = if is_import {
Some(AmbiguityKind::Import)
} else if innermost_res == builtin || res == builtin {
Some(AmbiguityKind::BuiltinAttr)
} else if is_derive_helper_compat(innermost_res, innermost_flags)
|| is_derive_helper_compat(res, flags)
} else if innermost_res == derive_helper_compat
|| res == derive_helper_compat
{
Some(AmbiguityKind::DeriveHelper)
} else if innermost_flags.contains(Flags::MACRO_RULES)