Skip to content

Commit ef07d7d

Browse files
committed
Auto merge of #28650 - sanxiyn:attr-usage, r=nrc
This is technically a [breaking-change]. Fix #2809. Fix #22746.
2 parents e650491 + 61f5b2b commit ef07d7d

File tree

10 files changed

+182
-13
lines changed

10 files changed

+182
-13
lines changed

src/librustc/front/check_attr.rs

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use session::Session;
12+
13+
use syntax::ast;
14+
use syntax::attr::AttrMetaMethods;
15+
use syntax::visit;
16+
use syntax::visit::Visitor;
17+
18+
#[derive(Copy, Clone, PartialEq)]
19+
enum Target {
20+
Fn,
21+
Struct,
22+
Enum,
23+
Other,
24+
}
25+
26+
impl Target {
27+
fn from_item(item: &ast::Item) -> Target {
28+
match item.node {
29+
ast::ItemFn(..) => Target::Fn,
30+
ast::ItemStruct(..) => Target::Struct,
31+
ast::ItemEnum(..) => Target::Enum,
32+
_ => Target::Other,
33+
}
34+
}
35+
}
36+
37+
struct CheckAttrVisitor<'a> {
38+
sess: &'a Session,
39+
}
40+
41+
impl<'a> CheckAttrVisitor<'a> {
42+
fn check_inline(&self, attr: &ast::Attribute, target: Target) {
43+
if target != Target::Fn {
44+
self.sess.span_err(
45+
attr.span,
46+
"attribute should be applied to function");
47+
}
48+
}
49+
50+
fn check_repr(&self, attr: &ast::Attribute, target: Target) {
51+
let words = match attr.meta_item_list() {
52+
Some(words) => words,
53+
None => {
54+
return;
55+
}
56+
};
57+
for word in words {
58+
let word: &str = &word.name();
59+
match word {
60+
"C" => {
61+
if target != Target::Struct && target != Target::Enum {
62+
self.sess.span_err(
63+
attr.span,
64+
"attribute should be applied to struct or enum");
65+
}
66+
}
67+
"packed" |
68+
"simd" => {
69+
if target != Target::Struct {
70+
self.sess.span_err(
71+
attr.span,
72+
"attribute should be applied to struct");
73+
}
74+
}
75+
"i8" | "u8" | "i16" | "u16" |
76+
"i32" | "u32" | "i64" | "u64" |
77+
"isize" | "usize" => {
78+
if target != Target::Enum {
79+
self.sess.span_err(
80+
attr.span,
81+
"attribute should be applied to enum");
82+
}
83+
}
84+
_ => (),
85+
}
86+
}
87+
}
88+
89+
fn check_attribute(&self, attr: &ast::Attribute, target: Target) {
90+
let name: &str = &attr.name();
91+
match name {
92+
"inline" => self.check_inline(attr, target),
93+
"repr" => self.check_repr(attr, target),
94+
_ => (),
95+
}
96+
}
97+
}
98+
99+
impl<'a, 'v> Visitor<'v> for CheckAttrVisitor<'a> {
100+
fn visit_item(&mut self, item: &ast::Item) {
101+
let target = Target::from_item(item);
102+
for attr in &item.attrs {
103+
self.check_attribute(attr, target);
104+
}
105+
}
106+
}
107+
108+
pub fn check_crate(sess: &Session, krate: &ast::Crate) {
109+
visit::walk_crate(&mut CheckAttrVisitor { sess: sess }, krate);
110+
}

src/librustc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ pub mod back {
101101
}
102102

103103
pub mod front {
104+
pub mod check_attr;
104105
pub mod map;
105106
}
106107

src/librustc_driver/driver.rs

+4
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ pub fn compile_input(sess: Session,
130130
&ast_map.krate(),
131131
&id[..]));
132132

133+
time(sess.time_passes(), "attribute checking", || {
134+
front::check_attr::check_crate(&sess, &expanded_crate);
135+
});
136+
133137
time(sess.time_passes(), "early lint checks", || {
134138
lint::check_ast_crate(&sess, &expanded_crate)
135139
});

src/librustc_front/attr.rs

