about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/deprecation.rs12
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/mod.rs28
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/stability.rs8
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/transparency.rs9
4 files changed, 14 insertions, 43 deletions
diff --git a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
index dcb12ac29cd..1b18ada70fc 100644
--- a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
@@ -2,7 +2,7 @@ use rustc_attr_data_structures::{AttributeKind, DeprecatedSince, Deprecation};
 use rustc_span::{Span, Symbol, sym};
 
 use super::util::parse_version;
-use super::{AttributeDuplicates, SingleAttributeParser};
+use super::{AttributeDuplicates, OnDuplicate, SingleAttributeParser};
 use crate::context::AcceptContext;
 use crate::parser::ArgParser;
 use crate::session_diagnostics;
@@ -44,15 +44,7 @@ fn get(
 impl SingleAttributeParser for DeprecationParser {
     const PATH: &'static [Symbol] = &[sym::deprecated];
     const ON_DUPLICATE_STRATEGY: AttributeDuplicates = AttributeDuplicates::ErrorFollowing;
-
-    fn on_duplicate(cx: &AcceptContext<'_>, used: Span, unused: Span) {
-        // FIXME(jdonszelmann): merge with errors from check_attrs.rs
-        cx.emit_err(session_diagnostics::UnusedMultiple {
-            this: used,
-            other: unused,
-            name: sym::deprecated,
-        });
-    }
+    const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
 
     fn convert(cx: &AcceptContext<'_>, args: &ArgParser<'_>) -> Option<AttributeKind> {
         let features = cx.features();
diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs
index 7aac4744504..852615b4fce 100644
--- a/compiler/rustc_attr_parsing/src/attributes/mod.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs
@@ -84,28 +84,8 @@ pub(crate) trait AttributeParser: Default + 'static {
 pub(crate) trait SingleAttributeParser: 'static {
     const PATH: &'static [Symbol];
 
-<<<<<<< Conflict 1 of 1
-+++++++ Contents of side #1
-    /// Called when a duplicate attribute is found.
-%%%%%%% Changes from base to side #2
-+    const ON_DUPLICATE_STRATEGY: AttributeDuplicates;
-+
-     /// Caled when a duplicate attribute is found.
->>>>>>> Conflict 1 of 1 ends
-    ///
-    /// - `unused` is the span of the attribute that was unused or bad because of some
-    ///   duplicate reason (see [`AttributeDuplicates`])
-    /// - `used` is the span of the attribute that was used in favor of the unused attribute
-    // FIXME(jdonszelmann): default error
-    fn on_duplicate(cx: &AcceptContext<'_>, used: Span, unused: Span) {
-        cx.emit_err(UnusedMultiple {
-            this: used,
-            other: unused,
-            name: Symbol::intern(
-                &Self::PATH.into_iter().map(|i| i.to_string()).collect::<Vec<_>>().join(".."),
-            ),
-        });
-    }
+    const ON_DUPLICATE_STRATEGY: AttributeDuplicates;
+    const ON_DUPLICATE: OnDuplicate;
 
     /// Converts a single syntactical attribute to a single semantic attribute, or [`AttributeKind`]
     fn convert(cx: &AcceptContext<'_>, args: &ArgParser<'_>) -> Option<AttributeKind>;
@@ -126,7 +106,7 @@ impl<T: SingleAttributeParser> AttributeParser for Single<T> {
                 // keep the first and error
                 AttributeDuplicates::ErrorFollowing => {
                     if let Some((_, unused)) = group.1 {
-                        T::on_duplicate(cx, cx.attr_span, unused);
+                        T::ON_DUPLICATE.exec::<T>(cx, cx.attr_span, unused);
                         return;
                     }
                 }
@@ -134,7 +114,7 @@ impl<T: SingleAttributeParser> AttributeParser for Single<T> {
                 // then replace
                 AttributeDuplicates::FutureWarnPreceding => {
                     if let Some((_, used)) = group.1 {
-                        T::on_duplicate(cx, used, cx.attr_span);
+                        T::ON_DUPLICATE.exec::<T>(cx, used, cx.attr_span);
                     }
                 }
             }
diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs
index 407fd5e1b8b..e8653453b39 100644
--- a/compiler/rustc_attr_parsing/src/attributes/stability.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs
@@ -8,7 +8,9 @@ use rustc_errors::ErrorGuaranteed;
 use rustc_span::{Span, Symbol, sym};
 
 use super::util::parse_version;
-use super::{AcceptMapping, AttributeDuplicates, AttributeParser, SingleAttributeParser};
+use super::{
+    AcceptMapping, AttributeDuplicates, AttributeParser, OnDuplicate, SingleAttributeParser,
+};
 use crate::context::{AcceptContext, FinalizeContext};
 use crate::parser::{ArgParser, MetaItemParser};
 use crate::session_diagnostics::{self, UnsupportedLiteralReason};
@@ -119,9 +121,7 @@ pub(crate) struct ConstStabilityIndirectParser;
 impl SingleAttributeParser for ConstStabilityIndirectParser {
     const PATH: &'static [Symbol] = &[sym::rustc_const_stable_indirect];
     const ON_DUPLICATE_STRATEGY: AttributeDuplicates = AttributeDuplicates::ErrorFollowing;
-
-    // ignore
-    fn on_duplicate(_cx: &AcceptContext<'_>, _used: Span, _unused: Span) {}
+    const ON_DUPLICATE: OnDuplicate = OnDuplicate::Ignore;
 
     fn convert(_cx: &AcceptContext<'_>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
         Some(AttributeKind::ConstStabilityIndirect)
diff --git a/compiler/rustc_attr_parsing/src/attributes/transparency.rs b/compiler/rustc_attr_parsing/src/attributes/transparency.rs
index 0ab4cb99a62..22d2806e41e 100644
--- a/compiler/rustc_attr_parsing/src/attributes/transparency.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/transparency.rs
@@ -1,8 +1,8 @@
 use rustc_attr_data_structures::AttributeKind;
 use rustc_span::hygiene::Transparency;
-use rustc_span::{Span, Symbol, sym};
+use rustc_span::{Symbol, sym};
 
-use super::{AcceptContext, AttributeDuplicates, SingleAttributeParser};
+use super::{AcceptContext, AttributeDuplicates, OnDuplicate, SingleAttributeParser};
 use crate::parser::ArgParser;
 
 pub(crate) struct TransparencyParser;
@@ -13,10 +13,9 @@ pub(crate) struct TransparencyParser;
 impl SingleAttributeParser for TransparencyParser {
     const PATH: &[Symbol] = &[sym::rustc_macro_transparency];
     const ON_DUPLICATE_STRATEGY: AttributeDuplicates = AttributeDuplicates::ErrorFollowing;
-
-    fn on_duplicate(cx: &crate::context::AcceptContext<'_>, used: Span, unused: Span) {
+    const ON_DUPLICATE: OnDuplicate = OnDuplicate::Custom(|cx, used, unused| {
         cx.dcx().span_err(vec![used, unused], "multiple macro transparency attributes");
-    }
+    });
 
     fn convert(cx: &AcceptContext<'_>, args: &ArgParser<'_>) -> Option<AttributeKind> {
         match args.name_value().and_then(|nv| nv.value_as_str()) {