about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2017-07-11 14:30:10 +0200
committerFelix S. Klock II <pnkfelix@pnkfx.org>2017-07-11 14:31:14 +0200
commit39b8aaf26fbde1ebcf4f5a3ed9af89305743087e (patch)
tree0e965df22b7938f23f18d4c754450fc469c9df25
parentd84693b93dae3958e3504f817face0184c5c3fdd (diff)
downloadrust-39b8aaf26fbde1ebcf4f5a3ed9af89305743087e.tar.gz
rust-39b8aaf26fbde1ebcf4f5a3ed9af89305743087e.zip
Slew of feature gating tests for issue #43106.
-rw-r--r--src/test/compile-fail/feature-gate/issue-43106-gating-of-bench.rs25
-rw-r--r--src/test/compile-fail/feature-gate/issue-43106-gating-of-builtin-attrs.rs878
-rw-r--r--src/test/compile-fail/feature-gate/issue-43106-gating-of-deprecated.rs31
-rw-r--r--src/test/compile-fail/feature-gate/issue-43106-gating-of-derive-2.rs47
-rw-r--r--src/test/compile-fail/feature-gate/issue-43106-gating-of-derive.rs44
-rw-r--r--src/test/compile-fail/feature-gate/issue-43106-gating-of-inline.rs37
-rw-r--r--src/test/compile-fail/feature-gate/issue-43106-gating-of-macro_escape.rs17
-rw-r--r--src/test/compile-fail/feature-gate/issue-43106-gating-of-macro_use.rs33
-rw-r--r--src/test/compile-fail/feature-gate/issue-43106-gating-of-proc_macro_derive.rs42
-rw-r--r--src/test/compile-fail/feature-gate/issue-43106-gating-of-rustc_deprecated.rs39
-rw-r--r--src/test/compile-fail/feature-gate/issue-43106-gating-of-stable.rs38
-rw-r--r--src/test/compile-fail/feature-gate/issue-43106-gating-of-test.rs22
-rw-r--r--src/test/compile-fail/feature-gate/issue-43106-gating-of-unstable.rs38
13 files changed, 1291 insertions, 0 deletions
diff --git a/src/test/compile-fail/feature-gate/issue-43106-gating-of-bench.rs b/src/test/compile-fail/feature-gate/issue-43106-gating-of-bench.rs
new file mode 100644
index 00000000000..a34f98f0355
--- /dev/null
+++ b/src/test/compile-fail/feature-gate/issue-43106-gating-of-bench.rs
@@ -0,0 +1,25 @@
+// Copyright 2017 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.
+
+// error-pattern: main function not found
+
+// At time of authorship, a crate-level #![bench] with no `--test`
+// will cause compilation to error unconditionally with "main function
+// not found" (despite having one), similar to #[bench].
+//
+// (The non-crate level cases are in
+// issue-43106-gating-of-builtin-attrs.rs.)
+
+// See issue-12997-1.rs and issue-12997-2.rs to see how `#[bench]` is
+// handled in "weird places" when `--test` is passed.
+
+#![bench                   = "4100"]
+
+fn main() { }
diff --git a/src/test/compile-fail/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/src/test/compile-fail/feature-gate/issue-43106-gating-of-builtin-attrs.rs
new file mode 100644
index 00000000000..29a2b0609fc
--- /dev/null
+++ b/src/test/compile-fail/feature-gate/issue-43106-gating-of-builtin-attrs.rs
@@ -0,0 +1,878 @@
+// Copyright 2017 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.
+
+// This test enumerates as many compiler-builtin ungated attributes as
+// possible (that is, all the mutually compatible ones), and checks
+// that we get "expected" (*) warnings for each in the various weird
+// places that users might put them in the syntax.
+//
+// (*): The word "expected" is in quotes above because the cases where
+// warnings are and are not emitted might not match a user's intuition
+// nor the rustc developers' intent. I am really just trying to
+// capture today's behavior in a test, not so that it become enshrined
+// as the absolute behavior going forward, but rather so that we do
+// not change the behavior in the future without even being *aware* of
+// the change when it happens.
+//
+// At the time of authoring, the attributes here are listed in the
+// order that they occur in libsyntax/feature_gate.rs.
+//
+// Any builtin attributes that:
+//
+//  - are not stable, or
+//
+//  - could not be included here covering the same cases as the other
+//    attributes without raising an *error* from rustc (note though
+//    that warnings are of course expected)
+//
+// have their own test case referenced by filename in an inline
+// comment.
+//
+// The test feeds numeric inputs to each attribute that accepts them
+// without error. We do this for two reasons: (1.) to exercise how
+// inputs are handled by each, and (2.) to ease searching for related
+// occurrences in the source text.
+
+#![feature(rustc_attrs)] // For `rustc_error`; see note below.
+#![warn(unused_attributes, unknown_lints)]
+#![allow(dead_code)]
+
+// UNGATED WHITE-LISTED BUILT-IN ATTRIBUTES
+
+#![warn                        (x5400)] //~ WARN unknown lint: `x5400`
+#![allow                       (x5300)] //~ WARN unknown lint: `x5300`
+#![forbid                      (x5200)] //~ WARN unknown lint: `x5200`
+#![deny                        (x5100)] //~ WARN unknown lint: `x5100`
+#![macro_reexport             = "5000"] //~ WARN unused attribute
+#![macro_use] // (allowed if no argument; see issue-43160-gating-of-macro_use.rs)
+#![macro_export               = "4800"] //~ WARN unused attribute
+#![plugin_registrar           = "4700"] //~ WARN unused attribute
+// skipping testing of cfg
+// skipping testing of cfg_attr
+#![main                      = "x4400"] //~ WARN unused attribute
+#![start                     = "x4300"] //~ WARN unused attribute
+// see issue-43106-gating-of-test.rs for crate-level; but non crate-level is below at "4200"
+// see issue-43106-gating-of-bench.rs for crate-level; but non crate-level is below at "4100"
+#![simd                       = "4000"] //~ WARN unused attribute
+#![repr                       = "3900"] //~ WARN unused attribute
+#![path                       = "3800"] //~ WARN unused attribute
+#![abi                        = "3700"] //~ WARN unused attribute
+#![automatically_derived      = "3600"] //~ WARN unused attribute
+#![no_mangle                  = "3500"]
+#![no_link                    = "3400"] //~ WARN unused attribute
+// see issue-43106-gating-of-derive.rs
+#![should_panic               = "3200"] //~ WARN unused attribute
+#![ignore                     = "3100"] //~ WARN unused attribute
+#![no_implicit_prelude        = "3000"]
+#![reexport_test_harness_main = "2900"]
+// see gated-link-args.rs
+// see issue-43106-gating-of-macro_escape.rs for crate-level; but non crate-level is below at "2700"
+// (cannot easily test gating of crate-level #[no_std]; but non crate-level is below at "2600")
+#![proc_macro_derive          = "2500"] //~ WARN unused attribute
+#![doc                        = "2400"]
+#![cold                       = "2300"]
+#![export_name                = "2200"]
+// see issue-43106-gating-of-inline.rs
+#![link                       = "2000"]
+#![link_name                  = "1900"]
+#![link_section               = "1800"]
+#![no_builtins                = "1700"] // Yikes, dupe'd on BUILTIN_ATTRIBUTES list (see "0300")
+#![no_mangle                  = "1600"] // Yikes, dupe'd on BUILTIN_ATTRIBUTES list (see "3500")
+// see issue-43106-gating-of-rustc_deprecated.rs
+#![must_use                   = "1400"]
+// see issue-43106-gating-of-stable.rs
+// see issue-43106-gating-of-unstable.rs
+// see issue-43106-gating-of-deprecated.rs
+#![windows_subsystem          = "1000"]
+
+// UNGATED CRATE-LEVEL BUILT-IN ATTRIBUTES
+
+#![crate_name                 = "0900"]
+#![crate_type                 = "bin"] // cannot pass "0800" here
+
+// For #![crate_id], see issue #43142. (I cannot bear to enshrine current behavior in a test)
+
+#![feature                    ( x0600)] //~ WARN unused or unknown feature
+
+// For #![no_start], see issue #43144. (I cannot bear to enshrine current behavior in a test)
+
+// (cannot easily gating state of crate-level #[no_main]; but non crate-level is below at "0400")
+#![no_builtins                = "0300"]
+#![recursion_limit            = "0200"]
+#![type_length_limit          = "0100"]
+
+// USES OF BUILT-IN ATTRIBUTES IN OTHER ("UNUSUAL") PLACES
+
+#[warn(x5400)]
+//~^ WARN unknown lint: `x5400`
+mod warn {
+    mod inner { #![warn(x5400)] }
+    //~^ WARN unknown lint: `x5400`
+
+    #[warn(x5400)] fn f() { }
+    //~^ WARN unknown lint: `x5400`
+
+    #[warn(x5400)] struct S;
+    //~^ WARN unknown lint: `x5400`
+
+    #[warn(x5400)] type T = S;
+    //~^ WARN unknown lint: `x5400`
+
+    #[warn(x5400)] impl S { }
+    //~^ WARN unknown lint: `x5400`
+}
+
+#[allow(x5300)]
+//~^ WARN unknown lint: `x5300`
+mod allow {
+    mod inner { #![allow(x5300)] }
+    //~^ WARN unknown lint: `x5300`
+
+    #[allow(x5300)] fn f() { }
+    //~^ WARN unknown lint: `x5300`
+
+    #[allow(x5300)] struct S;
+    //~^ WARN unknown lint: `x5300`
+
+    #[allow(x5300)] type T = S;
+    //~^ WARN unknown lint: `x5300`
+
+    #[allow(x5300)] impl S { }
+    //~^ WARN unknown lint: `x5300`
+}
+
+#[forbid(x5200)]
+//~^ WARN unknown lint: `x5200`
+mod forbid {
+    mod inner { #![forbid(x5200)] }
+    //~^ WARN unknown lint: `x5200`
+
+    #[forbid(x5200)] fn f() { }
+    //~^ WARN unknown lint: `x5200`
+
+    #[forbid(x5200)] struct S;
+    //~^ WARN unknown lint: `x5200`
+
+    #[forbid(x5200)] type T = S;
+    //~^ WARN unknown lint: `x5200`
+
+    #[forbid(x5200)] impl S { }
+    //~^ WARN unknown lint: `x5200`
+}
+
+#[deny(x5100)]
+//~^ WARN unknown lint: `x5100`
+mod deny {
+    mod inner { #![deny(x5100)] }
+    //~^ WARN unknown lint: `x5100`
+
+    #[deny(x5100)] fn f() { }
+    //~^ WARN unknown lint: `x5100`
+
+    #[deny(x5100)] struct S;
+    //~^ WARN unknown lint: `x5100`
+
+    #[deny(x5100)] type T = S;
+    //~^ WARN unknown lint: `x5100`
+
+    #[deny(x5100)] impl S { }
+    //~^ WARN unknown lint: `x5100`
+}
+
+#[macro_reexport = "5000"]
+//~^ WARN unused attribute
+mod macro_reexport {
+    mod inner { #![macro_reexport="5000"] }
+    //~^ WARN unused attribute
+
+    #[macro_reexport = "5000"] fn f() { }
+    //~^ WARN unused attribute
+
+    #[macro_reexport = "5000"] struct S;
+    //~^ WARN unused attribute
+
+    #[macro_reexport = "5000"] type T = S;
+    //~^ WARN unused attribute
+
+    #[macro_reexport = "5000"] impl S { }
+    //~^ WARN unused attribute
+}
+
+#[macro_use]
+mod macro_use {
+    mod inner { #![macro_use] }
+
+    #[macro_use] fn f() { }
+    //~^ WARN unused attribute
+
+    #[macro_use] struct S;
+    //~^ WARN unused attribute
+
+    #[macro_use] type T = S;
+    //~^ WARN unused attribute
+
+    #[macro_use] impl S { }
+    //~^ WARN unused attribute
+}
+
+#[macro_export = "4800"]
+//~^ WARN unused attribute
+mod macro_export {
+    mod inner { #![macro_export="4800"] }
+    //~^ WARN unused attribute
+
+    #[macro_export = "4800"] fn f() { }
+    //~^ WARN unused attribute
+
+    #[macro_export = "4800"] struct S;
+    //~^ WARN unused attribute
+
+    #[macro_export = "4800"] type T = S;
+    //~^ WARN unused attribute
+
+    #[macro_export = "4800"] impl S { }
+    //~^ WARN unused attribute
+}
+
+#[plugin_registrar = "4700"]
+//~^ WARN unused attribute
+mod plugin_registrar {
+    mod inner { #![plugin_registrar="4700"] }
+    //~^ WARN unused attribute
+
+    // for `fn f()` case, see gated-plugin_registrar.rs
+
+    #[plugin_registrar = "4700"] struct S;
+    //~^ WARN unused attribute
+
+    #[plugin_registrar = "4700"] type T = S;
+    //~^ WARN unused attribute
+
+    #[plugin_registrar = "4700"] impl S { }
+    //~^ WARN unused attribute
+}
+
+#[main = "4400"]
+//~^ WARN unused attribute
+mod main {
+    mod inner { #![main="4300"] }
+    //~^ WARN unused attribute
+
+    // for `fn f()` case, see feature-gate-main.rs
+
+    #[main = "4400"] struct S;
+    //~^ WARN unused attribute
+
+    #[main = "4400"] type T = S;
+    //~^ WARN unused attribute
+
+    #[main = "4400"] impl S { }
+    //~^ WARN unused attribute
+}
+
+#[start = "4300"]
+//~^ WARN unused attribute
+mod start {
+    mod inner { #![start="4300"] }
+    //~^ WARN unused attribute
+
+    // for `fn f()` case, see feature-gate-start.rs
+
+    #[start = "4300"] struct S;
+    //~^ WARN unused attribute
+
+    #[start = "4300"] type T = S;
+    //~^ WARN unused attribute
+
+    #[start = "4300"] impl S { }
+    //~^ WARN unused attribute
+}
+
+// At time of unit test authorship, if compiling without `--test` then
+// non-crate-level #[test] attributes seem to be ignored.
+
+#[test = "4200"]
+mod test { mod inner { #![test="4200"] }
+
+    fn f() { }
+
+    struct S;
+
+    type T = S;
+
+    impl S { }
+}
+
+// At time of unit test authorship, if compiling without `--test` then
+// non-crate-level #[bench] attributes seem to be ignored.
+
+#[bench = "4100"]
+mod bench {
+    mod inner { #![bench="4100"] }
+
+    #[bench = "4100"]
+    struct S;
+
+    #[bench = "4100"]
+    type T = S;
+
+    #[bench = "4100"]
+    impl S { }
+}
+
+#[simd = "4000"]
+//~^ WARN unused attribute
+mod simd {
+    mod inner { #![simd="4000"] }
+    //~^ WARN unused attribute
+
+    #[simd = "4000"] fn f() { }
+    //~^ WARN unused attribute
+
+    struct S; // for `struct S` case, see feature-gate-repr-simd.rs
+
+    #[simd = "4000"] type T = S;
+    //~^ WARN unused attribute
+
+    #[simd = "4000"] impl S { }
+    //~^ WARN unused attribute
+}
+
+#[repr = "3900"]
+//~^ WARN unused attribute
+mod repr {
+    mod inner { #![repr="3900"] }
+    //~^ WARN unused attribute
+
+    #[repr = "3900"] fn f() { }
+    //~^ WARN unused attribute
+
+    #[repr = "3900"] struct S;
+    //~^ WARN unused attribute
+
+    #[repr = "3900"] type T = S;
+    //~^ WARN unused attribute
+
+    #[repr = "3900"] impl S { }
+    //~^ WARN unused attribute
+}
+
+#[path = "3800"]
+mod path {
+    mod inner { #![path="3800"] }
+
+    #[path = "3800"] fn f() { }
+    //~^ WARN unused attribute
+
+    #[path = "3800"]  struct S;
+    //~^ WARN unused attribute
+
+    #[path = "3800"] type T = S;
+    //~^ WARN unused attribute
+
+    #[path = "3800"] impl S { }
+    //~^ WARN unused attribute
+}
+
+#[abi = "3700"]
+//~^ WARN unused attribute
+mod abi {
+    mod inner { #![abi="3700"] }
+    //~^ WARN unused attribute
+
+    #[abi = "3700"] fn f() { }
+    //~^ WARN unused attribute
+
+    #[abi = "3700"] struct S;
+    //~^ WARN unused attribute
+
+    #[abi = "3700"] type T = S;
+    //~^ WARN unused attribute
+
+    #[abi = "3700"] impl S { }
+    //~^ WARN unused attribute
+}
+
+#[automatically_derived = "3600"]
+//~^ WARN unused attribute
+mod automatically_derived {
+    mod inner { #![automatically_derived="3600"] }
+    //~^ WARN unused attribute
+
+    #[automatically_derived = "3600"] fn f() { }
+    //~^ WARN unused attribute
+
+    #[automatically_derived = "3600"] struct S;
+    //~^ WARN unused attribute
+
+    #[automatically_derived = "3600"] type T = S;
+    //~^ WARN unused attribute
+
+    #[automatically_derived = "3600"] impl S { }
+    //~^ WARN unused attribute
+}
+
+#[no_mangle = "3500"]
+mod no_mangle {
+    mod inner { #![no_mangle="3500"] }
+
+    #[no_mangle = "3500"] fn f() { }
+    //~^ WARN function f is marked #[no_mangle], but not exported
+
+    #[no_mangle = "3500"] struct S;
+
+    #[no_mangle = "3500"] type T = S;
+
+    #[no_mangle = "3500"] impl S { }
+}
+
+#[no_link = "3400"]
+//~^ WARN unused attribute
+mod no_link {
+    mod inner { #![no_link="3400"] }
+    //~^ WARN unused attribute
+
+    #[no_link = "3400"] fn f() { }
+    //~^ WARN unused attribute
+
+    #[no_link = "3400"] struct S;
+    //~^ WARN unused attribute
+
+    #[no_link = "3400"]type T = S;
+    //~^ WARN unused attribute
+
+    #[no_link = "3400"] impl S { }
+    //~^ WARN unused attribute
+}
+
+#[should_panic = "3200"]
+//~^ WARN unused attribute
+mod should_panic {
+    mod inner { #![should_panic="3200"] }
+    //~^ WARN unused attribute
+
+    #[should_panic = "3200"] fn f() { }
+    //~^ WARN unused attribute
+
+    #[should_panic = "3200"] struct S;
+    //~^ WARN unused attribute
+
+    #[should_panic = "3200"] type T = S;
+    //~^ WARN unused attribute
+
+    #[should_panic = "3200"] impl S { }
+    //~^ WARN unused attribute
+}
+
+#[ignore = "3100"]
+//~^ WARN unused attribute
+mod ignore {
+    mod inner { #![ignore="3100"] }
+    //~^ WARN unused attribute
+
+    #[ignore = "3100"] fn f() { }
+    //~^ WARN unused attribute
+
+    #[ignore = "3100"] struct S;
+    //~^ WARN unused attribute
+
+    #[ignore = "3100"] type T = S;
+    //~^ WARN unused attribute
+
+    #[ignore = "3100"] impl S { }
+    //~^ WARN unused attribute
+}
+
+#[no_implicit_prelude = "3000"]
+//~^ WARN unused attribute
+mod no_implicit_prelude {
+    mod inner { #![no_implicit_prelude="3000"] }
+    //~^ WARN unused attribute
+
+    #[no_implicit_prelude = "3000"] fn f() { }
+    //~^ WARN unused attribute
+
+    #[no_implicit_prelude = "3000"] struct S;
+    //~^ WARN unused attribute
+
+    #[no_implicit_prelude = "3000"] type T = S;
+    //~^ WARN unused attribute
+
+    #[no_implicit_prelude = "3000"] impl S { }
+    //~^ WARN unused attribute
+}
+
+#[reexport_test_harness_main = "2900"]
+//~^ WARN unused attribute
+mod reexport_test_harness_main {
+    mod inner { #![reexport_test_harness_main="2900"] }
+    //~^ WARN unused attribute
+
+    #[reexport_test_harness_main = "2900"] fn f() { }
+    //~^ WARN unused attribute
+
+    #[reexport_test_harness_main = "2900"] struct S;
+    //~^ WARN unused attribute
+
+    #[reexport_test_harness_main = "2900"] type T = S;
+    //~^ WARN unused attribute
+
+    #[reexport_test_harness_main = "2900"] impl S { }
+    //~^ WARN unused attribute
+}
+
+// Cannnot feed "2700" to `#[macro_escape]` without signaling an error.
+#[macro_escape]
+//~^ WARN macro_escape is a deprecated synonym for macro_use
+mod macro_escape {
+    mod inner { #![macro_escape] }
+    //~^ WARN macro_escape is a deprecated synonym for macro_use
+
+    #[macro_escape] fn f() { }
+    //~^ WARN unused attribute
+
+    #[macro_escape] struct S;
+    //~^ WARN unused attribute
+
+    #[macro_escape] type T = S;
+    //~^ WARN unused attribute
+
+    #[macro_escape] impl S { }
+    //~^ WARN unused attribute
+}
+
+#[no_std = "2600"]
+//~^ WARN unused attribute
+//~| WARN crate-level attribute should be an inner attribute
+mod no_std {
+    mod inner { #![no_std="2600"] }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be in the root module
+
+    #[no_std = "2600"] fn f() { }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[no_std = "2600"] struct S;
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[no_std = "2600"] type T = S;
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[no_std = "2600"] impl S { }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+}
+
+// At time of authorship, #[proc_macro_derive = "2500"] signals error
+// when it occurs on a mod (apart from crate-level). Therefore it goes
+// into its own file; see issue-43106-gating-of-proc_macro_derive.rs
+
+#[doc = "2400"]
+mod doc {
+    mod inner { #![doc="2400"] }
+
+    #[doc = "2400"] fn f() { }
+
+    #[doc = "2400"] struct S;
+
+    #[doc = "2400"] type T = S;
+
+    #[doc = "2400"] impl S { }
+}
+
+#[cold = "2300"]
+mod cold {
+    mod inner { #![cold="2300"] }
+
+    #[cold = "2300"] fn f() { }
+
+    #[cold = "2300"] struct S;
+
+    #[cold = "2300"] type T = S;
+
+    #[cold = "2300"] impl S { }
+}
+
+#[export_name = "2200"]
+mod export_name {
+    mod inner { #![export_name="2200"] }
+
+    #[export_name = "2200"] fn f() { }
+
+    #[export_name = "2200"] struct S;
+
+    #[export_name = "2200"] type T = S;
+
+    #[export_name = "2200"] impl S { }
+}
+
+// Note that this test ends with a `#[rustc_error] fn main()`, so it
+// will never invoke the linker. These are here nonetheless to point
+// out that we allow them at non-crate-level (though I do not know
+// whether they have the same effect here as at crate-level).
+
+#[link = "2000"]
+mod link {
+    mod inner { #![link="2000"] }
+
+    #[link = "2000"] fn f() { }
+
+    #[link = "2000"] struct S;
+
+    #[link = "2000"] type T = S;
+
+    #[link = "2000"] impl S { }
+}
+
+#[link_name = "1900"]
+mod link_name {
+    mod inner { #![link_name="1900"] }
+
+    #[link_name = "1900"] fn f() { }
+
+    #[link_name = "1900"] struct S;
+
+    #[link_name = "1900"] type T = S;
+
+    #[link_name = "1900"] impl S { }
+}
+
+#[link_section = "1800"]
+mod link_section {
+    mod inner { #![link_section="1800"] }
+
+    #[link_section = "1800"] fn f() { }
+
+    #[link_section = "1800"] struct S;
+
+    #[link_section = "1800"] type T = S;
+
+    #[link_section = "1800"] impl S { }
+}
+
+struct StructForDeprecated;
+
+#[deprecated = "1500"]
+mod deprecated {
+    mod inner { #![deprecated="1500"] }
+
+    #[deprecated = "1500"] fn f() { }
+
+    #[deprecated = "1500"] struct S1;
+
+    #[deprecated = "1500"] type T = super::StructForDeprecated;
+
+    #[deprecated = "1500"] impl super::StructForDeprecated { }
+}
+
+#[must_use = "1400"]
+mod must_use {
+    mod inner { #![must_use="1400"] }
+
+    #[must_use = "1400"] fn f() { }
+
+    #[must_use = "1400"] struct S;
+
+    #[must_use = "1400"] type T = S;
+
+    #[must_use = "1400"] impl S { }
+}
+
+#[windows_subsystem = "1000"]
+mod windows_subsystem {
+    mod inner { #![windows_subsystem="1000"] }
+
+    #[windows_subsystem = "1000"] fn f() { }
+
+    #[windows_subsystem = "1000"] struct S;
+
+    #[windows_subsystem = "1000"] type T = S;
+
+    #[windows_subsystem = "1000"] impl S { }
+}
+
+// BROKEN USES OF CRATE-LEVEL BUILT-IN ATTRIBUTES
+
+#[crate_name = "0900"]
+//~^ WARN unused attribute
+//~| WARN crate-level attribute should be an inner attribute
+mod crate_name {
+    mod inner { #![crate_name="0900"] }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be in the root module
+
+    #[crate_name = "0900"] fn f() { }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[crate_name = "0900"] struct S;
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[crate_name = "0900"] type T = S;
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[crate_name = "0900"] impl S { }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+}
+
+#[crate_type = "0800"]
+//~^ WARN unused attribute
+//~| WARN crate-level attribute should be an inner attribute
+mod crate_type {
+    mod inner { #![crate_type="0800"] }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be in the root module
+
+    #[crate_type = "0800"] fn f() { }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[crate_type = "0800"] struct S;
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[crate_type = "0800"] type T = S;
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[crate_type = "0800"] impl S { }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+}
+
+#[feature(x0600)]
+//~^ WARN unused attribute
+//~| WARN crate-level attribute should be an inner attribute
+mod feature {
+    mod inner { #![feature(x0600)] }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be in the root module
+
+    #[feature(x0600)] fn f() { }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[feature(x0600)] struct S;
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[feature(x0600)] type T = S;
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[feature(x0600)] impl S { }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+}
+
+
+#[no_main = "0400"]
+//~^ WARN unused attribute
+//~| WARN crate-level attribute should be an inner attribute
+mod no_main_1 {
+    mod inner { #![no_main="0400"] }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be in the root module
+
+    #[no_main = "0400"] fn f() { }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[no_main = "0400"] struct S;
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[no_main = "0400"] type T = S;
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[no_main = "0400"] impl S { }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+}
+
+#[no_builtins = "0300"]
+mod no_builtins {
+    mod inner { #![no_builtins="0200"] }
+
+    #[no_builtins = "0300"] fn f() { }
+
+    #[no_builtins = "0300"] struct S;
+
+    #[no_builtins = "0300"] type T = S;
+
+    #[no_builtins = "0300"] impl S { }
+}
+
+#[recursion_limit="0200"]
+//~^ WARN unused attribute
+//~| WARN crate-level attribute should be an inner attribute
+mod recursion_limit {
+    mod inner { #![recursion_limit="0200"] }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be in the root module
+
+    #[recursion_limit="0200"] fn f() { }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[recursion_limit="0200"] struct S;
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[recursion_limit="0200"] type T = S;
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[recursion_limit="0200"] impl S { }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+}
+
+#[type_length_limit="0100"]
+//~^ WARN unused attribute
+//~| WARN crate-level attribute should be an inner attribute
+mod type_length_limit {
+    mod inner { #![type_length_limit="0100"] }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be in the root module
+
+    #[type_length_limit="0100"] fn f() { }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[type_length_limit="0100"] struct S;
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[type_length_limit="0100"] type T = S;
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+
+    #[type_length_limit="0100"] impl S { }
+    //~^ WARN unused attribute
+    //~| WARN crate-level attribute should be an inner attribute
+}
+
+// Since we expect for the mix of attributes used here to compile
+// successfully, and we are just testing for the expected warnings of
+// various (mis)uses of attributes, we use the `rustc_error` attribute
+// on the `fn main()`.
+
+#[rustc_error]
+fn main() { //~ ERROR compilation successful
+    println!("Hello World");
+}
diff --git a/src/test/compile-fail/feature-gate/issue-43106-gating-of-deprecated.rs b/src/test/compile-fail/feature-gate/issue-43106-gating-of-deprecated.rs
new file mode 100644
index 00000000000..98da43c3a22
--- /dev/null
+++ b/src/test/compile-fail/feature-gate/issue-43106-gating-of-deprecated.rs
@@ -0,0 +1,31 @@
+// Copyright 2017 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.
+
+// This test just shows that a crate-level `#![deprecated]` does not
+// signal a warning or error. (This file sits on its own because a
+// crate-level `#![deprecated]` causes all that crate's item
+// definitions to be deprecated, which is a pain to work with.)
+//
+// (For non-crate-level cases, see issue-43106-gating-of-builtin-attrs.rs)
+
+#![feature(rustc_attrs)] // For `rustc_error`; see note below.
+#![allow(dead_code)]
+
+#![deprecated           = "1100"]
+
+// Since we expect for the mix of attributes used here to compile
+// successfully, and we are just testing for the expected warnings of
+// various (mis)uses of attributes, we use the `rustc_error` attribute
+// on the `fn main()`.
+
+#[rustc_error]
+fn main() { //~ ERROR compilation successful
+    println!("Hello World");
+}
diff --git a/src/test/compile-fail/feature-gate/issue-43106-gating-of-derive-2.rs b/src/test/compile-fail/feature-gate/issue-43106-gating-of-derive-2.rs
new file mode 100644
index 00000000000..be82d0a5f6d
--- /dev/null
+++ b/src/test/compile-fail/feature-gate/issue-43106-gating-of-derive-2.rs
@@ -0,0 +1,47 @@
+// Copyright 2017 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.
+
+// `#![derive]` is interpreted (and raises errors) when it occurs at
+// contexts other than ADT definitions. This test checks cases where
+// the derive-macro does not exist.
+
+#![derive(x3300)]
+//~^ ERROR cannot find derive macro `x3300` in this scope
+
+#[derive(x3300)]
+//~^ ERROR cannot find derive macro `x3300` in this scope
+mod derive {
+    mod inner { #![derive(x3300)] }
+    //~^ ERROR cannot find derive macro `x3300` in this scope
+
+    #[derive(x3300)]
+    //~^ ERROR cannot find derive macro `x3300` in this scope
+    fn derive() { }
+
+    #[derive(x3300)]
+    //~^ ERROR cannot find derive macro `x3300` in this scope
+    union U { f: i32 }
+
+    #[derive(x3300)]
+    //~^ ERROR cannot find derive macro `x3300` in this scope
+    enum E { }
+
+    #[derive(x3300)]
+    //~^ ERROR cannot find derive macro `x3300` in this scope
+    struct S;
+
+    #[derive(x3300)]
+    //~^ ERROR cannot find derive macro `x3300` in this scope
+    type T = S;
+
+    #[derive(x3300)]
+    //~^ ERROR cannot find derive macro `x3300` in this scope
+    impl S { }
+}
diff --git a/src/test/compile-fail/feature-gate/issue-43106-gating-of-derive.rs b/src/test/compile-fail/feature-gate/issue-43106-gating-of-derive.rs
new file mode 100644
index 00000000000..41c3d0ef561
--- /dev/null
+++ b/src/test/compile-fail/feature-gate/issue-43106-gating-of-derive.rs
@@ -0,0 +1,44 @@
+// Copyright 2017 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.
+
+// `#![derive]` is interpreted (and raises errors) when it occurs at
+// contexts other than ADT definitions. This test checks cases where
+// the derive-macro exists.
+
+#![derive(Debug)]
+//~^ ERROR `derive` may only be applied to structs, enums and unions
+
+#[derive(Debug)]
+//~^ ERROR `derive` may only be applied to structs, enums and unions
+mod derive {
+    mod inner { #![derive(Debug)] }
+    //~^ ERROR `derive` may only be applied to structs, enums and unions
+
+    #[derive(Debug)]
+    //~^ ERROR `derive` may only be applied to structs, enums and unions
+    fn derive() { }
+
+    #[derive(Copy, Clone)] // (can't derive Debug for unions)
+    union U { f: i32 }
+
+    #[derive(Debug)]
+    struct S;
+
+    #[derive(Debug)]
+    enum E { }
+
+    #[derive(Debug)]
+    //~^ ERROR `derive` may only be applied to structs, enums and unions
+    type T = S;
+
+    #[derive(Debug)]
+    //~^ ERROR `derive` may only be applied to structs, enums and unions
+    impl S { }
+}
diff --git a/src/test/compile-fail/feature-gate/issue-43106-gating-of-inline.rs b/src/test/compile-fail/feature-gate/issue-43106-gating-of-inline.rs
new file mode 100644
index 00000000000..24e77bf60a8
--- /dev/null
+++ b/src/test/compile-fail/feature-gate/issue-43106-gating-of-inline.rs
@@ -0,0 +1,37 @@
+// Copyright 2017 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.
+
+// This is testing whether `#[inline]` signals an error or warning
+// when put in "weird" places.
+//
+// (This file sits on its own because it actually signals an error,
+// which would mess up the treatment of other cases in
+// issue-43106-gating-of-builtin-attrs.rs)
+
+// Crate-level is accepted, though it is almost certainly unused?
+#![inline                     = "2100"]
+
+#[inline = "2100"]
+//~^ ERROR attribute should be applied to function
+mod inline {
+    mod inner { #![inline="2100"] }
+    //~^ ERROR attribute should be applied to function
+
+    #[inline = "2100"] fn f() { }
+
+    #[inline = "2100"] struct S;
+    //~^ ERROR attribute should be applied to function
+
+    #[inline = "2100"] type T = S;
+    //~^ ERROR attribute should be applied to function
+
+    #[inline = "2100"] impl S { }
+    //~^ ERROR attribute should be applied to function
+}
diff --git a/src/test/compile-fail/feature-gate/issue-43106-gating-of-macro_escape.rs b/src/test/compile-fail/feature-gate/issue-43106-gating-of-macro_escape.rs
new file mode 100644
index 00000000000..3b2dbdefeba
--- /dev/null
+++ b/src/test/compile-fail/feature-gate/issue-43106-gating-of-macro_escape.rs
@@ -0,0 +1,17 @@
+// Copyright 2017 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.
+
+// Testing that crate-level `#![macro_escape]` is not gated beyond a
+// depecation warning.  This file sits on its own, because crate-level
+// `#![macro_escape]` is incompatible with crate-level `#![macro_use]`
+// already present in issue-43106-gating-of-builtin-attrs.
+
+#![macro_escape]
+//~^ WARN macro_escape is a deprecated synonym for macro_use
diff --git a/src/test/compile-fail/feature-gate/issue-43106-gating-of-macro_use.rs b/src/test/compile-fail/feature-gate/issue-43106-gating-of-macro_use.rs
new file mode 100644
index 00000000000..cf5619da3c7
--- /dev/null
+++ b/src/test/compile-fail/feature-gate/issue-43106-gating-of-macro_use.rs
@@ -0,0 +1,33 @@
+// Copyright 2017 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.
+
+// This is just a check-list of the cases where feeding arguments to
+// `#[macro_use]` is rejected. (The cases where no error is emitted
+// corresponds to cases where the attribute is currently unused, so we
+// get that warning; see issue-43106-gating-of-builtin-attrs.rs
+
+#![macro_use                  = "4900"] //~ ERROR arguments to macro_use are not allowed here
+
+#[macro_use = "2700"]
+//~^ ERROR arguments to macro_use are not allowed here
+mod macro_escape {
+    mod inner { #![macro_use="2700"] }
+    //~^ ERROR arguments to macro_use are not allowed here
+
+    #[macro_use = "2700"] fn f() { }
+
+    #[macro_use = "2700"] struct S;
+
+    #[macro_use = "2700"] type T = S;
+
+    #[macro_use = "2700"] impl S { }
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/feature-gate/issue-43106-gating-of-proc_macro_derive.rs b/src/test/compile-fail/feature-gate/issue-43106-gating-of-proc_macro_derive.rs
new file mode 100644
index 00000000000..133f70e0f3b
--- /dev/null
+++ b/src/test/compile-fail/feature-gate/issue-43106-gating-of-proc_macro_derive.rs
@@ -0,0 +1,42 @@
+// Copyright 2017 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.
+
+// At time of authorship, #[proc_macro_derive = "2500"] will emit an
+// error when it occurs on a mod (apart from crate-level), but will
+// not descend further into the mod for other occurrences of the same
+// error.
+//
+// This file sits on its own because the the "weird" occurrences here
+// signal errors, making it incompatible with the "warnings only"
+// nature of issue-43106-gating-of-builtin-attrs.rs
+
+#[proc_macro_derive = "2500"]
+//~^ ERROR the `#[proc_macro_derive]` attribute may only be used on bare functions
+mod proc_macro_derive1 {
+    mod inner { #![proc_macro_derive="2500"] }
+    // (no error issued here if there was one on outer module)
+}
+
+mod proc_macro_derive2 {
+    mod inner { #![proc_macro_derive="2500"] }
+    //~^ ERROR the `#[proc_macro_derive]` attribute may only be used on bare functions
+
+    #[proc_macro_derive = "2500"] fn f() { }
+    //~^ ERROR the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro`
+
+    #[proc_macro_derive = "2500"] struct S;
+    //~^ ERROR the `#[proc_macro_derive]` attribute may only be used on bare functions
+
+    #[proc_macro_derive = "2500"] type T = S;
+    //~^ ERROR the `#[proc_macro_derive]` attribute may only be used on bare functions
+
+    #[proc_macro_derive = "2500"] impl S { }
+    //~^ ERROR the `#[proc_macro_derive]` attribute may only be used on bare functions
+}
diff --git a/src/test/compile-fail/feature-gate/issue-43106-gating-of-rustc_deprecated.rs b/src/test/compile-fail/feature-gate/issue-43106-gating-of-rustc_deprecated.rs
new file mode 100644
index 00000000000..4709ec2bc57
--- /dev/null
+++ b/src/test/compile-fail/feature-gate/issue-43106-gating-of-rustc_deprecated.rs
@@ -0,0 +1,39 @@
+// Copyright 2017 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.
+
+// Testing gating of `#[rustc_deprecated]` in "weird" places.
+//
+// This file sits on its own because these signal errors, making
+// this test incompatible with the "warnings only" nature of
+// issue-43106-gating-of-builtin-attrs.rs
+
+#![rustc_deprecated           = "1500"]
+//~^ ERROR stability attributes may not be used outside of the standard library
+
+#[rustc_deprecated = "1500"]
+//~^ ERROR stability attributes may not be used outside of the standard library
+mod rustc_deprecated {
+    mod inner { #![rustc_deprecated="1500"] }
+    //~^ ERROR stability attributes may not be used outside of the standard library
+
+    #[rustc_deprecated = "1500"] fn f() { }
+    //~^ ERROR stability attributes may not be used outside of the standard library
+
+    #[rustc_deprecated = "1500"] struct S;
+    //~^ ERROR stability attributes may not be used outside of the standard library
+    //~| ERROR stability attributes may not be used outside of the standard library
+
+    #[rustc_deprecated = "1500"] type T = S;
+    //~^ ERROR stability attributes may not be used outside of the standard library
+
+    #[rustc_deprecated = "1500"] impl S { }
+    //~^ ERROR stability attributes may not be used outside of the standard library
+}
+
diff --git a/src/test/compile-fail/feature-gate/issue-43106-gating-of-stable.rs b/src/test/compile-fail/feature-gate/issue-43106-gating-of-stable.rs
new file mode 100644
index 00000000000..9627d32d42a
--- /dev/null
+++ b/src/test/compile-fail/feature-gate/issue-43106-gating-of-stable.rs
@@ -0,0 +1,38 @@
+// Copyright 2017 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.
+
+// Testing gating of `#[stable]` in "weird" places.
+//
+// This file sits on its own because these signal errors, making
+// this test incompatible with the "warnings only" nature of
+// issue-43106-gating-of-builtin-attrs.rs
+
+#![stable                     = "1300"]
+//~^ ERROR stability attributes may not be used outside of the standard library
+
+#[stable = "1300"]
+//~^ ERROR stability attributes may not be used outside of the standard library
+mod stable {
+    mod inner { #![stable="1300"] }
+    //~^ ERROR stability attributes may not be used outside of the standard library
+
+    #[stable = "1300"] fn f() { }
+    //~^ ERROR stability attributes may not be used outside of the standard library
+
+    #[stable = "1300"] struct S;
+    //~^ ERROR stability attributes may not be used outside of the standard library
+    //~| ERROR stability attributes may not be used outside of the standard library
+
+    #[stable = "1300"] type T = S;
+    //~^ ERROR stability attributes may not be used outside of the standard library
+
+    #[stable = "1300"] impl S { }
+    //~^ ERROR stability attributes may not be used outside of the standard library
+}
diff --git a/src/test/compile-fail/feature-gate/issue-43106-gating-of-test.rs b/src/test/compile-fail/feature-gate/issue-43106-gating-of-test.rs
new file mode 100644
index 00000000000..adcbfe77280
--- /dev/null
+++ b/src/test/compile-fail/feature-gate/issue-43106-gating-of-test.rs
@@ -0,0 +1,22 @@
+// Copyright 2017 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.
+
+// error-pattern: main function not found
+
+// At time of authorship, crate-level #[test] attribute with no
+// `--test` signals unconditional error complaining of missing main
+// function (despite having one), similar to #[bench].
+//
+// (The non-crate level cases are in
+// issue-43106-gating-of-builtin-attrs.rs.)
+
+#![test                    = "4200"]
+
+fn main() { }
diff --git a/src/test/compile-fail/feature-gate/issue-43106-gating-of-unstable.rs b/src/test/compile-fail/feature-gate/issue-43106-gating-of-unstable.rs
new file mode 100644
index 00000000000..0708dc8f728
--- /dev/null
+++ b/src/test/compile-fail/feature-gate/issue-43106-gating-of-unstable.rs
@@ -0,0 +1,38 @@
+// Copyright 2017 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.
+
+// Testing gating of `#[unstable]` in "weird" places.
+//
+// This file sits on its own because these signal errors, making
+// this test incompatible with the "warnings only" nature of
+// issue-43106-gating-of-builtin-attrs.rs
+
+#![unstable                   = "1200"]
+//~^ ERROR stability attributes may not be used outside of the standard library
+
+#[unstable = "1200"]
+//~^ ERROR stability attributes may not be used outside of the standard library
+mod unstable {
+    mod inner { #![unstable="1200"] }
+    //~^ ERROR stability attributes may not be used outside of the standard library
+
+    #[unstable = "1200"] fn f() { }
+    //~^ ERROR stability attributes may not be used outside of the standard library
+
+    #[unstable = "1200"] struct S;
+    //~^ ERROR stability attributes may not be used outside of the standard library
+    //~| ERROR stability attributes may not be used outside of the standard library
+
+    #[unstable = "1200"] type T = S;
+    //~^ ERROR stability attributes may not be used outside of the standard library
+
+    #[unstable = "1200"] impl S { }
+    //~^ ERROR stability attributes may not be used outside of the standard library
+}