diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index 502b1c0f74371..e949398f074fc 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -414,14 +414,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } - ast::ItemKind::Impl(_, polarity, defaultness, ..) => { - if polarity == ast::ImplPolarity::Negative { - gate_feature_post!(&self, optin_builtin_traits, - i.span, - "negative trait bounds are not yet fully implemented; \ - use marker types for now"); - } - + ast::ItemKind::Impl(_, _, defaultness, ..) => { if let ast::Defaultness::Default = defaultness { gate_feature_post!(&self, specialization, i.span, @@ -429,12 +422,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } - ast::ItemKind::Trait(ast::IsAuto::Yes, ..) => { - gate_feature_post!(&self, optin_builtin_traits, - i.span, - "auto traits are experimental and possibly buggy"); - } - ast::ItemKind::OpaqueTy(..) => { gate_feature_post!( &self, @@ -464,11 +451,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { "linking to LLVM intrinsics is experimental"); } } - ast::ForeignItemKind::Ty => { - gate_feature_post!(&self, extern_types, i.span, - "extern types are experimental"); - } - ast::ForeignItemKind::Macro(..) => {} + _ => {} } visit::walk_foreign_item(self, i) @@ -789,7 +772,11 @@ pub fn check_crate(krate: &ast::Crate, gate_all!(try_blocks, "`try` blocks are unstable"); gate_all!(label_break_value, "labels on blocks are unstable"); gate_all!(box_syntax, "box expression syntax is experimental; you can call `Box::new` instead"); - + gate_all!(auto_traits, optin_builtin_traits, "auto traits are experimental and possibly buggy"); + gate_all!( + negative_impls, optin_builtin_traits, + "negative trait bounds are not yet fully implemented; use marker types for now" + ); // To avoid noise about type ascription in common syntax errors, // only emit if it is the *only* error. (Also check it last.) if parse_sess.span_diagnostic.err_count() == 0 { diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs index 95bddb5afdd08..4b11beb32f9f0 100644 --- a/src/libsyntax/parse/parser/item.rs +++ b/src/libsyntax/parse/parser/item.rs @@ -588,6 +588,7 @@ impl<'a> Parser<'a> { // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type. let polarity = if self.check(&token::Not) && self.look_ahead(1, |t| t.can_begin_type()) { self.bump(); // `!` + self.sess.gated_spans.negative_impls.borrow_mut().push(self.prev_span); ast::ImplPolarity::Negative } else { ast::ImplPolarity::Positive @@ -865,6 +866,11 @@ impl<'a> Parser<'a> { } } } + + if is_auto == IsAuto::Yes { + self.sess.gated_spans.auto_traits.borrow_mut().push(lo.to(self.prev_span)); + } + Ok((ident, ItemKind::Trait(is_auto, unsafety, tps, bounds, trait_items), None)) } } @@ -1235,6 +1241,7 @@ impl<'a> Parser<'a> { let ident = self.parse_ident()?; let hi = self.token.span; self.expect(&token::Semi)?; + self.sess.gated_spans.extern_types.borrow_mut().push(lo.to(self.prev_span)); Ok(ast::ForeignItem { ident, attrs, diff --git a/src/libsyntax/sess.rs b/src/libsyntax/sess.rs index 28a0868d5dd1e..203e57b262ed4 100644 --- a/src/libsyntax/sess.rs +++ b/src/libsyntax/sess.rs @@ -52,6 +52,12 @@ crate struct GatedSpans { pub box_syntax: Lock>, /// Spans collected for gating `type_ascription`, e.g. `42: usize`. pub type_ascription: Lock>, + /// Spans collected for gating `optin_builtin_traits`, e.g. `auto trait Foo {}`. + pub auto_traits: Lock>, + /// Spans collected for gating `optin_builtin_traits`, e.g. `impl !Trait for Type {}`. + pub negative_impls: Lock>, + /// Spans collected for gating `extern_types`, e.g. `extern type Foo;`. + pub extern_types: Lock>, } /// Info about a parsing session. diff --git a/src/test/ui/feature-gates/feature-gate-extern_types.rs b/src/test/ui/feature-gates/feature-gate-extern_types.rs index 6bdc96f55d6a5..b4b78f7172ad7 100644 --- a/src/test/ui/feature-gates/feature-gate-extern_types.rs +++ b/src/test/ui/feature-gates/feature-gate-extern_types.rs @@ -1,3 +1,4 @@ +#[cfg(FALSE)] extern { type T; //~ ERROR extern types are experimental } diff --git a/src/test/ui/feature-gates/feature-gate-extern_types.stderr b/src/test/ui/feature-gates/feature-gate-extern_types.stderr index f82c64f9ca66b..b2c1b897c1974 100644 --- a/src/test/ui/feature-gates/feature-gate-extern_types.stderr +++ b/src/test/ui/feature-gates/feature-gate-extern_types.stderr @@ -1,5 +1,5 @@ error[E0658]: extern types are experimental - --> $DIR/feature-gate-extern_types.rs:2:5 + --> $DIR/feature-gate-extern_types.rs:3:5 | LL | type T; | ^^^^^^^ diff --git a/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.rs b/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.rs index 35c05b75d365c..ed97a5942b1c4 100644 --- a/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.rs +++ b/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.rs @@ -9,4 +9,13 @@ auto trait AutoDummyTrait {} impl !AutoDummyTrait for DummyStruct {} //~^ ERROR negative trait bounds are not yet fully implemented; use marker types for now +macro_rules! accept_item { ($i:item) => {} } +accept_item! { + auto trait Auto {} + //~^ ERROR auto traits are experimental and possibly buggy +} +accept_item! { + impl !AutoDummyTrait for DummyStruct {} + //~^ ERROR negative trait bounds are not yet fully implemented; use marker types for now +} fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.stderr b/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.stderr index 0c3dd451b2723..7af8450a78b98 100644 --- a/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.stderr +++ b/src/test/ui/feature-gates/feature-gate-optin-builtin-traits.stderr @@ -7,15 +7,33 @@ LL | auto trait AutoDummyTrait {} = note: for more information, see https://github.com/rust-lang/rust/issues/13231 = help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable +error[E0658]: auto traits are experimental and possibly buggy + --> $DIR/feature-gate-optin-builtin-traits.rs:14:5 + | +LL | auto trait Auto {} + | ^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/13231 + = help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable + error[E0658]: negative trait bounds are not yet fully implemented; use marker types for now - --> $DIR/feature-gate-optin-builtin-traits.rs:9:1 + --> $DIR/feature-gate-optin-builtin-traits.rs:9:6 | LL | impl !AutoDummyTrait for DummyStruct {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/13231 + = help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable + +error[E0658]: negative trait bounds are not yet fully implemented; use marker types for now + --> $DIR/feature-gate-optin-builtin-traits.rs:18:10 + | +LL | impl !AutoDummyTrait for DummyStruct {} + | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/13231 = help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/syntax-trait-polarity-feature-gate.stderr b/src/test/ui/syntax-trait-polarity-feature-gate.stderr index c546bc4ef7e0a..b77b5ab6789c7 100644 --- a/src/test/ui/syntax-trait-polarity-feature-gate.stderr +++ b/src/test/ui/syntax-trait-polarity-feature-gate.stderr @@ -1,8 +1,8 @@ error[E0658]: negative trait bounds are not yet fully implemented; use marker types for now - --> $DIR/syntax-trait-polarity-feature-gate.rs:7:1 + --> $DIR/syntax-trait-polarity-feature-gate.rs:7:6 | LL | impl !Send for TestType {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ | = note: for more information, see https://github.com/rust-lang/rust/issues/13231 = help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable diff --git a/src/test/ui/traits/trait-alias/trait-alias-syntax-fail.stderr b/src/test/ui/traits/trait-alias/trait-alias-syntax-fail.stderr index 18c22133bc780..b1516cd7b1643 100644 --- a/src/test/ui/traits/trait-alias/trait-alias-syntax-fail.stderr +++ b/src/test/ui/traits/trait-alias/trait-alias-syntax-fail.stderr @@ -23,4 +23,3 @@ LL | trait D: = Eq; | ^ error: aborting due to 4 previous errors -