Skip to content

Commit 7d45a75

Browse files
committed
get_attr should check that no duplicates are allowed
1 parent 1603a70 commit 7d45a75

File tree

7 files changed

+38
-5
lines changed

7 files changed

+38
-5
lines changed

compiler/rustc_codegen_llvm/src/attributes.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,8 @@ pub fn from_fn_attrs<'ll, 'tcx>(
386386
) {
387387
let span = cx
388388
.tcx
389-
.get_attr(instance.def_id(), sym::target_feature)
389+
.get_attrs(instance.def_id(), sym::target_feature)
390+
.next()
390391
.map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span);
391392
let msg = format!(
392393
"the target features {} must all be either enabled or disabled together",

compiler/rustc_feature/src/builtin_attrs.rs

+8
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,14 @@ pub fn is_builtin_only_local(name: Symbol) -> bool {
825825
BUILTIN_ATTRIBUTE_MAP.get(&name).map_or(false, |attr| attr.only_local)
826826
}
827827

828+
pub fn is_valid_for_get_attr(name: Symbol) -> bool {
829+
BUILTIN_ATTRIBUTE_MAP.get(&name).map_or(false, |attr| match attr.duplicates {
830+
WarnFollowing | ErrorFollowing | ErrorPreceding | FutureWarnFollowing
831+
| FutureWarnPreceding => true,
832+
DuplicatesOk | WarnFollowingWordOnly => false,
833+
})
834+
}
835+
828836
pub static BUILTIN_ATTRIBUTE_MAP: LazyLock<FxHashMap<Symbol, &BuiltinAttribute>> =
829837
LazyLock::new(|| {
830838
let mut map = FxHashMap::default();

compiler/rustc_feature/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ pub use active::{Features, ACTIVE_FEATURES, INCOMPATIBLE_FEATURES};
149149
pub use builtin_attrs::AttributeDuplicates;
150150
pub use builtin_attrs::{
151151
deprecated_attributes, find_gated_cfg, is_builtin_attr_name, is_builtin_only_local,
152-
AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute, GatedCfg,
153-
BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
152+
is_valid_for_get_attr, AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute,
153+
GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
154154
};
155155
pub use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};

compiler/rustc_middle/src/ty/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -2280,7 +2280,11 @@ impl<'tcx> TyCtxt<'tcx> {
22802280
}
22812281

22822282
pub fn get_attr(self, did: DefId, attr: Symbol) -> Option<&'tcx ast::Attribute> {
2283-
self.get_attrs(did, attr).next()
2283+
if cfg!(debug_assertions) && !rustc_feature::is_valid_for_get_attr(attr) {
2284+
bug!("get_attr: unexpected called with DefId `{:?}`, attr `{:?}`", did, attr);
2285+
} else {
2286+
self.get_attrs(did, attr).next()
2287+
}
22842288
}
22852289

22862290
/// Determines whether an item is annotated with an attribute.

compiler/rustc_typeck/src/check/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1464,7 +1464,7 @@ fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, vs: &'tcx [hir::Variant<'tcx>], def_id: L
14641464
def.destructor(tcx); // force the destructor to be evaluated
14651465

14661466
if vs.is_empty() {
1467-
if let Some(attr) = tcx.get_attr(def_id.to_def_id(), sym::repr) {
1467+
if let Some(attr) = tcx.get_attrs(def_id.to_def_id(), sym::repr).next() {
14681468
struct_span_err!(
14691469
tcx.sess,
14701470
attr.span,

src/test/ui/issues/issue-100631.rs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// issue #100631, make sure `TyCtxt::get_attr` only called by case that compiler
2+
// can reasonably deal with multiple attributes.
3+
// `repr` will use `TyCtxt::get_attrs` since it's `DuplicatesOk`.
4+
#[repr(C)] //~ ERROR: unsupported representation for zero-variant enum [E0084]
5+
#[repr(C)]
6+
enum Foo {}
7+
8+
fn main() {}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0084]: unsupported representation for zero-variant enum
2+
--> $DIR/issue-100631.rs:4:1
3+
|
4+
LL | #[repr(C)]
5+
| ^^^^^^^^^^
6+
LL | #[repr(C)]
7+
LL | enum Foo {}
8+
| -------- zero-variant enum
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0084`.

0 commit comments

Comments
 (0)