Validate rustc_layout_scalar_valid_range_{start,end} attributes
This commit is contained in:
parent
1ba71abddd
commit
49431909a6
3 changed files with 90 additions and 1 deletions
|
@ -8,7 +8,7 @@ use rustc_middle::hir::map::Map;
|
||||||
use rustc_middle::ty::query::Providers;
|
use rustc_middle::ty::query::Providers;
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
|
|
||||||
use rustc_ast::{Attribute, LitKind, NestedMetaItem};
|
use rustc_ast::{Attribute, Lit, LitKind, NestedMetaItem};
|
||||||
use rustc_errors::{pluralize, struct_span_err};
|
use rustc_errors::{pluralize, struct_span_err};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
|
@ -87,6 +87,10 @@ impl CheckAttrVisitor<'tcx> {
|
||||||
self.check_export_name(hir_id, &attr, span, target)
|
self.check_export_name(hir_id, &attr, span, target)
|
||||||
} else if self.tcx.sess.check_name(attr, sym::rustc_args_required_const) {
|
} else if self.tcx.sess.check_name(attr, sym::rustc_args_required_const) {
|
||||||
self.check_rustc_args_required_const(&attr, span, target, item)
|
self.check_rustc_args_required_const(&attr, span, target, item)
|
||||||
|
} else if self.tcx.sess.check_name(attr, sym::rustc_layout_scalar_valid_range_start) {
|
||||||
|
self.check_rustc_layout_scalar_valid_range(&attr, span, target)
|
||||||
|
} else if self.tcx.sess.check_name(attr, sym::rustc_layout_scalar_valid_range_end) {
|
||||||
|
self.check_rustc_layout_scalar_valid_range(&attr, span, target)
|
||||||
} else if self.tcx.sess.check_name(attr, sym::allow_internal_unstable) {
|
} else if self.tcx.sess.check_name(attr, sym::allow_internal_unstable) {
|
||||||
self.check_allow_internal_unstable(hir_id, &attr, span, target, &attrs)
|
self.check_allow_internal_unstable(hir_id, &attr, span, target, &attrs)
|
||||||
} else if self.tcx.sess.check_name(attr, sym::rustc_allow_const_fn_unstable) {
|
} else if self.tcx.sess.check_name(attr, sym::rustc_allow_const_fn_unstable) {
|
||||||
|
@ -807,6 +811,37 @@ impl CheckAttrVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_rustc_layout_scalar_valid_range(
|
||||||
|
&self,
|
||||||
|
attr: &Attribute,
|
||||||
|
span: &Span,
|
||||||
|
target: Target,
|
||||||
|
) -> bool {
|
||||||
|
if target != Target::Struct {
|
||||||
|
self.tcx
|
||||||
|
.sess
|
||||||
|
.struct_span_err(attr.span, "attribute should be applied to a struct")
|
||||||
|
.span_label(*span, "not a struct")
|
||||||
|
.emit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let list = match attr.meta_item_list() {
|
||||||
|
None => return false,
|
||||||
|
Some(it) => it,
|
||||||
|
};
|
||||||
|
|
||||||
|
if matches!(&list[..], &[NestedMetaItem::Literal(Lit { kind: LitKind::Int(..), .. })]) {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
self.tcx
|
||||||
|
.sess
|
||||||
|
.struct_span_err(attr.span, "expected exactly one integer literal argument")
|
||||||
|
.emit();
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument.
|
/// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument.
|
||||||
fn check_rustc_legacy_const_generics(
|
fn check_rustc_legacy_const_generics(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
|
#[rustc_layout_scalar_valid_range_start(u32::MAX)] //~ ERROR
|
||||||
|
pub struct A(u32);
|
||||||
|
|
||||||
|
#[rustc_layout_scalar_valid_range_end(1, 2)] //~ ERROR
|
||||||
|
pub struct B(u8);
|
||||||
|
|
||||||
|
#[rustc_layout_scalar_valid_range_end(a = "a")] //~ ERROR
|
||||||
|
pub struct C(i32);
|
||||||
|
|
||||||
|
#[rustc_layout_scalar_valid_range_end(1)] //~ ERROR
|
||||||
|
enum E {
|
||||||
|
X = 1,
|
||||||
|
Y = 14,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _ = A(0);
|
||||||
|
let _ = B(0);
|
||||||
|
let _ = C(0);
|
||||||
|
let _ = E::X;
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
error: expected exactly one integer literal argument
|
||||||
|
--> $DIR/invalid_rustc_layout_scalar_valid_range.rs:3:1
|
||||||
|
|
|
||||||
|
LL | #[rustc_layout_scalar_valid_range_start(u32::MAX)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: expected exactly one integer literal argument
|
||||||
|
--> $DIR/invalid_rustc_layout_scalar_valid_range.rs:6:1
|
||||||
|
|
|
||||||
|
LL | #[rustc_layout_scalar_valid_range_end(1, 2)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: expected exactly one integer literal argument
|
||||||
|
--> $DIR/invalid_rustc_layout_scalar_valid_range.rs:9:1
|
||||||
|
|
|
||||||
|
LL | #[rustc_layout_scalar_valid_range_end(a = "a")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: attribute should be applied to a struct
|
||||||
|
--> $DIR/invalid_rustc_layout_scalar_valid_range.rs:12:1
|
||||||
|
|
|
||||||
|
LL | #[rustc_layout_scalar_valid_range_end(1)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL | / enum E {
|
||||||
|
LL | | X = 1,
|
||||||
|
LL | | Y = 14,
|
||||||
|
LL | | }
|
||||||
|
| |_- not a struct
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue