*self
}
}
+
+ // Shared references can be cloned, but mutable references *cannot*!
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[cfg(not(bootstrap))]
+ impl<T: ?Sized> !Clone for &mut T {}
}
}
}
+#[cfg(not(bootstrap))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> !DerefMut for &T {}
+
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Deref for &mut T {
type Target = T;
E0185: include_str!("./error_codes/E0185.md"),
E0186: include_str!("./error_codes/E0186.md"),
E0191: include_str!("./error_codes/E0191.md"),
-E0192: include_str!("./error_codes/E0192.md"),
E0193: include_str!("./error_codes/E0193.md"),
E0195: include_str!("./error_codes/E0195.md"),
E0197: include_str!("./error_codes/E0197.md"),
E0746: include_str!("./error_codes/E0746.md"),
E0747: include_str!("./error_codes/E0747.md"),
E0748: include_str!("./error_codes/E0748.md"),
+E0749: include_str!("./error_codes/E0749.md"),
+E0750: include_str!("./error_codes/E0750.md"),
;
// E0006, // merged with E0005
// E0008, // cannot bind by-move into a pattern guard
// E0188, // can not cast an immutable reference to a mutable pointer
// E0189, // deprecated: can only cast a boxed pointer to a boxed object
// E0190, // deprecated: can only cast a &-pointer to an &-object
+// E0192, // negative impl only applicable to auto traits
// E0194, // merged into E0403
// E0196, // cannot determine a type for this closure
E0208,
--- /dev/null
+Negative impls are not allowed to have any items. Negative impls
+declare that a trait is **not** implemented (and never will be) and
+hence there is no need to specify the values for trait methods or
+other items.
--- /dev/null
+Negative impls cannot be default impls. A default impl supplies
+default values for the items within to be used by other impls, whereas
+a negative impl declares that there are no other impls. These don't
+make sense to combine.
_ => unreachable!(),
};
- tcx.sess.span_err(span, &format!(
+ tcx.sess.span_err(
+ span,
+ &format!(
"`{}` return type cannot contain a projection or `Self` that references lifetimes from \
a parent scope",
if is_async { "async fn" } else { "impl Trait" },
- ));
+ ),
+ );
}
}
Ok(ConstValue::ByRef { alloc, .. }) => {
if alloc.relocations().len() != 0 {
let msg = "statics with a custom `#[link_section]` must be a \
- simple list of bytes on the wasm target with no \
- extra levels of indirection such as references";
+ simple list of bytes on the wasm target with no \
+ extra levels of indirection such as references";
tcx.sess.span_err(span, msg);
}
}
return;
}
+ // Negative impls are not expected to have any items
+ match tcx.impl_polarity(impl_id) {
+ ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
+ ty::ImplPolarity::Negative => {
+ if !impl_item_refs.is_empty() {
+ let first_item_span = tcx.hir().impl_item(impl_item_refs[0].id).span;
+ struct_span_err!(
+ tcx.sess,
+ first_item_span,
+ E0749,
+ "negative impls cannot have any items"
+ )
+ .emit();
+ }
+ return;
+ }
+ }
+
// Locate trait definition and items
let trait_def = tcx.trait_def(impl_trait_ref.def_id);
impl_item.span,
E0323,
"item `{}` is an associated const, \
- which doesn't match its trait `{}`",
+ which doesn't match its trait `{}`",
ty_impl_item.ident,
impl_trait_ref.print_only_trait_path()
);
let adjusted_ty = autoderef.unambiguous_final_ty(self);
debug!(
"try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
- index_ty={:?})",
+ index_ty={:?})",
expr, base_expr, adjusted_ty, index_ty
);
err.span_label(
fn_span,
"implicitly returns `()` as its body has no tail or `return` \
- expression",
+ expression",
);
}
},
match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
Ok(ok) => self.register_infer_ok_obligations(ok),
Err(_) => {
- self.tcx.sess.delay_span_bug(span, &format!(
+ self.tcx.sess.delay_span_bug(
+ span,
+ &format!(
"instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
self_ty,
impl_ty,
- ));
+ ),
+ );
}
}
}
handler.note_without_error("the compiler expectedly panicked. this is a feature.");
handler.note_without_error(
"we would appreciate a joke overview: \
- https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
+ https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
);
handler.note_without_error(&format!(
"rustc {} running on {}",
}
(ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => {
// FIXME(#27579): what amount of WF checking do we need for neg impls?
- if let (Some(of_trait), false) = (of_trait, is_auto) {
+ if let hir::Defaultness::Default { .. } = defaultness {
+ let mut spans = vec![span];
+ spans.extend(defaultness_span);
struct_span_err!(
tcx.sess,
- span.to(of_trait.path.span),
- E0192,
- "invalid negative impl"
+ spans,
+ E0750,
+ "negative impls cannot be default impls"
)
- .note(
- "negative impls are only allowed for auto traits, like `Send` and \
- `Sync`",
- )
- .emit()
+ .emit();
}
}
(ty::ImplPolarity::Reservation, _) => {
.struct_span_err(
span,
"non-defining opaque type use \
- in defining scope",
+ in defining scope",
)
.span_label(
param_span,
"cannot use static lifetime; use a bound lifetime \
- instead or remove the lifetime parameter from the \
- opaque type",
+ instead or remove the lifetime parameter from the \
+ opaque type",
)
.emit();
} else {
.struct_span_err(
span,
"non-defining opaque type use \
- in defining scope",
+ in defining scope",
)
.span_note(
tcx.def_span(param.def_id),
&format!(
"used non-generic const {} for \
- generic parameter",
+ generic parameter",
ty,
),
)
.struct_span_err(
span,
"non-defining opaque type use \
- in defining scope",
+ in defining scope",
)
.span_note(spans, "lifetime used multiple times")
.emit();
span,
&format!(
"`{}` cannot be used as the type of `self` without \
- the `arbitrary_self_types` feature",
+ the `arbitrary_self_types` feature",
receiver_ty,
),
)
+++ /dev/null
-#![feature(optin_builtin_traits)]
-
-trait Trait {
- type Bar;
-}
-
-struct Foo;
-
-impl !Trait for Foo { } //~ ERROR E0192
-
-fn main() {
-}
+++ /dev/null
-error[E0192]: invalid negative impl
- --> $DIR/E0192.rs:9:6
- |
-LL | impl !Trait for Foo { }
- | ^^^^^^
- |
- = note: negative impls are only allowed for auto traits, like `Send` and `Sync`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0192`.
default unsafe impl Send for S {} //~ ERROR impls of auto traits cannot be default
default impl !Send for Z {} //~ ERROR impls of auto traits cannot be default
+ //~^ ERROR negative impls cannot be default impls
trait Tr {}
-default impl !Tr for S {} //~ ERROR invalid negative impl
+default impl !Tr for S {} //~ ERROR negative impls cannot be default impls
fn main() {}
| |
| default because of this
-error[E0192]: invalid negative impl
- --> $DIR/validation.rs:13:14
+error[E0750]: negative impls cannot be default impls
+ --> $DIR/validation.rs:10:14
|
-LL | default impl !Tr for S {}
- | ^^^
+LL | default impl !Send for Z {}
+ | ^^^^^^^ ^
+
+error[E0750]: negative impls cannot be default impls
+ --> $DIR/validation.rs:14:14
|
- = note: negative impls are only allowed for auto traits, like `Send` and `Sync`
+LL | default impl !Tr for S {}
+ | ^^^^^^^ ^
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
-For more information about this error, try `rustc --explain E0192`.
+For more information about this error, try `rustc --explain E0750`.
unsafe impl !Send for TestType {}
//~^ ERROR negative impls cannot be unsafe
impl !TestTrait for TestType {}
-//~^ ERROR invalid negative impl
struct TestType2<T>(T);
unsafe impl<T> !Send for TestType2<T> {}
//~^ ERROR negative impls cannot be unsafe
impl<T> !TestTrait for TestType2<T> {}
-//~^ ERROR invalid negative impl
fn main() {}
| unsafe because of this
error: inherent impls cannot be negative
- --> $DIR/syntax-trait-polarity.rs:19:10
+ --> $DIR/syntax-trait-polarity.rs:18:10
|
LL | impl<T> !TestType2<T> {}
| -^^^^^^^^^^^^ inherent impl for this type
| negative because of this
error[E0198]: negative impls cannot be unsafe
- --> $DIR/syntax-trait-polarity.rs:22:16
+ --> $DIR/syntax-trait-polarity.rs:21:16
|
LL | unsafe impl<T> !Send for TestType2<T> {}
| ------ -^^^^
| | negative because of this
| unsafe because of this
-error[E0192]: invalid negative impl
- --> $DIR/syntax-trait-polarity.rs:14:6
- |
-LL | impl !TestTrait for TestType {}
- | ^^^^^^^^^^
- |
- = note: negative impls are only allowed for auto traits, like `Send` and `Sync`
-
-error[E0192]: invalid negative impl
- --> $DIR/syntax-trait-polarity.rs:24:9
- |
-LL | impl<T> !TestTrait for TestType2<T> {}
- | ^^^^^^^^^^
- |
- = note: negative impls are only allowed for auto traits, like `Send` and `Sync`
-
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
-Some errors have detailed explanations: E0192, E0198.
-For more information about an error, try `rustc --explain E0192`.
+For more information about this error, try `rustc --explain E0198`.
--- /dev/null
+#![feature(optin_builtin_traits)]
+
+pub trait ForeignTrait { }
+
+impl ForeignTrait for u32 { }
+impl !ForeignTrait for String {}
--- /dev/null
+// The dummy functions are used to avoid adding new cfail files.
+// What happens is that the compiler attempts to squash duplicates and some
+// 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)]
+
+use std::marker::Send;
+
+struct Outer<T: Send>(T);
+
+struct Outer2<T>(T);
+
+unsafe impl<T: Send> Sync for Outer2<T> {}
+
+fn is_send<T: Send>(_: T) {}
+fn is_sync<T: Sync>(_: T) {}
+
+fn dummy() {
+ struct TestType;
+ impl !Send for TestType {}
+
+ Outer(TestType);
+ //~^ ERROR `dummy::TestType` cannot be sent between threads safely
+ //~| ERROR `dummy::TestType` cannot be sent between threads safely
+}
+
+fn dummy1b() {
+ struct TestType;
+ impl !Send for TestType {}
+
+ is_send(TestType);
+ //~^ ERROR `dummy1b::TestType` cannot be sent between threads safely
+}
+
+fn dummy1c() {
+ struct TestType;
+ impl !Send for TestType {}
+
+ is_send((8, TestType));
+ //~^ ERROR `dummy1c::TestType` cannot be sent between threads safely
+}
+
+fn dummy2() {
+ struct TestType;
+ impl !Send for TestType {}
+
+ is_send(Box::new(TestType));
+ //~^ ERROR `dummy2::TestType` cannot be sent between threads safely
+}
+
+fn dummy3() {
+ struct TestType;
+ impl !Send for TestType {}
+
+ is_send(Box::new(Outer2(TestType)));
+ //~^ ERROR `dummy3::TestType` cannot be sent between threads safely
+}
+
+fn main() {
+ struct TestType;
+ impl !Send for TestType {}
+
+ // This will complain about a missing Send impl because `Sync` is implement *just*
+ // for T that are `Send`. Look at #20366 and #19950
+ is_sync(Outer2(TestType));
+ //~^ ERROR `main::TestType` cannot be sent between threads safely
+}
--- /dev/null
+error[E0277]: `dummy::TestType` cannot be sent between threads safely
+ --> $DIR/negated-auto-traits-error.rs:23:11
+ |
+LL | struct Outer<T: Send>(T);
+ | ------------------------- required by `Outer`
+...
+LL | Outer(TestType);
+ | ^^^^^^^^ `dummy::TestType` cannot be sent between threads safely
+ |
+ = help: the trait `std::marker::Send` is not implemented for `dummy::TestType`
+
+error[E0277]: `dummy::TestType` cannot be sent between threads safely
+ --> $DIR/negated-auto-traits-error.rs:23:5
+ |
+LL | struct Outer<T: Send>(T);
+ | ------------------------- required by `Outer`
+...
+LL | Outer(TestType);
+ | ^^^^^^^^^^^^^^^ `dummy::TestType` cannot be sent between threads safely
+ |
+ = help: the trait `std::marker::Send` is not implemented for `dummy::TestType`
+
+error[E0277]: `dummy1b::TestType` cannot be sent between threads safely
+ --> $DIR/negated-auto-traits-error.rs:32:13
+ |
+LL | fn is_send<T: Send>(_: T) {}
+ | ------- ---- required by this bound in `is_send`
+...
+LL | is_send(TestType);
+ | ^^^^^^^^ `dummy1b::TestType` cannot be sent between threads safely
+ |
+ = help: the trait `std::marker::Send` is not implemented for `dummy1b::TestType`
+
+error[E0277]: `dummy1c::TestType` cannot be sent between threads safely
+ --> $DIR/negated-auto-traits-error.rs:40:13
+ |
+LL | fn is_send<T: Send>(_: T) {}
+ | ------- ---- required by this bound in `is_send`
+...
+LL | is_send((8, TestType));
+ | ^^^^^^^^^^^^^ `dummy1c::TestType` cannot be sent between threads safely
+ |
+ = help: within `({integer}, dummy1c::TestType)`, the trait `std::marker::Send` is not implemented for `dummy1c::TestType`
+ = note: required because it appears within the type `({integer}, dummy1c::TestType)`
+
+error[E0277]: `dummy2::TestType` cannot be sent between threads safely
+ --> $DIR/negated-auto-traits-error.rs:48:13
+ |
+LL | fn is_send<T: Send>(_: T) {}
+ | ------- ---- required by this bound in `is_send`
+...
+LL | is_send(Box::new(TestType));
+ | ^^^^^^^^^^^^^^^^^^
+ | |
+ | expected an implementor of trait `std::marker::Send`
+ | help: consider borrowing here: `&Box::new(TestType)`
+ |
+ = note: the trait bound `dummy2::TestType: std::marker::Send` is not satisfied
+ = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<dummy2::TestType>`
+ = note: required because it appears within the type `std::boxed::Box<dummy2::TestType>`
+
+error[E0277]: `dummy3::TestType` cannot be sent between threads safely
+ --> $DIR/negated-auto-traits-error.rs:56:13
+ |
+LL | fn is_send<T: Send>(_: T) {}
+ | ------- ---- required by this bound in `is_send`
+...
+LL | is_send(Box::new(Outer2(TestType)));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `dummy3::TestType` cannot be sent between threads safely
+ |
+ = help: within `Outer2<dummy3::TestType>`, the trait `std::marker::Send` is not implemented for `dummy3::TestType`
+ = note: required because it appears within the type `Outer2<dummy3::TestType>`
+ = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<Outer2<dummy3::TestType>>`
+ = note: required because it appears within the type `std::boxed::Box<Outer2<dummy3::TestType>>`
+
+error[E0277]: `main::TestType` cannot be sent between threads safely
+ --> $DIR/negated-auto-traits-error.rs:66:13
+ |
+LL | fn is_sync<T: Sync>(_: T) {}
+ | ------- ---- required by this bound in `is_sync`
+...
+LL | is_sync(Outer2(TestType));
+ | ^^^^^^^^^^^^^^^^
+ | |
+ | expected an implementor of trait `std::marker::Sync`
+ | help: consider borrowing here: `&Outer2(TestType)`
+ |
+ = note: the trait bound `main::TestType: std::marker::Sync` is not satisfied
+ = note: required because of the requirements on the impl of `std::marker::Sync` for `Outer2<main::TestType>`
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+// run-pass
+#![allow(unused_variables)]
+#![feature(optin_builtin_traits)]
+
+use std::marker::Send;
+
+pub struct WaitToken;
+impl !Send for WaitToken {}
+
+pub struct Test<T>(T);
+unsafe impl<T: 'static> Send for Test<T> {}
+
+pub fn spawn<F>(_: F) -> () where F: FnOnce(), F: Send + 'static {}
+
+fn main() {
+ let wt = Test(WaitToken);
+ spawn(move || {
+ let x = wt;
+ println!("Hello, World!");
+ });
+}
--- /dev/null
+#![feature(optin_builtin_traits)]
+#![feature(specialization)]
+
+trait MyTrait {
+ type Foo;
+}
+
+default impl !MyTrait for u32 {} //~ ERROR negative impls cannot be default impls
+
+fn main() {}
--- /dev/null
+error[E0750]: negative impls cannot be default impls
+ --> $DIR/negative-default-impls.rs:8:14
+ |
+LL | default impl !MyTrait for u32 {}
+ | ^^^^^^^ ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0750`.
--- /dev/null
+#![feature(specialization)]
+#![feature(optin_builtin_traits)]
+
+// Negative impl for u32 cannot "specialize" the base impl.
+trait MyTrait {
+ fn foo();
+}
+impl<T> MyTrait for T {
+ default fn foo() { }
+}
+impl !MyTrait for u32 { } //~ ERROR conflicting implementations
+
+fn main() { }
--- /dev/null
+error[E0119]: conflicting implementations of trait `MyTrait` for type `u32`:
+ --> $DIR/negative-specializes-positive-item.rs:11:1
+ |
+LL | impl<T> MyTrait for T {
+ | --------------------- first implementation here
+...
+LL | impl !MyTrait for u32 { }
+ | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
--- /dev/null
+#![feature(specialization)]
+#![feature(optin_builtin_traits)]
+
+// Negative impl for u32 cannot "specialize" the base impl.
+trait MyTrait { }
+impl<T> MyTrait for T { }
+impl !MyTrait for u32 { } //~ ERROR conflicting implementations
+
+// The second impl specializes the first, no error.
+trait MyTrait2 { }
+impl<T> MyTrait2 for T { }
+impl MyTrait2 for u32 { }
+
+fn main() { }
--- /dev/null
+error[E0119]: conflicting implementations of trait `MyTrait` for type `u32`:
+ --> $DIR/negative-specializes-positive.rs:7:1
+ |
+LL | impl<T> MyTrait for T { }
+ | --------------------- first implementation here
+LL | impl !MyTrait for u32 { }
+ | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
--- /dev/null
+#![feature(optin_builtin_traits)]
+
+trait MyTrait {
+ type Foo;
+}
+
+impl !MyTrait for u32 {
+ type Foo = i32; //~ ERROR negative impls cannot have any items
+}
+
+fn main() {}
--- /dev/null
+error[E0749]: negative impls cannot have any items
+ --> $DIR/no-items.rs:8:5
+ |
+LL | type Foo = i32;
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0749`.
--- /dev/null
+use std::cell::Cell;
+use std::marker::PhantomPinned;
+use std::pin::Pin;
+
+struct MyType<'a>(Cell<Option<&'a mut MyType<'a>>>, PhantomPinned);
+
+impl<'a> Clone for &'a mut MyType<'a> { //~ ERROR conflicting implementations
+ fn clone(&self) -> &'a mut MyType<'a> {
+ self.0.replace(None).unwrap()
+ }
+}
+
+
+fn main() {
+ let mut unpinned = MyType(Cell::new(None), PhantomPinned);
+ let bad_addr = &unpinned as *const MyType<'_> as usize;
+ let mut p = Box::pin(MyType(Cell::new(Some(&mut unpinned)), PhantomPinned));
+
+ // p_mut1 is okay: it does not point to the bad_addr
+ let p_mut1: Pin<&mut MyType<'_>> = p.as_mut();
+ assert_ne!(bad_addr, &*p_mut1 as *const _ as usize);
+
+ // but p_mut2 does point to bad_addr! this is unsound
+ let p_mut2: Pin<&mut MyType<'_>> = p_mut1.clone();
+ assert_eq!(bad_addr, &*p_mut2 as *const _ as usize);
+}
--- /dev/null
+error[E0119]: conflicting implementations of trait `std::clone::Clone` for type `&mut MyType<'_>`:
+ --> $DIR/pin-unsound-issue-66544-clone.rs:7:1
+ |
+LL | impl<'a> Clone for &'a mut MyType<'a> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: conflicting implementation in crate `core`:
+ - impl<T> std::clone::Clone for &mut T
+ where T: ?Sized;
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
--- /dev/null
+// Demonstrate that "rogue" `DerefMut` impls for `&T` are not allowed.
+//
+// https://github.com/rust-lang/rust/issues/66544
+
+use std::cell::Cell;
+use std::marker::PhantomPinned;
+use std::ops::DerefMut;
+use std::pin::Pin;
+
+struct MyType<'a>(Cell<Option<&'a mut MyType<'a>>>, PhantomPinned);
+
+impl<'a> DerefMut for &'a MyType<'a> { //~ ERROR conflicting implementations
+ fn deref_mut(&mut self) -> &mut MyType<'a> {
+ self.0.replace(None).unwrap()
+ }
+}
+
+
+fn main() {
+ let mut unpinned = MyType(Cell::new(None), PhantomPinned);
+ let bad_addr = &unpinned as *const MyType<'_> as usize;
+ let p = Box::pin(MyType(Cell::new(Some(&mut unpinned)), PhantomPinned));
+
+ // p_ref is okay: it does not point to the bad_addr
+ let mut p_ref: Pin<&MyType<'_>> = p.as_ref();
+ assert_ne!(bad_addr, &*p_ref as *const _ as usize);
+
+ // but p_mut does point to bad_addr! this is unsound
+ let p_mut: Pin<&mut MyType<'_>> = p_ref.as_mut();
+ assert_eq!(bad_addr, &*p_mut as *const _ as usize);
+
+ println!("oh no!");
+}
--- /dev/null
+error[E0119]: conflicting implementations of trait `std::ops::DerefMut` for type `&MyType<'_>`:
+ --> $DIR/pin-unsound-issue-66544-derefmut.rs:12:1
+ |
+LL | impl<'a> DerefMut for &'a MyType<'a> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: conflicting implementation in crate `core`:
+ - impl<T> std::ops::DerefMut for &T
+ where T: ?Sized;
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
--- /dev/null
+#![feature(specialization)]
+#![feature(optin_builtin_traits)]
+
+trait MyTrait { }
+
+impl<T> !MyTrait for T { }
+impl MyTrait for u32 { } //~ ERROR conflicting implementations
+
+fn main() { }
--- /dev/null
+error[E0119]: conflicting implementations of trait `MyTrait` for type `u32`:
+ --> $DIR/positive-specializes-negative.rs:7:1
+ |
+LL | impl<T> !MyTrait for T { }
+ | ---------------------- first implementation here
+LL | impl MyTrait for u32 { }
+ | ^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
--- /dev/null
+#![feature(optin_builtin_traits)]
+
+// aux-build: foreign_trait.rs
+
+// Test that we cannot implement `LocalTrait` for `String`,
+// even though there is a `String: !ForeignTrait` impl.
+//
+// This may not be the behavior we want long term, but it's the
+// current semantics that we implemented so as to land `!Foo` impls
+// quickly. See internals thread:
+//
+// https://internals.rust-lang.org/t/foo/11587/
+
+extern crate foreign_trait;
+use foreign_trait::ForeignTrait;
+
+trait LocalTrait { }
+impl<T: ForeignTrait> LocalTrait for T { }
+impl LocalTrait for String { } //~ ERROR conflicting implementations
+
+fn main() { }
--- /dev/null
+error[E0119]: conflicting implementations of trait `LocalTrait` for type `std::string::String`:
+ --> $DIR/rely-on-negative-impl-in-coherence.rs:19:1
+ |
+LL | impl<T: ForeignTrait> LocalTrait for T { }
+ | -------------------------------------- first implementation here
+LL | impl LocalTrait for String { }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::string::String`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
--- /dev/null
+// run-pass
+
+#![feature(optin_builtin_traits)]
+#![allow(dead_code)]
+
+struct TestType;
+
+trait TestTrait {
+ fn dummy(&self) {}
+}
+
+impl !TestTrait for TestType {}
+
+fn main() {}
+++ /dev/null
-// run-pass
-#![allow(unused_variables)]
-#![feature(optin_builtin_traits)]
-
-use std::marker::Send;
-
-pub struct WaitToken;
-impl !Send for WaitToken {}
-
-pub struct Test<T>(T);
-unsafe impl<T: 'static> Send for Test<T> {}
-
-pub fn spawn<F>(_: F) -> () where F: FnOnce(), F: Send + 'static {}
-
-fn main() {
- let wt = Test(WaitToken);
- spawn(move || {
- let x = wt;
- println!("Hello, World!");
- });
-}
+++ /dev/null
-// The dummy functions are used to avoid adding new cfail files.
-// What happens is that the compiler attempts to squash duplicates and some
-// 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)]
-
-use std::marker::Send;
-
-struct Outer<T: Send>(T);
-
-struct Outer2<T>(T);
-
-unsafe impl<T: Send> Sync for Outer2<T> {}
-
-fn is_send<T: Send>(_: T) {}
-fn is_sync<T: Sync>(_: T) {}
-
-fn dummy() {
- struct TestType;
- impl !Send for TestType {}
-
- Outer(TestType);
- //~^ ERROR `dummy::TestType` cannot be sent between threads safely
- //~| ERROR `dummy::TestType` cannot be sent between threads safely
-}
-
-fn dummy1b() {
- struct TestType;
- impl !Send for TestType {}
-
- is_send(TestType);
- //~^ ERROR `dummy1b::TestType` cannot be sent between threads safely
-}
-
-fn dummy1c() {
- struct TestType;
- impl !Send for TestType {}
-
- is_send((8, TestType));
- //~^ ERROR `dummy1c::TestType` cannot be sent between threads safely
-}
-
-fn dummy2() {
- struct TestType;
- impl !Send for TestType {}
-
- is_send(Box::new(TestType));
- //~^ ERROR `dummy2::TestType` cannot be sent between threads safely
-}
-
-fn dummy3() {
- struct TestType;
- impl !Send for TestType {}
-
- is_send(Box::new(Outer2(TestType)));
- //~^ ERROR `dummy3::TestType` cannot be sent between threads safely
-}
-
-fn main() {
- struct TestType;
- impl !Send for TestType {}
-
- // This will complain about a missing Send impl because `Sync` is implement *just*
- // for T that are `Send`. Look at #20366 and #19950
- is_sync(Outer2(TestType));
- //~^ ERROR `main::TestType` cannot be sent between threads safely
-}
+++ /dev/null
-error[E0277]: `dummy::TestType` cannot be sent between threads safely
- --> $DIR/traits-negative-impls.rs:23:11
- |
-LL | struct Outer<T: Send>(T);
- | ------------------------- required by `Outer`
-...
-LL | Outer(TestType);
- | ^^^^^^^^ `dummy::TestType` cannot be sent between threads safely
- |
- = help: the trait `std::marker::Send` is not implemented for `dummy::TestType`
-
-error[E0277]: `dummy::TestType` cannot be sent between threads safely
- --> $DIR/traits-negative-impls.rs:23:5
- |
-LL | struct Outer<T: Send>(T);
- | ------------------------- required by `Outer`
-...
-LL | Outer(TestType);
- | ^^^^^^^^^^^^^^^ `dummy::TestType` cannot be sent between threads safely
- |
- = help: the trait `std::marker::Send` is not implemented for `dummy::TestType`
-
-error[E0277]: `dummy1b::TestType` cannot be sent between threads safely
- --> $DIR/traits-negative-impls.rs:32:13
- |
-LL | fn is_send<T: Send>(_: T) {}
- | ------- ---- required by this bound in `is_send`
-...
-LL | is_send(TestType);
- | ^^^^^^^^ `dummy1b::TestType` cannot be sent between threads safely
- |
- = help: the trait `std::marker::Send` is not implemented for `dummy1b::TestType`
-
-error[E0277]: `dummy1c::TestType` cannot be sent between threads safely
- --> $DIR/traits-negative-impls.rs:40:13
- |
-LL | fn is_send<T: Send>(_: T) {}
- | ------- ---- required by this bound in `is_send`
-...
-LL | is_send((8, TestType));
- | ^^^^^^^^^^^^^ `dummy1c::TestType` cannot be sent between threads safely
- |
- = help: within `({integer}, dummy1c::TestType)`, the trait `std::marker::Send` is not implemented for `dummy1c::TestType`
- = note: required because it appears within the type `({integer}, dummy1c::TestType)`
-
-error[E0277]: `dummy2::TestType` cannot be sent between threads safely
- --> $DIR/traits-negative-impls.rs:48:13
- |
-LL | fn is_send<T: Send>(_: T) {}
- | ------- ---- required by this bound in `is_send`
-...
-LL | is_send(Box::new(TestType));
- | ^^^^^^^^^^^^^^^^^^
- | |
- | expected an implementor of trait `std::marker::Send`
- | help: consider borrowing here: `&Box::new(TestType)`
- |
- = note: the trait bound `dummy2::TestType: std::marker::Send` is not satisfied
- = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<dummy2::TestType>`
- = note: required because it appears within the type `std::boxed::Box<dummy2::TestType>`
-
-error[E0277]: `dummy3::TestType` cannot be sent between threads safely
- --> $DIR/traits-negative-impls.rs:56:13
- |
-LL | fn is_send<T: Send>(_: T) {}
- | ------- ---- required by this bound in `is_send`
-...
-LL | is_send(Box::new(Outer2(TestType)));
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `dummy3::TestType` cannot be sent between threads safely
- |
- = help: within `Outer2<dummy3::TestType>`, the trait `std::marker::Send` is not implemented for `dummy3::TestType`
- = note: required because it appears within the type `Outer2<dummy3::TestType>`
- = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<Outer2<dummy3::TestType>>`
- = note: required because it appears within the type `std::boxed::Box<Outer2<dummy3::TestType>>`
-
-error[E0277]: `main::TestType` cannot be sent between threads safely
- --> $DIR/traits-negative-impls.rs:66:13
- |
-LL | fn is_sync<T: Sync>(_: T) {}
- | ------- ---- required by this bound in `is_sync`
-...
-LL | is_sync(Outer2(TestType));
- | ^^^^^^^^^^^^^^^^
- | |
- | expected an implementor of trait `std::marker::Sync`
- | help: consider borrowing here: `&Outer2(TestType)`
- |
- = note: the trait bound `main::TestType: std::marker::Sync` is not satisfied
- = note: required because of the requirements on the impl of `std::marker::Sync` for `Outer2<main::TestType>`
-
-error: aborting due to 7 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
+++ /dev/null
-#![feature(optin_builtin_traits)]
-
-struct TestType;
-
-trait TestTrait {
- fn dummy(&self) { }
-}
-
-impl !TestTrait for TestType {}
-//~^ ERROR invalid negative impl
-
-fn main() {}
+++ /dev/null
-error[E0192]: invalid negative impl
- --> $DIR/typeck-negative-impls-builtin.rs:9:6
- |
-LL | impl !TestTrait for TestType {}
- | ^^^^^^^^^^
- |
- = note: negative impls are only allowed for auto traits, like `Send` and `Sync`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0192`.