about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2018-04-05 16:51:19 +0800
committerGitHub <noreply@github.com>2018-04-05 16:51:19 +0800
commita70f84401286b58c5767ada0dfd63729640af0e9 (patch)
treea8b464ee85d225a994041703c02b197d2cafd5b8
parent46d0befb8e365acc7393e70353d21159a8910b99 (diff)
parent138472bdc6b428eafc755dbc97b2706fa13a268c (diff)
downloadrust-a70f84401286b58c5767ada0dfd63729640af0e9.tar.gz
rust-a70f84401286b58c5767ada0dfd63729640af0e9.zip
Rollup merge of #49345 - davidtwco:issue-44109, r=nikomatsakis
RFC 2008: Finishing Touches

Part of #44109.

r? @nikomatsakis
(not sure who was best for this PR).
-rw-r--r--src/librustc/diagnostics.rs27
-rw-r--r--src/librustc/hir/check_attr.rs27
-rw-r--r--src/test/compile-fail/rfc-2008-non-exhaustive/invalid-attribute.rs28
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() { }