-1
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,6 @@ pub enum InlineAttr {
300300

301301
/// Determine what `#[inline]` attribute is present in `attrs`, if any.
302302
pub fn find_inline_attr(diagnostic: Option<&SpanHandler>, attrs: &[Attribute]) -> InlineAttr {
303-
// FIXME (#2809)---validate the usage of #[inline] and #[inline]
304303
attrs.iter().fold(InlineAttr::None, |ia,attr| {
305304
match attr.node.value.node {
306305
MetaWord(ref n) if *n == "inline" => {

src/libsyntax/attr.rs

-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,6 @@ pub enum InlineAttr {
323323

324324
/// Determine what `#[inline]` attribute is present in `attrs`, if any.
325325
pub fn find_inline_attr(diagnostic: Option<&SpanHandler>, attrs: &[Attribute]) -> InlineAttr {
326-
// FIXME (#2809)---validate the usage of #[inline] and #[inline]
327326
attrs.iter().fold(InlineAttr::None, |ia,attr| {
328327
match attr.node.value.node {
329328
MetaWord(ref n) if *n == "inline" => {

src/test/auxiliary/sepcomp_cci_lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,4 @@ pub fn cci_fn() -> usize {
1313
1200
1414
}
1515

16-
#[inline]
17-
pub static CCI_STATIC: usize = 34;
16+
pub const CCI_CONST: usize = 34;

src/test/auxiliary/xcrate_static_addresses.rs

-3
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#[inline(never)]
1211
pub static global: isize = 3;
1312

14-
#[inline(never)]
1513
static global0: isize = 4;
1614

17-
#[inline(never)]
1815
pub static global2: &'static isize = &global0;
1916

2017
pub fn verify_same(a: &'static isize) {
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![allow(dead_code)]
12+
13+
#[inline]
14+
fn f() {}
15+
16+
#[inline] //~ ERROR: attribute should be applied to function
17+
struct S;
18+
19+
fn main() {}
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![allow(dead_code)]
12+
#![feature(repr_simd)]
13+
14+
#[repr(C)] //~ ERROR: attribute should be applied to struct or enum
15+
fn f() {}
16+
17+
#[repr(C)]
18+
struct SExtern(f64, f64);
19+
20+
#[repr(packed)]
21+
struct SPacked(f64, f64);
22+
23+
#[repr(simd)]
24+
struct SSimd(f64, f64);
25+
26+
#[repr(i8)] //~ ERROR: attribute should be applied to enum
27+
struct SInt(f64, f64);
28+
29+
#[repr(C)]
30+
enum EExtern { A, B }
31+
32+
#[repr(packed)] //~ ERROR: attribute should be applied to struct
33+
enum EPacked { A, B }
34+
35+
#[repr(simd)] //~ ERROR: attribute should be applied to struct
36+
enum ESimd { A, B }
37+
38+
#[repr(i8)]
39+
enum EInt { A, B }
40+
41+
fn main() {}

src/test/run-pass/sepcomp-cci.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,23 @@
1616

1717

1818
extern crate sepcomp_cci_lib;
19-
use sepcomp_cci_lib::{cci_fn, CCI_STATIC};
19+
use sepcomp_cci_lib::{cci_fn, CCI_CONST};
2020

2121
fn call1() -> usize {
22-
cci_fn() + CCI_STATIC
22+
cci_fn() + CCI_CONST
2323
}
2424

2525
mod a {
26-
use sepcomp_cci_lib::{cci_fn, CCI_STATIC};
26+
use sepcomp_cci_lib::{cci_fn, CCI_CONST};
2727
pub fn call2() -> usize {
28-
cci_fn() + CCI_STATIC
28+
cci_fn() + CCI_CONST
2929
}
3030
}
3131

3232
mod b {
33-
use sepcomp_cci_lib::{cci_fn, CCI_STATIC};
33+
use sepcomp_cci_lib::{cci_fn, CCI_CONST};
3434
pub fn call3() -> usize {
35-
cci_fn() + CCI_STATIC
35+
cci_fn() + CCI_CONST
3636
}
3737
}
3838

0 commit comments

Comments
 (0)