diff options
| author | David Wood <david@davidtw.co> | 2018-03-24 18:07:18 +0000 |
|---|---|---|
| committer | David Wood <david@davidtw.co> | 2018-04-02 23:02:29 +0100 |
| commit | 138472bdc6b428eafc755dbc97b2706fa13a268c (patch) | |
| tree | eaae47d996071a68142d2625b0f12316617aad68 | |
| parent | 934902af61d8024ddd7db290b33a7076dad7b107 (diff) | |
| download | rust-138472bdc6b428eafc755dbc97b2706fa13a268c.tar.gz rust-138472bdc6b428eafc755dbc97b2706fa13a268c.zip | |
Checking location and syntax of non_exhaustive attribute.
| -rw-r--r-- | src/librustc/diagnostics.rs | 27 | ||||
| -rw-r--r-- | src/librustc/hir/check_attr.rs | 27 | ||||
| -rw-r--r-- | src/test/compile-fail/rfc-2008-non-exhaustive/invalid-attribute.rs | 28 |
3 files changed, 82 insertions, 0 deletions
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index c74ae2343b8..2662e709991 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -2058,6 +2058,33 @@ where 'x: 'y ``` "##, +E0910: r##" +This error indicates that a `#[non_exhaustive]` attribute was incorrectly placed +on something other than a struct or enum. + +Examples of erroneous code: + +```compile_fail,E0910 +# #![feature(non_exhaustive)] + +#[non_exhaustive] +trait Foo { } +``` +"##, + +E0911: r##" +This error indicates that a `#[non_exhaustive]` attribute had a value. The +`#[non_exhaustive]` should be empty. + +Examples of erroneous code: + +```compile_fail,E0911 +# #![feature(non_exhaustive)] + +#[non_exhaustive(anything)] +struct Foo; +``` +"##, } diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 316ed07ca05..956cd17f38f 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -66,6 +66,8 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { for attr in &item.attrs { if attr.check_name("inline") { self.check_inline(attr, &item.span, target) + } else if attr.check_name("non_exhaustive") { + self.check_non_exhaustive(attr, item, target) } else if attr.check_name("wasm_import_module") { has_wasm_import_module = true; if attr.value_str().is_none() { @@ -113,6 +115,31 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { } } + /// Check if the `#[non_exhaustive]` attribute on an `item` is valid. + fn check_non_exhaustive(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) { + match target { + Target::Struct | Target::Enum => { /* Valid */ }, + _ => { + struct_span_err!(self.tcx.sess, + attr.span, + E0910, + "attribute can only be applied to a struct or enum") + .span_label(item.span, "not a struct or enum") + .emit(); + return; + } + } + + if attr.meta_item_list().is_some() || attr.value_str().is_some() { + struct_span_err!(self.tcx.sess, + attr.span, + E0911, + "attribute should be empty") + .span_label(item.span, "not empty") + .emit(); + } + } + /// Check if the `#[repr]` attributes on `item` are valid. fn check_repr(&self, item: &hir::Item, target: Target) { // Extract the names of all repr hints, e.g., [foo, bar, align] for: diff --git a/src/test/compile-fail/rfc-2008-non-exhaustive/invalid-attribute.rs b/src/test/compile-fail/rfc-2008-non-exhaustive/invalid-attribute.rs new file mode 100644 index 00000000000..e48d989c01d --- /dev/null +++ b/src/test/compile-fail/rfc-2008-non-exhaustive/invalid-attribute.rs @@ -0,0 +1,28 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(non_exhaustive)] + +#[non_exhaustive(anything)] +//~^ ERROR attribute should be empty [E0911] +struct Foo; + +#[non_exhaustive] +//~^ ERROR attribute can only be applied to a struct or enum [E0910] +trait Bar { } + +#[non_exhaustive] +//~^ ERROR attribute can only be applied to a struct or enum [E0910] +union Baz { + f1: u16, + f2: u16 +} + +fn main() { } |
