Skip to content

Commit

Permalink
Rollup merge of rust-lang#83054 - tmiasko:rustc_layout_scalar_valid_r…
Browse files Browse the repository at this point in the history
…ange, r=davidtwco

Validate rustc_layout_scalar_valid_range_{start,end} attributes

Fixes rust-lang#82251, rust-lang#82981.
  • Loading branch information
Dylan-DPC authored Mar 14, 2021
2 parents 377542a + 4943190 commit 68422d2
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 1 deletion.
1 change: 1 addition & 0 deletions compiler/rustc_ast/src/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ impl NestedMetaItem {
}

impl Attribute {
#[inline]
pub fn has_name(&self, name: Symbol) -> bool {
match self.kind {
AttrKind::Normal(ref item, _) => item.path == name,
Expand Down
37 changes: 36 additions & 1 deletion compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_middle::hir::map::Map;
use rustc_middle::ty::query::Providers;
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_hir as hir;
use rustc_hir::def_id::LocalDefId;
Expand Down Expand Up @@ -87,6 +87,10 @@ impl CheckAttrVisitor<'tcx> {
self.check_export_name(hir_id, &attr, span, target)
} else if self.tcx.sess.check_name(attr, sym::rustc_args_required_const) {
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) {
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) {
Expand Down Expand Up @@ -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.
fn check_rustc_legacy_const_generics(
&self,
Expand Down
23 changes: 23 additions & 0 deletions src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.rs
Original file line number Diff line number Diff line change
@@ -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;
}
31 changes: 31 additions & 0 deletions src/test/ui/invalid/invalid_rustc_layout_scalar_valid_range.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 68422d2

Please sign in to comment.