about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authoryukang <moorekang@gmail.com>2022-09-06 14:16:54 +0800
committeryukang <moorekang@gmail.com>2022-09-06 14:16:54 +0800
commit00b10a5552c575e884a40de808a3cb64a647a442 (patch)
treed8c2f809353954988709497671ef8c5931f103e9 /compiler
parent676afc514944aa618977bacf8fe28cefc443a13a (diff)
downloadrust-00b10a5552c575e884a40de808a3cb64a647a442.tar.gz
rust-00b10a5552c575e884a40de808a3cb64a647a442.zip
get_attr should check that no duplicates are allowed
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs3
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs8
-rw-r--r--compiler/rustc_feature/src/lib.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs6
-rw-r--r--compiler/rustc_typeck/src/check/check.rs2
5 files changed, 18 insertions, 5 deletions
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index aabbe8ac276..b38684a63e4 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -386,7 +386,8 @@ pub fn from_fn_attrs<'ll, 'tcx>(
     ) {
         let span = cx
             .tcx
-            .get_attr(instance.def_id(), sym::target_feature)
+            .get_attrs(instance.def_id(), sym::target_feature)
+            .next()
             .map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span);
         let msg = format!(
             "the target features {} must all be either enabled or disabled together",
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index e359d50c4e9..38a02cb1d7c 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -823,6 +823,14 @@ pub fn is_builtin_only_local(name: Symbol) -> bool {
     BUILTIN_ATTRIBUTE_MAP.get(&name).map_or(false, |attr| attr.only_local)
 }
 
+pub fn is_valid_for_get_attr(name: Symbol) -> bool {
+    BUILTIN_ATTRIBUTE_MAP.get(&name).map_or(false, |attr| match attr.duplicates {
+        WarnFollowing | ErrorFollowing | ErrorPreceding | FutureWarnFollowing
+        | FutureWarnPreceding => true,
+        DuplicatesOk | WarnFollowingWordOnly => false,
+    })
+}
+
 pub static BUILTIN_ATTRIBUTE_MAP: LazyLock<FxHashMap<Symbol, &BuiltinAttribute>> =
     LazyLock::new(|| {
         let mut map = FxHashMap::default();
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index e44c9291f84..bdaa0ee88eb 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -151,7 +151,7 @@ pub use active::{Features, ACTIVE_FEATURES, INCOMPATIBLE_FEATURES};
 pub use builtin_attrs::AttributeDuplicates;
 pub use builtin_attrs::{
     deprecated_attributes, find_gated_cfg, is_builtin_attr_name, is_builtin_only_local,
-    AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute, GatedCfg,
-    BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
+    is_valid_for_get_attr, AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute,
+    GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
 };
 pub use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index ed04e766033..58b0657a5b0 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -2274,7 +2274,11 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     pub fn get_attr(self, did: DefId, attr: Symbol) -> Option<&'tcx ast::Attribute> {
-        self.get_attrs(did, attr).next()
+        if cfg!(debug_assertions) && !rustc_feature::is_valid_for_get_attr(attr) {
+            bug!("get_attr: unexpected called with DefId `{:?}`, attr `{:?}`", did, attr);
+        } else {
+            self.get_attrs(did, attr).next()
+        }
     }
 
     /// Determines whether an item is annotated with an attribute.
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 46135caa9bc..43893263be1 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -1459,7 +1459,7 @@ fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, vs: &'tcx [hir::Variant<'tcx>], def_id: L
     def.destructor(tcx); // force the destructor to be evaluated
 
     if vs.is_empty() {
-        if let Some(attr) = tcx.get_attr(def_id.to_def_id(), sym::repr) {
+        if let Some(attr) = tcx.get_attrs(def_id.to_def_id(), sym::repr).next() {
             struct_span_err!(
                 tcx.sess,
                 attr.span,