diff --git a/src/doc/unstable-book/src/language-features/negative-impls.md b/src/doc/unstable-book/src/language-features/negative-impls.md new file mode 100644 index 00000000000..3cf9351b630 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/negative-impls.md @@ -0,0 +1,57 @@ +# `negative_impls` + +The tracking issue for this feature is [#13231] + +[#13231]: https://github.com/rust-lang/rust/issues/13231 + +---- + +With the feature gate `negative_impls`, you can write negative impls as well as positive ones: + +```rust +#![feature(negative_impls)] +trait DerefMut { } +impl !DerefMut for &T { } +``` + +Negative impls indicate a semver guarantee that the given trait will not be implemented for the given types. Negative impls play an additional purpose for auto traits, described below. + +Negative impls have the following characteristics: + +* They do not have any items. +* They must obey the orphan rules as if they were a positive impl. +* They cannot "overlap" with any positive impls. + +## Semver interaction + +It is a breaking change to remove a negative impl. Negative impls are a commitment not to implement the given trait for the named types. + +## Orphan and overlap rules + +Negative impls must obey the same orphan rules as a positive impl. This implies you cannot add a negative impl for types defined in upstream crates and so forth. + +Similarly, negative impls cannot overlap with positive impls, again using the same "overlap" check that we ordinarily use to determine if two impls overlap. (Note that positive impls typically cannot overlap with one another either, except as permitted by specialization.) + +## Interaction with auto traits + +Declaring a negative impl `impl !SomeAutoTrait for SomeType` for an +auto-trait serves two purposes: + +* as with any trait, it declares that `SomeType` will never implement `SomeAutoTrait`; +* it disables the automatic `SomeType: SomeAutoTrait` impl that would otherwise have been generated. + +Note that, at present, there is no way to indicate that a given type +does not implement an auto trait *but that it may do so in the +future*. For ordinary types, this is done by simply not declaring any +impl at all, but that is not an option for auto traits. A workaround +is that one could embed a marker type as one of the fields, where the +marker type is `!AutoTrait`. + +## Immediate uses + +Negative impls are used to declare that `&T: !DerefMut` and `&mut T: !Clone`, as required to fix the soundness of `Pin` described in [#66544](https://github.com/rust-lang/rust/issues/66544). + +This serves two purposes: + +* For proving the correctness of unsafe code, we can use that impl as evidence that no `DerefMut` or `Clone` impl exists. +* It prevents downstream crates from creating such impls. diff --git a/src/doc/unstable-book/src/language-features/optin-builtin-traits.md b/src/doc/unstable-book/src/language-features/optin-builtin-traits.md index 1ec8b8bf8dd..6f0f0cfd33e 100644 --- a/src/doc/unstable-book/src/language-features/optin-builtin-traits.md +++ b/src/doc/unstable-book/src/language-features/optin-builtin-traits.md @@ -10,7 +10,8 @@ The `optin_builtin_traits` feature gate allows you to define auto traits. Auto traits, like [`Send`] or [`Sync`] in the standard library, are marker traits that are automatically implemented for every type, unless the type, or a type it contains, -has explicitly opted out via a negative impl. +has explicitly opted out via a negative impl. (Negative impls are separately controlled +by the `negative_impls` feature.) [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html @@ -22,6 +23,7 @@ impl !Trait for Type Example: ```rust +#![feature(negative_impls)] #![feature(optin_builtin_traits)] auto trait Valid {} @@ -43,3 +45,63 @@ fn main() { // must_be_valid( MaybeValid(False) ); } ``` + +## Automatic trait implementations + +When a type is declared as an `auto trait`, we will automatically +create impls for every struct/enum/union, unless an explicit impl is +provided. These automatic impls contain a where clause for each field +of the form `T: AutoTrait`, where `T` is the type of the field and +`AutoTrait` is the auto trait in question. As an example, consider the +struct `List` and the auto trait `Send`: + +```rust +struct List { + data: T, + next: Option>>, +} +``` + +Presuming that there is no explicit impl of `Send` for `List`, the +compiler will supply an automatic impl of the form: + +```rust +struct List { + data: T, + next: Option>>, +} + +unsafe impl Send for List +where + T: Send, // from the field `data` + Option>>: Send, // from the field `next` +{ } +``` + +Explicit impls may be either positive or negative. They take the form: + +```rust,ignore +impl<...> AutoTrait for StructName<..> { } +impl<...> !AutoTrait for StructName<..> { } +``` + +## Coinduction: Auto traits permit cyclic matching + +Unlike ordinary trait matching, auto traits are **coinductive**. This +means, in short, that cycles which occur in trait matching are +considered ok. As an example, consider the recursive struct `List` +introduced in the previous section. In attempting to determine whether +`List: Send`, we would wind up in a cycle: to apply the impl, we must +show that `Option>: Send`, which will in turn require +`Box: Send` and then finally `List: Send` again. Under ordinary +trait matching, this cycle would be an error, but for an auto trait it +is considered a successful match. + +## Items + +Auto traits cannot have any trait items, such as methods or associated types. This ensures that we can generate default implementations. + +## Supertraits + +Auto traits cannot have supertraits. This is for soundness reasons, as the interaction of coinduction with implied bounds is difficult to reconcile. + diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index d55a1a3b635..5857b79d5ee 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -99,6 +99,7 @@ #![feature(internal_uninit_const)] #![feature(lang_items)] #![feature(libc)] +#![cfg_attr(not(bootstrap), feature(negative_impls))] #![feature(nll)] #![feature(optin_builtin_traits)] #![feature(pattern)] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 94fc2fd357a..0bee16f98bd 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -98,6 +98,7 @@ #![feature(is_sorted)] #![feature(lang_items)] #![feature(link_llvm_intrinsics)] +#![cfg_attr(not(bootstrap), feature(negative_impls))] #![feature(never_type)] #![feature(nll)] #![feature(exhaustive_patterns)] diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 8f16e3c08ec..a975ce93bb1 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -24,6 +24,7 @@ #![feature(decl_macro)] #![feature(extern_types)] #![feature(in_band_lifetimes)] +#![cfg_attr(not(bootstrap), feature(negative_impls))] #![feature(optin_builtin_traits)] #![feature(rustc_attrs)] #![cfg_attr(bootstrap, feature(specialization))] diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 5cd7b58e14e..a0d7b064d0c 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -286,8 +286,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { start, i.span, "`#[start]` functions are experimental \ - and their signature may change \ - over time" + and their signature may change \ + over time" ); } if attr::contains_name(&i.attrs[..], sym::main) { @@ -296,8 +296,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { main, i.span, "declaration of a non-standard `#[main]` \ - function may change over time, for now \ - a top-level `fn main()` is required" + function may change over time, for now \ + a top-level `fn main()` is required" ); } } @@ -341,7 +341,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { if let ast::ImplPolarity::Negative(span) = polarity { gate_feature_post!( &self, - optin_builtin_traits, + negative_impls, span.to(of_trait.as_ref().map(|t| t.path.span).unwrap_or(span)), "negative trait bounds are not yet fully implemented; \ use marker types for now" diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index a21314afb1e..6157c46f80c 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -802,13 +802,13 @@ impl HandlerInner { )); self.failure(&format!( "For more information about an error, try \ - `rustc --explain {}`.", + `rustc --explain {}`.", &error_codes[0] )); } else { self.failure(&format!( "For more information about this error, try \ - `rustc --explain {}`.", + `rustc --explain {}`.", &error_codes[0] )); } diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 9f1fee8fc09..293f86d4597 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -152,6 +152,9 @@ declare_features! ( /// Allows features specific to OIBIT (auto traits). (active, optin_builtin_traits, "1.0.0", Some(13231), None), + /// Allow negative trait implementations. + (active, negative_impls, "1.0.0", Some(13231), None), + /// Allows using `box` in patterns (RFC 469). (active, box_patterns, "1.0.0", Some(29641), None), diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs index 3ebcef947bc..7a1aea15753 100644 --- a/src/librustc_span/lib.rs +++ b/src/librustc_span/lib.rs @@ -9,6 +9,7 @@ #![feature(const_if_match)] #![feature(const_fn)] #![feature(const_panic)] +#![cfg_attr(not(bootstrap), feature(negative_impls))] #![feature(nll)] #![feature(optin_builtin_traits)] #![feature(specialization)] @@ -305,7 +306,11 @@ impl Span { /// Returns `self` if `self` is not the dummy span, and `other` otherwise. pub fn substitute_dummy(self, other: Span) -> Span { - if self.is_dummy() { other } else { self } + if self.is_dummy() { + other + } else { + self + } } /// Returns `true` if `self` fully encloses `other`. @@ -336,21 +341,33 @@ impl Span { pub fn trim_start(self, other: Span) -> Option { let span = self.data(); let other = other.data(); - if span.hi > other.hi { Some(span.with_lo(cmp::max(span.lo, other.hi))) } else { None } + if span.hi > other.hi { + Some(span.with_lo(cmp::max(span.lo, other.hi))) + } else { + None + } } /// Returns the source span -- this is either the supplied span, or the span for /// the macro callsite that expanded to it. pub fn source_callsite(self) -> Span { let expn_data = self.ctxt().outer_expn_data(); - if !expn_data.is_root() { expn_data.call_site.source_callsite() } else { self } + if !expn_data.is_root() { + expn_data.call_site.source_callsite() + } else { + self + } } /// The `Span` for the tokens in the previous macro expansion from which `self` was generated, /// if any. pub fn parent(self) -> Option { let expn_data = self.ctxt().outer_expn_data(); - if !expn_data.is_root() { Some(expn_data.call_site) } else { None } + if !expn_data.is_root() { + Some(expn_data.call_site) + } else { + None + } } /// Edition of the crate from which this span came. @@ -376,10 +393,18 @@ impl Span { pub fn source_callee(self) -> Option { fn source_callee(expn_data: ExpnData) -> ExpnData { let next_expn_data = expn_data.call_site.ctxt().outer_expn_data(); - if !next_expn_data.is_root() { source_callee(next_expn_data) } else { expn_data } + if !next_expn_data.is_root() { + source_callee(next_expn_data) + } else { + expn_data + } } let expn_data = self.ctxt().outer_expn_data(); - if !expn_data.is_root() { Some(source_callee(expn_data)) } else { None } + if !expn_data.is_root() { + Some(source_callee(expn_data)) + } else { + None + } } /// Checks if a span is "internal" to a macro in which `#[unstable]` @@ -1199,7 +1224,11 @@ impl SourceFile { let line_index = lookup_line(&self.lines[..], pos); assert!(line_index < self.lines.len() as isize); - if line_index >= 0 { Some(line_index as usize) } else { None } + if line_index >= 0 { + Some(line_index as usize) + } else { + None + } } pub fn line_bounds(&self, line_index: usize) -> (BytePos, BytePos) { diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index dcb4e849a75..bb41629ef09 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -473,6 +473,7 @@ symbols! { needs_drop, needs_panic_runtime, negate_unsigned, + negative_impls, never, never_type, never_type_fallback, diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index e5dad307a20..d4110527054 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -278,6 +278,7 @@ #![feature(maybe_uninit_ref)] #![feature(maybe_uninit_slice)] #![feature(needs_panic_runtime)] +#![cfg_attr(not(bootstrap), feature(negative_impls))] #![feature(never_type)] #![feature(nll)] #![feature(optin_builtin_traits)] diff --git a/src/test/pretty/trait-polarity.rs b/src/test/pretty/trait-polarity.rs index 3aab99bf6a0..df1a7946afb 100644 --- a/src/test/pretty/trait-polarity.rs +++ b/src/test/pretty/trait-polarity.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] // pp-exact diff --git a/src/test/rustdoc/empty-section.rs b/src/test/rustdoc/empty-section.rs index d95f3a80365..665aa38b11e 100644 --- a/src/test/rustdoc/empty-section.rs +++ b/src/test/rustdoc/empty-section.rs @@ -1,6 +1,6 @@ #![crate_name = "foo"] -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] pub struct Foo; diff --git a/src/test/rustdoc/impl-parts-crosscrate.rs b/src/test/rustdoc/impl-parts-crosscrate.rs index f9583d1a722..a68db9c70ad 100644 --- a/src/test/rustdoc/impl-parts-crosscrate.rs +++ b/src/test/rustdoc/impl-parts-crosscrate.rs @@ -1,7 +1,7 @@ // aux-build:rustdoc-impl-parts-crosscrate.rs // ignore-cross-compile -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] extern crate rustdoc_impl_parts_crosscrate; diff --git a/src/test/rustdoc/impl-parts.rs b/src/test/rustdoc/impl-parts.rs index fbb4e725481..68baca9a04e 100644 --- a/src/test/rustdoc/impl-parts.rs +++ b/src/test/rustdoc/impl-parts.rs @@ -1,3 +1,4 @@ +#![feature(negative_impls)] #![feature(optin_builtin_traits)] pub auto trait AnOibit {} diff --git a/src/test/rustdoc/issue-55321.rs b/src/test/rustdoc/issue-55321.rs index 257cb32c65c..8c001db06c5 100644 --- a/src/test/rustdoc/issue-55321.rs +++ b/src/test/rustdoc/issue-55321.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] // @has issue_55321/struct.A.html // @has - '//*[@id="implementations-list"]/*[@class="impl"]//code' "impl !Send for A" diff --git a/src/test/rustdoc/negative-impl-sidebar.rs b/src/test/rustdoc/negative-impl-sidebar.rs index 838ca0402e4..cb46d1778d9 100644 --- a/src/test/rustdoc/negative-impl-sidebar.rs +++ b/src/test/rustdoc/negative-impl-sidebar.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] #![crate_name = "foo"] pub struct Foo; diff --git a/src/test/rustdoc/negative-impl.rs b/src/test/rustdoc/negative-impl.rs index 8ac87f4f0cb..d76aac6906c 100644 --- a/src/test/rustdoc/negative-impl.rs +++ b/src/test/rustdoc/negative-impl.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] // @matches negative_impl/struct.Alpha.html '//pre' "pub struct Alpha" pub struct Alpha; diff --git a/src/test/ui/async-await/issue-64130-1-sync.rs b/src/test/ui/async-await/issue-64130-1-sync.rs index cc5ca89f03a..af83f14bbda 100644 --- a/src/test/ui/async-await/issue-64130-1-sync.rs +++ b/src/test/ui/async-await/issue-64130-1-sync.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] // edition:2018 // This tests the the specialized async-await-specific error when futures don't implement an diff --git a/src/test/ui/async-await/issue-64130-2-send.rs b/src/test/ui/async-await/issue-64130-2-send.rs index 1efe2ab3f85..2362831d8b8 100644 --- a/src/test/ui/async-await/issue-64130-2-send.rs +++ b/src/test/ui/async-await/issue-64130-2-send.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] // edition:2018 // This tests the the specialized async-await-specific error when futures don't implement an diff --git a/src/test/ui/async-await/issue-64130-3-other.rs b/src/test/ui/async-await/issue-64130-3-other.rs index 901544edba1..b819970d59d 100644 --- a/src/test/ui/async-await/issue-64130-3-other.rs +++ b/src/test/ui/async-await/issue-64130-3-other.rs @@ -1,4 +1,5 @@ #![feature(optin_builtin_traits)] +#![feature(negative_impls)] // edition:2018 // This tests the the unspecialized async-await-specific error when futures don't implement an diff --git a/src/test/ui/async-await/issue-64130-3-other.stderr b/src/test/ui/async-await/issue-64130-3-other.stderr index d6828172928..6456e7abd74 100644 --- a/src/test/ui/async-await/issue-64130-3-other.stderr +++ b/src/test/ui/async-await/issue-64130-3-other.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `Foo: Qux` is not satisfied in `impl std::future::Future` - --> $DIR/issue-64130-3-other.rs:23:5 + --> $DIR/issue-64130-3-other.rs:24:5 | LL | fn is_qux(t: T) { } | ------ --- required by this bound in `is_qux` @@ -13,7 +13,7 @@ LL | is_qux(bar()); = help: the following implementations were found: note: future does not implement `Qux` as this value is used across an await - --> $DIR/issue-64130-3-other.rs:17:5 + --> $DIR/issue-64130-3-other.rs:18:5 | LL | let x = Foo; | - has type `Foo` diff --git a/src/test/ui/codemap_tests/empty_span.rs b/src/test/ui/codemap_tests/empty_span.rs index 4d52b391280..7753e2eceb5 100644 --- a/src/test/ui/codemap_tests/empty_span.rs +++ b/src/test/ui/codemap_tests/empty_span.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] fn main() { struct Foo; diff --git a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs index 0fabb5ec91d..24b87892753 100644 --- a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs +++ b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] #![feature(marker_trait_attr)] #[marker] diff --git a/src/test/ui/coherence/coherence-default-trait-impl.rs b/src/test/ui/coherence/coherence-default-trait-impl.rs index db24662e2d5..4115ba34e17 100644 --- a/src/test/ui/coherence/coherence-default-trait-impl.rs +++ b/src/test/ui/coherence/coherence-default-trait-impl.rs @@ -1,4 +1,5 @@ #![feature(optin_builtin_traits)] +#![feature(negative_impls)] auto trait MySafeTrait {} diff --git a/src/test/ui/coherence/coherence-default-trait-impl.stderr b/src/test/ui/coherence/coherence-default-trait-impl.stderr index f6a163268a1..b08ccb087d9 100644 --- a/src/test/ui/coherence/coherence-default-trait-impl.stderr +++ b/src/test/ui/coherence/coherence-default-trait-impl.stderr @@ -1,11 +1,11 @@ error[E0199]: implementing the trait `MySafeTrait` is not unsafe - --> $DIR/coherence-default-trait-impl.rs:7:1 + --> $DIR/coherence-default-trait-impl.rs:8:1 | LL | unsafe impl MySafeTrait for Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0200]: the trait `MyUnsafeTrait` requires an `unsafe impl` declaration - --> $DIR/coherence-default-trait-impl.rs:12:1 + --> $DIR/coherence-default-trait-impl.rs:13:1 | LL | impl MyUnsafeTrait for Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs index 5ea69190951..a9c8d20a79d 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs @@ -1,4 +1,5 @@ #![feature(optin_builtin_traits)] +#![feature(negative_impls)] // Test for issue #56934 - that it is impossible to redundantly // implement an auto-trait for a trait object type that contains it. diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr index b8137b36948..23db5328a72 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr @@ -1,17 +1,17 @@ error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1` - --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:14:1 + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1 | LL | impl !Marker1 for dyn Object + Marker2 { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1` error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2` - --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:16:1 + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:17:1 | LL | impl !Marker2 for dyn Object + Marker2 { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2` error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:22:1 + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:23:1 | LL | impl !Send for dyn Marker2 {} | ^^^^^^^^^^^^^^^----------- @@ -22,13 +22,13 @@ LL | impl !Send for dyn Marker2 {} = note: define and implement a trait or new type instead error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)` - --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:26:1 + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:27:1 | LL | impl !Send for dyn Object {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker2 + 'static)` - --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:27:1 + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:28:1 | LL | impl !Send for dyn Object + Marker2 {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs index 6b5689e8260..c565f9c83e8 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs @@ -1,4 +1,5 @@ #![feature(optin_builtin_traits)] +#![feature(negative_impls)] // Test for issue #56934 - that it is impossible to redundantly // implement an auto-trait for a trait object type that contains it. diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr index d68337bed00..141ab7771f3 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr @@ -1,17 +1,17 @@ error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1` - --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:14:1 + --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:15:1 | LL | impl Marker1 for dyn Object + Marker2 { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1` error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2` - --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:16:1 + --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:17:1 | LL | impl Marker2 for dyn Object + Marker2 { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2` error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:22:1 + --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:23:1 | LL | unsafe impl Send for dyn Marker2 {} | ^^^^^^^^^^^^^^^^^^^^^----------- @@ -22,13 +22,13 @@ LL | unsafe impl Send for dyn Marker2 {} = note: define and implement a trait or new type instead error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)` - --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:26:1 + --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:27:1 | LL | unsafe impl Send for dyn Object {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker2 + 'static)` - --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:27:1 + --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:28:1 | LL | unsafe impl Send for dyn Object + Marker2 {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type diff --git a/src/test/ui/coherence/coherence-impls-copy.rs b/src/test/ui/coherence/coherence-impls-copy.rs index dec40f9dd40..a86ca0e5eac 100644 --- a/src/test/ui/coherence/coherence-impls-copy.rs +++ b/src/test/ui/coherence/coherence-impls-copy.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] use std::marker::Copy; diff --git a/src/test/ui/coherence/coherence-impls-send.rs b/src/test/ui/coherence/coherence-impls-send.rs index 7898dc9831d..e00cb9a7c5b 100644 --- a/src/test/ui/coherence/coherence-impls-send.rs +++ b/src/test/ui/coherence/coherence-impls-send.rs @@ -1,9 +1,9 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] use std::marker::Copy; enum TestE { - A + A, } struct MyType; @@ -26,5 +26,4 @@ unsafe impl Send for &'static [NotSync] {} //~^ ERROR conflicting implementations of trait //~| ERROR only traits defined in the current crate -fn main() { -} +fn main() {} diff --git a/src/test/ui/coherence/coherence-impls-sized.rs b/src/test/ui/coherence/coherence-impls-sized.rs index 19e7349c507..231b96ad42e 100644 --- a/src/test/ui/coherence/coherence-impls-sized.rs +++ b/src/test/ui/coherence/coherence-impls-sized.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] use std::marker::Copy; diff --git a/src/test/ui/coherence/coherence-negative-impls-safe-rpass.rs b/src/test/ui/coherence/coherence-negative-impls-safe-rpass.rs index 695a71cbd2d..b87e162aca0 100644 --- a/src/test/ui/coherence/coherence-negative-impls-safe-rpass.rs +++ b/src/test/ui/coherence/coherence-negative-impls-safe-rpass.rs @@ -2,7 +2,7 @@ #![allow(dead_code)] // pretty-expanded FIXME #23616 -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] use std::marker::Send; diff --git a/src/test/ui/coherence/coherence-negative-impls-safe.rs b/src/test/ui/coherence/coherence-negative-impls-safe.rs index 45c478ecc03..4821aa6b5ad 100644 --- a/src/test/ui/coherence/coherence-negative-impls-safe.rs +++ b/src/test/ui/coherence/coherence-negative-impls-safe.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] use std::marker::Send; diff --git a/src/test/ui/coherence/coherence-orphan.rs b/src/test/ui/coherence/coherence-orphan.rs index a7b48825d7c..3beac04c7e8 100644 --- a/src/test/ui/coherence/coherence-orphan.rs +++ b/src/test/ui/coherence/coherence-orphan.rs @@ -1,5 +1,5 @@ // aux-build:coherence_orphan_lib.rs -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] extern crate coherence_orphan_lib as lib; diff --git a/src/test/ui/error-codes/E0198.rs b/src/test/ui/error-codes/E0198.rs index 00ab0c35623..041bbe8fdcf 100644 --- a/src/test/ui/error-codes/E0198.rs +++ b/src/test/ui/error-codes/E0198.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] struct Foo; diff --git a/src/test/ui/error-codes/E0199.rs b/src/test/ui/error-codes/E0199.rs index c95afa3f97d..2421bf0a55f 100644 --- a/src/test/ui/error-codes/E0199.rs +++ b/src/test/ui/error-codes/E0199.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] struct Foo; diff --git a/src/test/ui/feature-gate-negative_impls.rs b/src/test/ui/feature-gate-negative_impls.rs new file mode 100644 index 00000000000..683fd6db6f2 --- /dev/null +++ b/src/test/ui/feature-gate-negative_impls.rs @@ -0,0 +1,3 @@ +trait MyTrait {} +impl !MyTrait for u32 {} //~ ERROR negative trait bounds are not yet fully implemented +fn main() {} diff --git a/src/test/ui/feature-gate-negative_impls.stderr b/src/test/ui/feature-gate-negative_impls.stderr new file mode 100644 index 00000000000..922048996bd --- /dev/null +++ b/src/test/ui/feature-gate-negative_impls.stderr @@ -0,0 +1,12 @@ +error[E0658]: negative trait bounds are not yet fully implemented; use marker types for now + --> $DIR/feature-gate-negative_impls.rs:2:6 + | +LL | impl !MyTrait for u32 {} + | ^^^^^^^^ + | + = note: see issue #13231 for more information + = help: add `#![feature(negative_impls)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. 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 490d29ad8a3..e9090b78c78 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 @@ -14,7 +14,7 @@ LL | impl !AutoDummyTrait for DummyStruct {} | ^^^^^^^^^^^^^^^ | = note: see issue #13231 for more information - = help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable + = help: add `#![feature(negative_impls)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/ui/generator/auto-trait-regions.nll.stderr b/src/test/ui/generator/auto-trait-regions.nll.stderr index bf87aea0d4c..794369a8dc0 100644 --- a/src/test/ui/generator/auto-trait-regions.nll.stderr +++ b/src/test/ui/generator/auto-trait-regions.nll.stderr @@ -1,5 +1,5 @@ error[E0716]: temporary value dropped while borrowed - --> $DIR/auto-trait-regions.rs:45:24 + --> $DIR/auto-trait-regions.rs:46:24 | LL | let a = A(&mut true, &mut true, No); | ^^^^ - temporary value is freed at the end of this statement @@ -12,7 +12,7 @@ LL | assert_foo(a); = note: consider using a `let` binding to create a longer lived value error[E0716]: temporary value dropped while borrowed - --> $DIR/auto-trait-regions.rs:45:35 + --> $DIR/auto-trait-regions.rs:46:35 | LL | let a = A(&mut true, &mut true, No); | ^^^^ - temporary value is freed at the end of this statement @@ -25,13 +25,13 @@ LL | assert_foo(a); = note: consider using a `let` binding to create a longer lived value error: higher-ranked subtype error - --> $DIR/auto-trait-regions.rs:30:5 + --> $DIR/auto-trait-regions.rs:31:5 | LL | assert_foo(gen); | ^^^^^^^^^^^^^^^ error: higher-ranked subtype error - --> $DIR/auto-trait-regions.rs:49:5 + --> $DIR/auto-trait-regions.rs:50:5 | LL | assert_foo(gen); | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/generator/auto-trait-regions.rs b/src/test/ui/generator/auto-trait-regions.rs index dbd8965dcf0..1e77d8058a7 100644 --- a/src/test/ui/generator/auto-trait-regions.rs +++ b/src/test/ui/generator/auto-trait-regions.rs @@ -1,5 +1,6 @@ #![feature(generators)] #![feature(optin_builtin_traits)] +#![feature(negative_impls)] auto trait Foo {} diff --git a/src/test/ui/generator/auto-trait-regions.stderr b/src/test/ui/generator/auto-trait-regions.stderr index 29a3907d93c..5ec462e1046 100644 --- a/src/test/ui/generator/auto-trait-regions.stderr +++ b/src/test/ui/generator/auto-trait-regions.stderr @@ -1,5 +1,5 @@ error: implementation of `Foo` is not general enough - --> $DIR/auto-trait-regions.rs:30:5 + --> $DIR/auto-trait-regions.rs:31:5 | LL | auto trait Foo {} | ----------------- trait `Foo` defined here @@ -11,7 +11,7 @@ LL | assert_foo(gen); = note: ...but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1` error: implementation of `Foo` is not general enough - --> $DIR/auto-trait-regions.rs:30:5 + --> $DIR/auto-trait-regions.rs:31:5 | LL | auto trait Foo {} | ----------------- trait `Foo` defined here @@ -23,7 +23,7 @@ LL | assert_foo(gen); = note: ...but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1` error: implementation of `Foo` is not general enough - --> $DIR/auto-trait-regions.rs:49:5 + --> $DIR/auto-trait-regions.rs:50:5 | LL | auto trait Foo {} | ----------------- trait `Foo` defined here @@ -35,7 +35,7 @@ LL | assert_foo(gen); = note: ...but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2` error: implementation of `Foo` is not general enough - --> $DIR/auto-trait-regions.rs:49:5 + --> $DIR/auto-trait-regions.rs:50:5 | LL | auto trait Foo {} | ----------------- trait `Foo` defined here diff --git a/src/test/ui/issues/issue-17718-static-sync.rs b/src/test/ui/issues/issue-17718-static-sync.rs index dccbde6a3c5..6f278d76bb1 100644 --- a/src/test/ui/issues/issue-17718-static-sync.rs +++ b/src/test/ui/issues/issue-17718-static-sync.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] use std::marker::Sync; diff --git a/src/test/ui/issues/issue-23080-2.rs b/src/test/ui/issues/issue-23080-2.rs index d20bb4bd907..7f6b9e3fba7 100644 --- a/src/test/ui/issues/issue-23080-2.rs +++ b/src/test/ui/issues/issue-23080-2.rs @@ -1,6 +1,7 @@ //~ ERROR #![feature(optin_builtin_traits)] +#![feature(negative_impls)] unsafe auto trait Trait { type Output; //~ ERROR E0380 diff --git a/src/test/ui/issues/issue-23080-2.stderr b/src/test/ui/issues/issue-23080-2.stderr index fcd1ecfa982..48ce09aaa34 100644 --- a/src/test/ui/issues/issue-23080-2.stderr +++ b/src/test/ui/issues/issue-23080-2.stderr @@ -1,5 +1,5 @@ error[E0380]: auto traits cannot have methods or associated items - --> $DIR/issue-23080-2.rs:6:10 + --> $DIR/issue-23080-2.rs:7:10 | LL | unsafe auto trait Trait { | ----- auto trait cannot have items diff --git a/src/test/ui/issues/issue-23080.rs b/src/test/ui/issues/issue-23080.rs index fa5c35316bc..035db82ba5d 100644 --- a/src/test/ui/issues/issue-23080.rs +++ b/src/test/ui/issues/issue-23080.rs @@ -1,4 +1,5 @@ #![feature(optin_builtin_traits)] +#![feature(negative_impls)] unsafe auto trait Trait { fn method(&self) { //~ ERROR E0380 diff --git a/src/test/ui/issues/issue-23080.stderr b/src/test/ui/issues/issue-23080.stderr index dbb9861b578..73ecb1c362e 100644 --- a/src/test/ui/issues/issue-23080.stderr +++ b/src/test/ui/issues/issue-23080.stderr @@ -1,5 +1,5 @@ error[E0380]: auto traits cannot have methods or associated items - --> $DIR/issue-23080.rs:4:8 + --> $DIR/issue-23080.rs:5:8 | LL | unsafe auto trait Trait { | ----- auto trait cannot have items diff --git a/src/test/ui/issues/issue-29516.rs b/src/test/ui/issues/issue-29516.rs index d43367e3452..035f904b15b 100644 --- a/src/test/ui/issues/issue-29516.rs +++ b/src/test/ui/issues/issue-29516.rs @@ -1,5 +1,6 @@ // check-pass #![feature(optin_builtin_traits)] +#![feature(negative_impls)] auto trait NotSame {} diff --git a/src/test/ui/issues/issue-33140-hack-boundaries.rs b/src/test/ui/issues/issue-33140-hack-boundaries.rs index 5aba886273f..5984a256a30 100644 --- a/src/test/ui/issues/issue-33140-hack-boundaries.rs +++ b/src/test/ui/issues/issue-33140-hack-boundaries.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] #![allow(order_dependent_trait_objects)] // Check that the issue #33140 hack does not allow unintended things. diff --git a/src/test/ui/mut/mutable-enum-indirect.rs b/src/test/ui/mut/mutable-enum-indirect.rs index 611ff0d66a2..502859c0413 100644 --- a/src/test/ui/mut/mutable-enum-indirect.rs +++ b/src/test/ui/mut/mutable-enum-indirect.rs @@ -1,7 +1,7 @@ // Tests that an `&` pointer to something inherently mutable is itself // to be considered mutable. -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] use std::marker::Sync; diff --git a/src/test/ui/never_type/auto-traits.rs b/src/test/ui/never_type/auto-traits.rs index 2d9689888cb..84c8db4053e 100644 --- a/src/test/ui/never_type/auto-traits.rs +++ b/src/test/ui/never_type/auto-traits.rs @@ -1,6 +1,7 @@ // check-pass #![feature(optin_builtin_traits)] +#![feature(negative_impls)] #![feature(never_type)] fn main() { diff --git a/src/test/ui/no_send-enum.rs b/src/test/ui/no_send-enum.rs index 4b4d06f1e32..bd560649b99 100644 --- a/src/test/ui/no_send-enum.rs +++ b/src/test/ui/no_send-enum.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] use std::marker::Send; diff --git a/src/test/ui/no_send-struct.rs b/src/test/ui/no_send-struct.rs index 67816bfee5d..75a363f9f76 100644 --- a/src/test/ui/no_send-struct.rs +++ b/src/test/ui/no_send-struct.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] use std::marker::Send; diff --git a/src/test/ui/no_share-enum.rs b/src/test/ui/no_share-enum.rs index f5edb63cf86..44bf1913e7a 100644 --- a/src/test/ui/no_share-enum.rs +++ b/src/test/ui/no_share-enum.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] use std::marker::Sync; diff --git a/src/test/ui/no_share-struct.rs b/src/test/ui/no_share-struct.rs index 35867d0f216..7d8a36a76f2 100644 --- a/src/test/ui/no_share-struct.rs +++ b/src/test/ui/no_share-struct.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] use std::marker::Sync; diff --git a/src/test/ui/parser/trait-object-bad-parens.rs b/src/test/ui/parser/trait-object-bad-parens.rs index 048e028be1c..0a2836d691f 100644 --- a/src/test/ui/parser/trait-object-bad-parens.rs +++ b/src/test/ui/parser/trait-object-bad-parens.rs @@ -1,4 +1,5 @@ #![feature(optin_builtin_traits)] +#![feature(negative_impls)] #![allow(bare_trait_objects)] auto trait Auto {} diff --git a/src/test/ui/parser/trait-object-bad-parens.stderr b/src/test/ui/parser/trait-object-bad-parens.stderr index f53afdff5e7..74e484eebee 100644 --- a/src/test/ui/parser/trait-object-bad-parens.stderr +++ b/src/test/ui/parser/trait-object-bad-parens.stderr @@ -1,23 +1,23 @@ error[E0178]: expected a path on the left-hand side of `+`, not `((Auto))` - --> $DIR/trait-object-bad-parens.rs:7:16 + --> $DIR/trait-object-bad-parens.rs:8:16 | LL | let _: Box<((Auto)) + Auto>; | ^^^^^^^^^^^^^^^ expected a path error[E0178]: expected a path on the left-hand side of `+`, not `(Auto + Auto)` - --> $DIR/trait-object-bad-parens.rs:9:16 + --> $DIR/trait-object-bad-parens.rs:10:16 | LL | let _: Box<(Auto + Auto) + Auto>; | ^^^^^^^^^^^^^^^^^^^^ expected a path error[E0178]: expected a path on the left-hand side of `+`, not `(Auto)` - --> $DIR/trait-object-bad-parens.rs:11:16 + --> $DIR/trait-object-bad-parens.rs:12:16 | LL | let _: Box<(Auto +) + Auto>; | ^^^^^^^^^^^^^^^ expected a path error[E0178]: expected a path on the left-hand side of `+`, not `(dyn Auto)` - --> $DIR/trait-object-bad-parens.rs:13:16 + --> $DIR/trait-object-bad-parens.rs:14:16 | LL | let _: Box<(dyn Auto) + Auto>; | ^^^^^^^^^^^^^^^^^ expected a path diff --git a/src/test/ui/privacy/privacy-sanity.rs b/src/test/ui/privacy/privacy-sanity.rs index f83b24c49a1..8bbf1ab5d1f 100644 --- a/src/test/ui/privacy/privacy-sanity.rs +++ b/src/test/ui/privacy/privacy-sanity.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] pub trait Tr { fn f(); diff --git a/src/test/ui/privacy/private-in-public-non-principal-2.rs b/src/test/ui/privacy/private-in-public-non-principal-2.rs index 8a59073fa6c..cd3d609ca3e 100644 --- a/src/test/ui/privacy/private-in-public-non-principal-2.rs +++ b/src/test/ui/privacy/private-in-public-non-principal-2.rs @@ -1,4 +1,5 @@ #![feature(optin_builtin_traits)] +#![feature(negative_impls)] #[allow(private_in_public)] mod m { diff --git a/src/test/ui/privacy/private-in-public-non-principal-2.stderr b/src/test/ui/privacy/private-in-public-non-principal-2.stderr index 1b6d143b932..7850694aab2 100644 --- a/src/test/ui/privacy/private-in-public-non-principal-2.stderr +++ b/src/test/ui/privacy/private-in-public-non-principal-2.stderr @@ -1,5 +1,5 @@ error: trait `m::PrivNonPrincipal` is private - --> $DIR/private-in-public-non-principal-2.rs:11:5 + --> $DIR/private-in-public-non-principal-2.rs:12:5 | LL | m::leak_dyn_nonprincipal(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ private trait diff --git a/src/test/ui/privacy/private-in-public-non-principal.rs b/src/test/ui/privacy/private-in-public-non-principal.rs index b306849ac8e..aa946f5c0ac 100644 --- a/src/test/ui/privacy/private-in-public-non-principal.rs +++ b/src/test/ui/privacy/private-in-public-non-principal.rs @@ -1,4 +1,5 @@ #![feature(optin_builtin_traits)] +#![feature(negative_impls)] pub trait PubPrincipal {} auto trait PrivNonPrincipal {} diff --git a/src/test/ui/privacy/private-in-public-non-principal.stderr b/src/test/ui/privacy/private-in-public-non-principal.stderr index 778c98671ad..05131135d49 100644 --- a/src/test/ui/privacy/private-in-public-non-principal.stderr +++ b/src/test/ui/privacy/private-in-public-non-principal.stderr @@ -1,5 +1,5 @@ warning: private trait `PrivNonPrincipal` in public interface (error E0445) - --> $DIR/private-in-public-non-principal.rs:6:1 + --> $DIR/private-in-public-non-principal.rs:7:1 | LL | pub fn leak_dyn_nonprincipal() -> Box { loop {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | pub fn check_doc_lint() {} | ^^^^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/private-in-public-non-principal.rs:10:8 + --> $DIR/private-in-public-non-principal.rs:11:8 | LL | #[deny(missing_docs)] | ^^^^^^^^^^^^ diff --git a/src/test/ui/specialization/defaultimpl/validation.rs b/src/test/ui/specialization/defaultimpl/validation.rs index ac8742c70c8..8134333c58f 100644 --- a/src/test/ui/specialization/defaultimpl/validation.rs +++ b/src/test/ui/specialization/defaultimpl/validation.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] #![feature(specialization)] struct S; diff --git a/src/test/ui/specialization/specialization-overlap-negative.rs b/src/test/ui/specialization/specialization-overlap-negative.rs index 4f5f65dafaa..dff2b28bf00 100644 --- a/src/test/ui/specialization/specialization-overlap-negative.rs +++ b/src/test/ui/specialization/specialization-overlap-negative.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] #![feature(specialization)] trait MyTrait {} diff --git a/src/test/ui/specialization/specialization-polarity.rs b/src/test/ui/specialization/specialization-polarity.rs index fd0671ad09e..4a733fb3c49 100644 --- a/src/test/ui/specialization/specialization-polarity.rs +++ b/src/test/ui/specialization/specialization-polarity.rs @@ -1,6 +1,7 @@ // Make sure specialization cannot change impl polarity #![feature(optin_builtin_traits)] +#![feature(negative_impls)] #![feature(specialization)] auto trait Foo {} diff --git a/src/test/ui/specialization/specialization-polarity.stderr b/src/test/ui/specialization/specialization-polarity.stderr index c6e7f193d01..30655d87d55 100644 --- a/src/test/ui/specialization/specialization-polarity.stderr +++ b/src/test/ui/specialization/specialization-polarity.stderr @@ -1,5 +1,5 @@ error[E0748]: found both positive and negative implementation of trait `Foo` for type `u8`: - --> $DIR/specialization-polarity.rs:9:1 + --> $DIR/specialization-polarity.rs:10:1 | LL | impl Foo for T {} | ----------------- positive implementation here @@ -7,7 +7,7 @@ LL | impl !Foo for u8 {} | ^^^^^^^^^^^^^^^^ negative implementation here error[E0748]: found both positive and negative implementation of trait `Bar` for type `u8`: - --> $DIR/specialization-polarity.rs:14:1 + --> $DIR/specialization-polarity.rs:15:1 | LL | impl !Bar for T {} | ------------------ negative implementation here diff --git a/src/test/ui/syntax-trait-polarity-feature-gate.stderr b/src/test/ui/syntax-trait-polarity-feature-gate.stderr index 5d4c1b354f7..1c37106f13d 100644 --- a/src/test/ui/syntax-trait-polarity-feature-gate.stderr +++ b/src/test/ui/syntax-trait-polarity-feature-gate.stderr @@ -5,7 +5,7 @@ LL | impl !Send for TestType {} | ^^^^^ | = note: see issue #13231 for more information - = help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable + = help: add `#![feature(negative_impls)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/syntax-trait-polarity.rs b/src/test/ui/syntax-trait-polarity.rs index 739a3c12dfb..ed2947493b0 100644 --- a/src/test/ui/syntax-trait-polarity.rs +++ b/src/test/ui/syntax-trait-polarity.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] use std::marker::Send; diff --git a/src/test/ui/traits/auto-traits.rs b/src/test/ui/traits/auto-traits.rs index c495b97b25b..15fdddc5f3f 100644 --- a/src/test/ui/traits/auto-traits.rs +++ b/src/test/ui/traits/auto-traits.rs @@ -1,6 +1,7 @@ // run-pass #![allow(unused_doc_comments)] #![feature(optin_builtin_traits)] +#![feature(negative_impls)] auto trait Auto {} unsafe auto trait AutoUnsafe {} diff --git a/src/test/ui/traits/negative-impls/auxiliary/foreign_trait.rs b/src/test/ui/traits/negative-impls/auxiliary/foreign_trait.rs index 1790b24be33..681f26438e6 100644 --- a/src/test/ui/traits/negative-impls/auxiliary/foreign_trait.rs +++ b/src/test/ui/traits/negative-impls/auxiliary/foreign_trait.rs @@ -1,6 +1,6 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] -pub trait ForeignTrait { } +pub trait ForeignTrait {} -impl ForeignTrait for u32 { } +impl ForeignTrait for u32 {} impl !ForeignTrait for String {} diff --git a/src/test/ui/traits/negative-impls/negated-auto-traits-error.rs b/src/test/ui/traits/negative-impls/negated-auto-traits-error.rs index fb9a3a99748..4bdad5dc591 100644 --- a/src/test/ui/traits/negative-impls/negated-auto-traits-error.rs +++ b/src/test/ui/traits/negative-impls/negated-auto-traits-error.rs @@ -3,7 +3,7 @@ // errors are not reported. This way, we make sure that, for each function, different // typeck phases are involved and all errors are reported. -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] use std::marker::Send; diff --git a/src/test/ui/traits/negative-impls/negated-auto-traits-rpass.rs b/src/test/ui/traits/negative-impls/negated-auto-traits-rpass.rs index 8664b6a6a6e..010dbf24664 100644 --- a/src/test/ui/traits/negative-impls/negated-auto-traits-rpass.rs +++ b/src/test/ui/traits/negative-impls/negated-auto-traits-rpass.rs @@ -1,6 +1,6 @@ // run-pass #![allow(unused_variables)] -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] use std::marker::Send; diff --git a/src/test/ui/traits/negative-impls/negative-default-impls.rs b/src/test/ui/traits/negative-impls/negative-default-impls.rs index b23ac87f899..2d50bc83ec3 100644 --- a/src/test/ui/traits/negative-impls/negative-default-impls.rs +++ b/src/test/ui/traits/negative-impls/negative-default-impls.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] #![feature(specialization)] trait MyTrait { diff --git a/src/test/ui/traits/negative-impls/negative-specializes-positive-item.rs b/src/test/ui/traits/negative-impls/negative-specializes-positive-item.rs index c7009430eae..043273e6241 100644 --- a/src/test/ui/traits/negative-impls/negative-specializes-positive-item.rs +++ b/src/test/ui/traits/negative-impls/negative-specializes-positive-item.rs @@ -1,5 +1,5 @@ #![feature(specialization)] -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] // Negative impl for u32 cannot "specialize" the base impl. trait MyTrait { diff --git a/src/test/ui/traits/negative-impls/negative-specializes-positive.rs b/src/test/ui/traits/negative-impls/negative-specializes-positive.rs index 25301c696e1..ac0fac10eef 100644 --- a/src/test/ui/traits/negative-impls/negative-specializes-positive.rs +++ b/src/test/ui/traits/negative-impls/negative-specializes-positive.rs @@ -1,5 +1,5 @@ #![feature(specialization)] -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] // Negative impl for u32 cannot "specialize" the base impl. trait MyTrait {} diff --git a/src/test/ui/traits/negative-impls/no-items.rs b/src/test/ui/traits/negative-impls/no-items.rs index 5bfbf9653ab..5fc6be9b300 100644 --- a/src/test/ui/traits/negative-impls/no-items.rs +++ b/src/test/ui/traits/negative-impls/no-items.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] trait MyTrait { type Foo; diff --git a/src/test/ui/traits/negative-impls/positive-specializes-negative.rs b/src/test/ui/traits/negative-impls/positive-specializes-negative.rs index 8a8ee70370f..eac4c24d5d3 100644 --- a/src/test/ui/traits/negative-impls/positive-specializes-negative.rs +++ b/src/test/ui/traits/negative-impls/positive-specializes-negative.rs @@ -1,5 +1,5 @@ #![feature(specialization)] -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] trait MyTrait {} diff --git a/src/test/ui/traits/negative-impls/rely-on-negative-impl-in-coherence.rs b/src/test/ui/traits/negative-impls/rely-on-negative-impl-in-coherence.rs index b823c0f7864..db72aaf1803 100644 --- a/src/test/ui/traits/negative-impls/rely-on-negative-impl-in-coherence.rs +++ b/src/test/ui/traits/negative-impls/rely-on-negative-impl-in-coherence.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] // aux-build: foreign_trait.rs diff --git a/src/test/ui/traits/negative-impls/typeck-negative-impls-builtin.rs b/src/test/ui/traits/negative-impls/typeck-negative-impls-builtin.rs index 6a2e99f8147..e326d3ab3f3 100644 --- a/src/test/ui/traits/negative-impls/typeck-negative-impls-builtin.rs +++ b/src/test/ui/traits/negative-impls/typeck-negative-impls-builtin.rs @@ -1,6 +1,6 @@ // run-pass -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] #![allow(dead_code)] struct TestType; diff --git a/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.rs b/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.rs index 86029473b51..4106f56d64a 100644 --- a/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.rs +++ b/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.rs @@ -1,5 +1,5 @@ #![allow(dead_code)] -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] // Overlapping negative impls for `MyStruct` are not permitted: struct MyStruct; @@ -7,5 +7,4 @@ impl !Send for MyStruct {} impl !Send for MyStruct {} //~^ ERROR conflicting implementations of trait -fn main() { -} +fn main() {} diff --git a/src/test/ui/traits/overlap-permitted-for-marker-traits.rs b/src/test/ui/traits/overlap-permitted-for-marker-traits.rs new file mode 100644 index 00000000000..00823d13b36 --- /dev/null +++ b/src/test/ui/traits/overlap-permitted-for-marker-traits.rs @@ -0,0 +1,28 @@ +// run-pass +// Tests for RFC 1268: we allow overlapping impls of marker traits, +// that is, traits without items. In this case, a type `T` is +// `MyMarker` if it is either `Debug` or `Display`. + +#![feature(marker_trait_attr)] +#![feature(negative_impls)] + +use std::fmt::{Debug, Display}; + +#[marker] +trait MyMarker {} + +impl MyMarker for T {} +impl MyMarker for T {} + +fn foo(t: T) -> T { + t +} + +fn main() { + // Debug && Display: + assert_eq!(1, foo(1)); + assert_eq!(2.0, foo(2.0)); + + // Debug && !Display: + assert_eq!(vec![1], foo(vec![1])); +} diff --git a/src/test/ui/traits/syntax-trait-polarity.rs b/src/test/ui/traits/syntax-trait-polarity.rs index c6524f5c8e7..c809f9e89f9 100644 --- a/src/test/ui/traits/syntax-trait-polarity.rs +++ b/src/test/ui/traits/syntax-trait-polarity.rs @@ -2,7 +2,7 @@ #![allow(dead_code)] // pretty-expanded FIXME #23616 -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] struct TestType; diff --git a/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.rs b/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.rs index c65242b1bb1..571f934fc5b 100644 --- a/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.rs +++ b/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.rs @@ -3,6 +3,7 @@ // to be synthesized. #![feature(optin_builtin_traits)] +#![feature(negative_impls)] auto trait Magic: Copy {} //~ ERROR E0568 diff --git a/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr b/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr index a83ff370151..f44986da0e2 100644 --- a/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr +++ b/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr @@ -1,5 +1,5 @@ error[E0568]: auto traits cannot have super traits - --> $DIR/traits-inductive-overflow-supertrait-oibit.rs:7:19 + --> $DIR/traits-inductive-overflow-supertrait-oibit.rs:8:19 | LL | auto trait Magic: Copy {} | ----- ^^^^ help: remove the super traits @@ -7,7 +7,7 @@ LL | auto trait Magic: Copy {} | auto trait cannot have super traits error[E0277]: the trait bound `NoClone: std::marker::Copy` is not satisfied - --> $DIR/traits-inductive-overflow-supertrait-oibit.rs:15:23 + --> $DIR/traits-inductive-overflow-supertrait-oibit.rs:16:23 | LL | fn copy(x: T) -> (T, T) { (x, x) } | ---- ----- required by this bound in `copy` diff --git a/src/test/ui/typeck/typeck-auto-trait-no-supertraits-2.rs b/src/test/ui/typeck/typeck-auto-trait-no-supertraits-2.rs index 92d8ba88727..8824a6d2767 100644 --- a/src/test/ui/typeck/typeck-auto-trait-no-supertraits-2.rs +++ b/src/test/ui/typeck/typeck-auto-trait-no-supertraits-2.rs @@ -1,4 +1,5 @@ #![feature(optin_builtin_traits)] +#![feature(negative_impls)] auto trait Magic : Sized where Option : Magic {} //~ ERROR E0568 impl Magic for T {} diff --git a/src/test/ui/typeck/typeck-auto-trait-no-supertraits-2.stderr b/src/test/ui/typeck/typeck-auto-trait-no-supertraits-2.stderr index e3976293277..63b3300f6db 100644 --- a/src/test/ui/typeck/typeck-auto-trait-no-supertraits-2.stderr +++ b/src/test/ui/typeck/typeck-auto-trait-no-supertraits-2.stderr @@ -1,5 +1,5 @@ error[E0568]: auto traits cannot have super traits - --> $DIR/typeck-auto-trait-no-supertraits-2.rs:3:20 + --> $DIR/typeck-auto-trait-no-supertraits-2.rs:4:20 | LL | auto trait Magic : Sized where Option : Magic {} | ----- ^^^^^ help: remove the super traits diff --git a/src/test/ui/typeck/typeck-auto-trait-no-supertraits.rs b/src/test/ui/typeck/typeck-auto-trait-no-supertraits.rs index e48017acfc7..edbca915124 100644 --- a/src/test/ui/typeck/typeck-auto-trait-no-supertraits.rs +++ b/src/test/ui/typeck/typeck-auto-trait-no-supertraits.rs @@ -23,6 +23,7 @@ // } #![feature(optin_builtin_traits)] +#![feature(negative_impls)] auto trait Magic: Copy {} //~ ERROR E0568 impl Magic for T {} diff --git a/src/test/ui/typeck/typeck-auto-trait-no-supertraits.stderr b/src/test/ui/typeck/typeck-auto-trait-no-supertraits.stderr index b1602e3642e..796638fc54d 100644 --- a/src/test/ui/typeck/typeck-auto-trait-no-supertraits.stderr +++ b/src/test/ui/typeck/typeck-auto-trait-no-supertraits.stderr @@ -1,5 +1,5 @@ error[E0568]: auto traits cannot have super traits - --> $DIR/typeck-auto-trait-no-supertraits.rs:27:19 + --> $DIR/typeck-auto-trait-no-supertraits.rs:28:19 | LL | auto trait Magic: Copy {} | ----- ^^^^ help: remove the super traits diff --git a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.rs b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.rs index 6c170fb5bae..71ac2b466c1 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.rs +++ b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.rs @@ -1,4 +1,5 @@ #![feature(optin_builtin_traits)] +#![feature(negative_impls)] auto trait MyTrait {} diff --git a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.stderr b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.stderr index f060afea24e..23401ca3086 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.stderr +++ b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied in `(MyS2, MyS)` - --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:16:5 + --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:17:5 | LL | fn is_mytrait() {} | ---------- ------- required by this bound in `is_mytrait` diff --git a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.rs b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.rs index d72f6761218..6483b9213dc 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.rs +++ b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.rs @@ -1,4 +1,5 @@ #![feature(optin_builtin_traits)] +#![feature(negative_impls)] auto trait MyTrait {} diff --git a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr index 22a2cb3e0ec..a30b29a3893 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr +++ b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied - --> $DIR/typeck-default-trait-impl-constituent-types.rs:20:18 + --> $DIR/typeck-default-trait-impl-constituent-types.rs:21:18 | LL | fn is_mytrait() {} | ---------- ------- required by this bound in `is_mytrait` diff --git a/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs b/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs index 212e165151d..772ac322032 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs +++ b/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs @@ -3,7 +3,7 @@ // Test that we do not consider associated types to be sendable without // some applicable trait bound (and we don't ICE). -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] extern crate tdticc_coherence_lib as lib; diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation-send.rs b/src/test/ui/typeck/typeck-default-trait-impl-negation-send.rs index 617d0f3b565..3a2fc39d409 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-negation-send.rs +++ b/src/test/ui/typeck/typeck-default-trait-impl-negation-send.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] struct MySendable { t: *mut u8 diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.rs b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.rs index e4487fb110c..2734b761e61 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.rs +++ b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.rs @@ -1,4 +1,4 @@ -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] struct Managed; impl !Send for Managed {} diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation.rs b/src/test/ui/typeck/typeck-default-trait-impl-negation.rs index 0b6e13be6e1..47cab60625d 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-negation.rs +++ b/src/test/ui/typeck/typeck-default-trait-impl-negation.rs @@ -1,4 +1,5 @@ #![feature(optin_builtin_traits)] +#![feature(negative_impls)] auto trait MyTrait {} diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr b/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr index 4b13fcc885a..e31bb810744 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr +++ b/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `ThisImplsUnsafeTrait: MyTrait` is not satisfied - --> $DIR/typeck-default-trait-impl-negation.rs:21:19 + --> $DIR/typeck-default-trait-impl-negation.rs:22:19 | LL | fn is_my_trait() {} | ----------- ------- required by this bound in `is_my_trait` @@ -11,7 +11,7 @@ LL | is_my_trait::(); error[E0277]: the trait bound `ThisImplsTrait: MyUnsafeTrait` is not satisfied - --> $DIR/typeck-default-trait-impl-negation.rs:24:26 + --> $DIR/typeck-default-trait-impl-negation.rs:25:26 | LL | fn is_my_unsafe_trait() {} | ------------------ ------------- required by this bound in `is_my_unsafe_trait` diff --git a/src/test/ui/typeck/typeck-default-trait-impl-precedence.rs b/src/test/ui/typeck/typeck-default-trait-impl-precedence.rs index 9b228f70646..614a5ff55b1 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-precedence.rs +++ b/src/test/ui/typeck/typeck-default-trait-impl-precedence.rs @@ -4,6 +4,7 @@ // impls whose types unify. #![feature(optin_builtin_traits)] +#![feature(negative_impls)] auto trait Defaulted { } impl<'a,T:Signed> Defaulted for &'a T { } diff --git a/src/test/ui/typeck/typeck-default-trait-impl-precedence.stderr b/src/test/ui/typeck/typeck-default-trait-impl-precedence.stderr index 15877304418..0d256094c60 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-precedence.stderr +++ b/src/test/ui/typeck/typeck-default-trait-impl-precedence.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `u32: Signed` is not satisfied - --> $DIR/typeck-default-trait-impl-precedence.rs:18:5 + --> $DIR/typeck-default-trait-impl-precedence.rs:19:5 | LL | fn is_defaulted() { } | ------------ --------- required by this bound in `is_defaulted` diff --git a/src/test/ui/typeck/typeck-unsafe-always-share.rs b/src/test/ui/typeck/typeck-unsafe-always-share.rs index 7d1ff732983..dc5ddf51563 100644 --- a/src/test/ui/typeck/typeck-unsafe-always-share.rs +++ b/src/test/ui/typeck/typeck-unsafe-always-share.rs @@ -1,6 +1,6 @@ // Verify that UnsafeCell is *always* !Sync regardless if `T` is sync. -#![feature(optin_builtin_traits)] +#![feature(negative_impls)] use std::cell::UnsafeCell; use std::marker::Sync;