mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-08 16:07:43 +00:00
get_attr should check that no duplicates are allowed
This commit is contained in:
parent
676afc5149
commit
00b10a5552
@ -386,7 +386,8 @@ pub fn from_fn_attrs<'ll, 'tcx>(
|
|||||||
) {
|
) {
|
||||||
let span = cx
|
let span = cx
|
||||||
.tcx
|
.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);
|
.map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span);
|
||||||
let msg = format!(
|
let msg = format!(
|
||||||
"the target features {} must all be either enabled or disabled together",
|
"the target features {} must all be either enabled or disabled together",
|
||||||
|
@ -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)
|
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>> =
|
pub static BUILTIN_ATTRIBUTE_MAP: LazyLock<FxHashMap<Symbol, &BuiltinAttribute>> =
|
||||||
LazyLock::new(|| {
|
LazyLock::new(|| {
|
||||||
let mut map = FxHashMap::default();
|
let mut map = FxHashMap::default();
|
||||||
|
@ -151,7 +151,7 @@ pub use active::{Features, ACTIVE_FEATURES, INCOMPATIBLE_FEATURES};
|
|||||||
pub use builtin_attrs::AttributeDuplicates;
|
pub use builtin_attrs::AttributeDuplicates;
|
||||||
pub use builtin_attrs::{
|
pub use builtin_attrs::{
|
||||||
deprecated_attributes, find_gated_cfg, is_builtin_attr_name, is_builtin_only_local,
|
deprecated_attributes, find_gated_cfg, is_builtin_attr_name, is_builtin_only_local,
|
||||||
AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute, GatedCfg,
|
is_valid_for_get_attr, AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute,
|
||||||
BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
|
GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
|
||||||
};
|
};
|
||||||
pub use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
|
pub use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
|
||||||
|
@ -2274,7 +2274,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_attr(self, did: DefId, attr: Symbol) -> Option<&'tcx ast::Attribute> {
|
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.
|
/// Determines whether an item is annotated with an attribute.
|
||||||
|
@ -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
|
def.destructor(tcx); // force the destructor to be evaluated
|
||||||
|
|
||||||
if vs.is_empty() {
|
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!(
|
struct_span_err!(
|
||||||
tcx.sess,
|
tcx.sess,
|
||||||
attr.span,
|
attr.span,
|
||||||
|
8
src/test/ui/attributes/issue-100631.rs
Normal file
8
src/test/ui/attributes/issue-100631.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// issue #100631, make sure `TyCtxt::get_attr` only called by case that compiler
|
||||||
|
// can reasonably deal with multiple attributes.
|
||||||
|
// `repr` will use `TyCtxt::get_attrs` since it's `DuplicatesOk`.
|
||||||
|
#[repr(C)] //~ ERROR: unsupported representation for zero-variant enum [E0084]
|
||||||
|
#[repr(C)]
|
||||||
|
enum Foo {}
|
||||||
|
|
||||||
|
fn main() {}
|
12
src/test/ui/attributes/issue-100631.stderr
Normal file
12
src/test/ui/attributes/issue-100631.stderr
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
error[E0084]: unsupported representation for zero-variant enum
|
||||||
|
--> $DIR/issue-100631.rs:4:1
|
||||||
|
|
|
||||||
|
LL | #[repr(C)]
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
LL | #[repr(C)]
|
||||||
|
LL | enum Foo {}
|
||||||
|
| -------- zero-variant enum
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0084`.
|
Loading…
Reference in New Issue
Block a user