mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-27 07:03:45 +00:00
permit negative impls for non-auto traits
This commit is contained in:
parent
a17dd36084
commit
e8a05e201e
@ -227,4 +227,9 @@ mod impls {
|
||||
*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 {}
|
||||
}
|
||||
|
@ -81,6 +81,10 @@ impl<T: ?Sized> Deref for &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;
|
||||
|
@ -97,7 +97,6 @@ E0184: include_str!("./error_codes/E0184.md"),
|
||||
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"),
|
||||
@ -426,6 +425,8 @@ E0745: include_str!("./error_codes/E0745.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
|
||||
@ -460,6 +461,7 @@ E0748: include_str!("./error_codes/E0748.md"),
|
||||
// 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,
|
||||
|
4
src/librustc_error_codes/error_codes/E0749.md
Normal file
4
src/librustc_error_codes/error_codes/E0749.md
Normal file
@ -0,0 +1,4 @@
|
||||
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.
|
4
src/librustc_error_codes/error_codes/E0750.md
Normal file
4
src/librustc_error_codes/error_codes/E0750.md
Normal file
@ -0,0 +1,4 @@
|
||||
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.
|
@ -1659,11 +1659,14 @@ fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: DefId, span:
|
||||
_ => 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" },
|
||||
));
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1841,8 +1844,8 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span)
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -1971,6 +1974,24 @@ fn check_impl_items_against_trait<'tcx>(
|
||||
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);
|
||||
|
||||
@ -2010,7 +2031,7 @@ fn check_impl_items_against_trait<'tcx>(
|
||||
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()
|
||||
);
|
||||
@ -3554,7 +3575,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
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
|
||||
);
|
||||
|
||||
@ -4705,7 +4726,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
err.span_label(
|
||||
fn_span,
|
||||
"implicitly returns `()` as its body has no tail or `return` \
|
||||
expression",
|
||||
expression",
|
||||
);
|
||||
}
|
||||
},
|
||||
@ -5577,11 +5598,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
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,
|
||||
));
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5767,7 +5791,7 @@ fn fatally_break_rust(sess: &Session) {
|
||||
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 {}",
|
||||
|
@ -124,18 +124,16 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
|
||||
}
|
||||
(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, _) => {
|
||||
@ -902,13 +900,13 @@ fn check_opaque_types<'fcx, 'tcx>(
|
||||
.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 {
|
||||
@ -923,13 +921,13 @@ fn check_opaque_types<'fcx, 'tcx>(
|
||||
.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,
|
||||
),
|
||||
)
|
||||
@ -944,7 +942,7 @@ fn check_opaque_types<'fcx, 'tcx>(
|
||||
.struct_span_err(
|
||||
span,
|
||||
"non-defining opaque type use \
|
||||
in defining scope",
|
||||
in defining scope",
|
||||
)
|
||||
.span_note(spans, "lifetime used multiple times")
|
||||
.emit();
|
||||
@ -1030,7 +1028,7 @@ fn check_method_receiver<'fcx, 'tcx>(
|
||||
span,
|
||||
&format!(
|
||||
"`{}` cannot be used as the type of `self` without \
|
||||
the `arbitrary_self_types` feature",
|
||||
the `arbitrary_self_types` feature",
|
||||
receiver_ty,
|
||||
),
|
||||
)
|
||||
|
@ -1,12 +0,0 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait Trait {
|
||||
type Bar;
|
||||
}
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl !Trait for Foo { } //~ ERROR E0192
|
||||
|
||||
fn main() {
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
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`.
|
@ -8,8 +8,9 @@ default impl S {} //~ ERROR inherent impls cannot be `default`
|
||||
|
||||
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() {}
|
||||
|
@ -24,14 +24,18 @@ LL | default impl !Send for Z {}
|
||||
| |
|
||||
| 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 !Send for Z {}
|
||||
| ^^^^^^^ ^
|
||||
|
||||
error[E0750]: negative impls cannot be default impls
|
||||
--> $DIR/validation.rs:14:14
|
||||
|
|
||||
LL | default impl !Tr for S {}
|
||||
| ^^^
|
||||
|
|
||||
= note: negative impls are only allowed for auto traits, like `Send` and `Sync`
|
||||
| ^^^^^^^ ^
|
||||
|
||||
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`.
|
||||
|
@ -12,7 +12,6 @@ trait TestTrait {}
|
||||
unsafe impl !Send for TestType {}
|
||||
//~^ ERROR negative impls cannot be unsafe
|
||||
impl !TestTrait for TestType {}
|
||||
//~^ ERROR invalid negative impl
|
||||
|
||||
struct TestType2<T>(T);
|
||||
|
||||
@ -22,6 +21,5 @@ impl<T> !TestType2<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() {}
|
||||
|
@ -16,7 +16,7 @@ LL | unsafe impl !Send for TestType {}
|
||||
| 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
|
||||
@ -24,7 +24,7 @@ LL | impl<T> !TestType2<T> {}
|
||||
| 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> {}
|
||||
| ------ -^^^^
|
||||
@ -32,23 +32,6 @@ 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: aborting due to 4 previous errors
|
||||
|
||||
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
|
||||
|
||||
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`.
|
||||
|
@ -0,0 +1,6 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
pub trait ForeignTrait { }
|
||||
|
||||
impl ForeignTrait for u32 { }
|
||||
impl !ForeignTrait for String {}
|
@ -1,5 +1,5 @@
|
||||
error[E0277]: `dummy::TestType` cannot be sent between threads safely
|
||||
--> $DIR/traits-negative-impls.rs:23:11
|
||||
--> $DIR/negated-auto-traits-error.rs:23:11
|
||||
|
|
||||
LL | struct Outer<T: Send>(T);
|
||||
| ------------------------- required by `Outer`
|
||||
@ -10,7 +10,7 @@ LL | Outer(TestType);
|
||||
= 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
|
||||
--> $DIR/negated-auto-traits-error.rs:23:5
|
||||
|
|
||||
LL | struct Outer<T: Send>(T);
|
||||
| ------------------------- required by `Outer`
|
||||
@ -21,7 +21,7 @@ LL | Outer(TestType);
|
||||
= 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
|
||||
--> $DIR/negated-auto-traits-error.rs:32:13
|
||||
|
|
||||
LL | fn is_send<T: Send>(_: T) {}
|
||||
| ------- ---- required by this bound in `is_send`
|
||||
@ -32,7 +32,7 @@ LL | is_send(TestType);
|
||||
= 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
|
||||
--> $DIR/negated-auto-traits-error.rs:40:13
|
||||
|
|
||||
LL | fn is_send<T: Send>(_: T) {}
|
||||
| ------- ---- required by this bound in `is_send`
|
||||
@ -44,7 +44,7 @@ LL | is_send((8, 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
|
||||
--> $DIR/negated-auto-traits-error.rs:48:13
|
||||
|
|
||||
LL | fn is_send<T: Send>(_: T) {}
|
||||
| ------- ---- required by this bound in `is_send`
|
||||
@ -60,7 +60,7 @@ LL | is_send(Box::new(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
|
||||
--> $DIR/negated-auto-traits-error.rs:56:13
|
||||
|
|
||||
LL | fn is_send<T: Send>(_: T) {}
|
||||
| ------- ---- required by this bound in `is_send`
|
||||
@ -74,7 +74,7 @@ LL | is_send(Box::new(Outer2(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
|
||||
--> $DIR/negated-auto-traits-error.rs:66:13
|
||||
|
|
||||
LL | fn is_sync<T: Sync>(_: T) {}
|
||||
| ------- ---- required by this bound in `is_sync`
|
10
src/test/ui/traits/negative-impls/negative-default-impls.rs
Normal file
10
src/test/ui/traits/negative-impls/negative-default-impls.rs
Normal file
@ -0,0 +1,10 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(specialization)]
|
||||
|
||||
trait MyTrait {
|
||||
type Foo;
|
||||
}
|
||||
|
||||
default impl !MyTrait for u32 {} //~ ERROR negative impls cannot be default impls
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,9 @@
|
||||
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`.
|
@ -0,0 +1,13 @@
|
||||
#![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() { }
|
@ -0,0 +1,12 @@
|
||||
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`.
|
@ -0,0 +1,14 @@
|
||||
#![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() { }
|
@ -0,0 +1,11 @@
|
||||
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`.
|
11
src/test/ui/traits/negative-impls/no-items.rs
Normal file
11
src/test/ui/traits/negative-impls/no-items.rs
Normal file
@ -0,0 +1,11 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait MyTrait {
|
||||
type Foo;
|
||||
}
|
||||
|
||||
impl !MyTrait for u32 {
|
||||
type Foo = i32; //~ ERROR negative impls cannot have any items
|
||||
}
|
||||
|
||||
fn main() {}
|
9
src/test/ui/traits/negative-impls/no-items.stderr
Normal file
9
src/test/ui/traits/negative-impls/no-items.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
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`.
|
@ -0,0 +1,26 @@
|
||||
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);
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
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`.
|
@ -0,0 +1,33 @@
|
||||
// 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!");
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
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`.
|
@ -0,0 +1,9 @@
|
||||
#![feature(specialization)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait MyTrait { }
|
||||
|
||||
impl<T> !MyTrait for T { }
|
||||
impl MyTrait for u32 { } //~ ERROR conflicting implementations
|
||||
|
||||
fn main() { }
|
@ -0,0 +1,11 @@
|
||||
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`.
|
@ -0,0 +1,21 @@
|
||||
#![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() { }
|
@ -0,0 +1,11 @@
|
||||
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`.
|
@ -1,12 +1,14 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
struct TestType;
|
||||
|
||||
trait TestTrait {
|
||||
fn dummy(&self) { }
|
||||
fn dummy(&self) {}
|
||||
}
|
||||
|
||||
impl !TestTrait for TestType {}
|
||||
//~^ ERROR invalid negative impl
|
||||
|
||||
fn main() {}
|
@ -1,11 +0,0 @@
|
||||
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`.
|
Loading…
Reference in New Issue
Block a user