introduce negative_impls
feature gate and document
They used to be covered by `optin_builtin_traits` but negative impls are now applicable to all traits, not just auto traits. This also adds docs in the unstable book for the current state of auto traits.
This commit is contained in:
parent
65071708f8
commit
fda3378e3f
@ -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<T: ?Sized> !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.
|
@ -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<T> {
|
||||
data: T,
|
||||
next: Option<Box<List<T>>>,
|
||||
}
|
||||
```
|
||||
|
||||
Presuming that there is no explicit impl of `Send` for `List`, the
|
||||
compiler will supply an automatic impl of the form:
|
||||
|
||||
```rust
|
||||
struct List<T> {
|
||||
data: T,
|
||||
next: Option<Box<List<T>>>,
|
||||
}
|
||||
|
||||
unsafe impl<T> Send for List<T>
|
||||
where
|
||||
T: Send, // from the field `data`
|
||||
Option<Box<List<T>>>: 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<Box<List>>: Send`, which will in turn require
|
||||
`Box<List>: 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.
|
||||
|
||||
|
@ -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)]
|
||||
|
@ -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)]
|
||||
|
@ -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))]
|
||||
|
@ -286,8 +286,8 @@ fn visit_item(&mut self, i: &'a ast::Item) {
|
||||
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 @@ fn visit_item(&mut self, i: &'a ast::Item) {
|
||||
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 @@ fn visit_item(&mut self, i: &'a ast::Item) {
|
||||
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"
|
||||
|
@ -802,13 +802,13 @@ fn print_error_count(&mut self, registry: &Registry) {
|
||||
));
|
||||
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]
|
||||
));
|
||||
}
|
||||
|
@ -152,6 +152,9 @@ pub fn set(&self, features: &mut Features, span: Span) {
|
||||
/// 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),
|
||||
|
||||
|
@ -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 @@ pub fn shrink_to_hi(self) -> 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 @@ pub fn source_equal(&self, other: &Span) -> bool {
|
||||
pub fn trim_start(self, other: Span) -> Option<Span> {
|
||||
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<Span> {
|
||||
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 @@ pub fn rust_2018(&self) -> bool {
|
||||
pub fn source_callee(self) -> Option<ExpnData> {
|
||||
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 @@ pub fn lookup_line(&self, pos: BytePos) -> Option<usize> {
|
||||
|
||||
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) {
|
||||
|
@ -473,6 +473,7 @@
|
||||
needs_drop,
|
||||
needs_panic_runtime,
|
||||
negate_unsigned,
|
||||
negative_impls,
|
||||
never,
|
||||
never_type,
|
||||
never_type_fallback,
|
||||
|
@ -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)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
// pp-exact
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![crate_name = "foo"]
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
pub struct Foo;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
#![feature(negative_impls)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
pub auto trait AnOibit {}
|
||||
|
@ -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"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![crate_name = "foo"]
|
||||
|
||||
pub struct Foo;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
// @matches negative_impl/struct.Alpha.html '//pre' "pub struct Alpha"
|
||||
pub struct Alpha;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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: Qux>(t: T) { }
|
||||
| ------ --- required by this bound in `is_qux`
|
||||
@ -13,7 +13,7 @@ LL | is_qux(bar());
|
||||
= help: the following implementations were found:
|
||||
<Foo as Qux>
|
||||
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`
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
fn main() {
|
||||
struct Foo;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(marker_trait_attr)]
|
||||
|
||||
#[marker]
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
auto trait MySafeTrait {}
|
||||
|
||||
|
@ -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 {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Copy;
|
||||
|
||||
|
@ -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() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Copy;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#![allow(dead_code)]
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Send;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Send;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// aux-build:coherence_orphan_lib.rs
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
extern crate coherence_orphan_lib as lib;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
struct Foo;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
struct Foo;
|
||||
|
||||
|
3
src/test/ui/feature-gate-negative_impls.rs
Normal file
3
src/test/ui/feature-gate-negative_impls.rs
Normal file
@ -0,0 +1,3 @@
|
||||
trait MyTrait {}
|
||||
impl !MyTrait for u32 {} //~ ERROR negative trait bounds are not yet fully implemented
|
||||
fn main() {}
|
12
src/test/ui/feature-gate-negative_impls.stderr
Normal file
12
src/test/ui/feature-gate-negative_impls.stderr
Normal file
@ -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 <https://github.com/rust-lang/rust/issues/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`.
|
@ -14,7 +14,7 @@ LL | impl !AutoDummyTrait for DummyStruct {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #13231 <https://github.com/rust-lang/rust/issues/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
|
||||
|
||||
|
@ -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);
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
@ -1,5 +1,6 @@
|
||||
#![feature(generators)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
auto trait Foo {}
|
||||
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Sync;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
//~ ERROR
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
unsafe auto trait Trait {
|
||||
type Output; //~ ERROR E0380
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
unsafe auto trait Trait {
|
||||
fn method(&self) { //~ ERROR E0380
|
||||
|
@ -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
|
||||
|
@ -1,5 +1,6 @@
|
||||
// check-pass
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
auto trait NotSame {}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(never_type)]
|
||||
|
||||
fn main() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Send;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Send;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Sync;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Sync;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![allow(bare_trait_objects)]
|
||||
|
||||
auto trait Auto {}
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
pub trait Tr {
|
||||
fn f();
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
#[allow(private_in_public)]
|
||||
mod m {
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
pub trait PubPrincipal {}
|
||||
auto trait PrivNonPrincipal {}
|
||||
|
@ -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<dyn PubPrincipal + PrivNonPrincipal> { 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)]
|
||||
| ^^^^^^^^^^^^
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(specialization)]
|
||||
|
||||
struct S;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(specialization)]
|
||||
|
||||
trait MyTrait {}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Make sure specialization cannot change impl polarity
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(specialization)]
|
||||
|
||||
auto trait Foo {}
|
||||
|
@ -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<T> 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<T> !Bar for T {}
|
||||
| ------------------ negative implementation here
|
||||
|
@ -5,7 +5,7 @@ LL | impl !Send for TestType {}
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #13231 <https://github.com/rust-lang/rust/issues/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
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Send;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// run-pass
|
||||
#![allow(unused_doc_comments)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
auto trait Auto {}
|
||||
unsafe auto trait AutoUnsafe {}
|
||||
|
@ -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 {}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// run-pass
|
||||
#![allow(unused_variables)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Send;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(specialization)]
|
||||
|
||||
trait MyTrait {
|
||||
|
@ -1,5 +1,5 @@
|
||||
#![feature(specialization)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
// Negative impl for u32 cannot "specialize" the base impl.
|
||||
trait MyTrait {
|
||||
|
@ -1,5 +1,5 @@
|
||||
#![feature(specialization)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
// Negative impl for u32 cannot "specialize" the base impl.
|
||||
trait MyTrait {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
trait MyTrait {
|
||||
type Foo;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#![feature(specialization)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
trait MyTrait {}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
// aux-build: foreign_trait.rs
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
struct TestType;
|
||||
|
@ -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() {}
|
||||
|
28
src/test/ui/traits/overlap-permitted-for-marker-traits.rs
Normal file
28
src/test/ui/traits/overlap-permitted-for-marker-traits.rs
Normal file
@ -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<T: Debug> MyMarker for T {}
|
||||
impl<T: Display> MyMarker for T {}
|
||||
|
||||
fn foo<T: MyMarker>(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]));
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
#![allow(dead_code)]
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
struct TestType;
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
// to be synthesized.
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
auto trait Magic: Copy {} //~ ERROR E0568
|
||||
|
||||
|
@ -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<T: Magic>(x: T) -> (T, T) { (x, x) }
|
||||
| ---- ----- required by this bound in `copy`
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
auto trait Magic : Sized where Option<Self> : Magic {} //~ ERROR E0568
|
||||
impl<T:Magic> Magic for T {}
|
||||
|
@ -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<Self> : Magic {}
|
||||
| ----- ^^^^^ help: remove the super traits
|
||||
|
@ -23,6 +23,7 @@
|
||||
// }
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
auto trait Magic: Copy {} //~ ERROR E0568
|
||||
impl<T:Magic> Magic for T {}
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
auto trait MyTrait {}
|
||||
|
||||
|
@ -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<T: MyTrait>() {}
|
||||
| ---------- ------- required by this bound in `is_mytrait`
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
auto trait MyTrait {}
|
||||
|
||||
|
@ -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<T: MyTrait>() {}
|
||||
| ---------- ------- required by this bound in `is_mytrait`
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
struct MySendable {
|
||||
t: *mut u8
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
struct Managed;
|
||||
impl !Send for Managed {}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
auto trait MyTrait {}
|
||||
|
||||
|
@ -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<T: MyTrait>() {}
|
||||
| ----------- ------- required by this bound in `is_my_trait`
|
||||
@ -11,7 +11,7 @@ LL | is_my_trait::<ThisImplsUnsafeTrait>();
|
||||
<ThisImplsUnsafeTrait as MyTrait>
|
||||
|
||||
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<T: MyUnsafeTrait>() {}
|
||||
| ------------------ ------------- required by this bound in `is_my_unsafe_trait`
|
||||
|
@ -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 { }
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user