make a custom error for overlap with negative impls
This commit is contained in:
parent
e8a05e201e
commit
65071708f8
|
@ -427,6 +427,7 @@ 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"),
|
||||
E0751: include_str!("./error_codes/E0751.md"),
|
||||
;
|
||||
// E0006, // merged with E0005
|
||||
// E0008, // cannot bind by-move into a pattern guard
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
There are both a positive and negative trait implementation for the same type.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0748
|
||||
trait MyTrait {}
|
||||
impl MyTrait for i32 { }
|
||||
impl !MyTrait for i32 { }
|
||||
```
|
||||
|
||||
Negative implementations are a promise that the trait will never be
|
||||
implemented for the given types.
|
|
@ -324,86 +324,7 @@ pub(super) fn specialization_graph_provider(
|
|||
};
|
||||
|
||||
if let Some(overlap) = overlap {
|
||||
let impl_span =
|
||||
tcx.sess.source_map().guess_head_span(tcx.span_of_impl(impl_def_id).unwrap());
|
||||
|
||||
// Work to be done after we've built the DiagnosticBuilder. We have to define it
|
||||
// now because the struct_lint methods don't return back the DiagnosticBuilder
|
||||
// that's passed in.
|
||||
let decorate = |err: LintDiagnosticBuilder<'_>| {
|
||||
let msg = format!(
|
||||
"conflicting implementations of trait `{}`{}:{}",
|
||||
overlap.trait_desc,
|
||||
overlap
|
||||
.self_desc
|
||||
.clone()
|
||||
.map_or(String::new(), |ty| { format!(" for type `{}`", ty) }),
|
||||
match used_to_be_allowed {
|
||||
Some(FutureCompatOverlapErrorKind::Issue33140) => " (E0119)",
|
||||
_ => "",
|
||||
}
|
||||
);
|
||||
let mut err = err.build(&msg);
|
||||
match tcx.span_of_impl(overlap.with_impl) {
|
||||
Ok(span) => {
|
||||
err.span_label(
|
||||
tcx.sess.source_map().guess_head_span(span),
|
||||
"first implementation here".to_string(),
|
||||
);
|
||||
|
||||
err.span_label(
|
||||
impl_span,
|
||||
format!(
|
||||
"conflicting implementation{}",
|
||||
overlap
|
||||
.self_desc
|
||||
.map_or(String::new(), |ty| format!(" for `{}`", ty))
|
||||
),
|
||||
);
|
||||
}
|
||||
Err(cname) => {
|
||||
let msg = match to_pretty_impl_header(tcx, overlap.with_impl) {
|
||||
Some(s) => format!(
|
||||
"conflicting implementation in crate `{}`:\n- {}",
|
||||
cname, s
|
||||
),
|
||||
None => format!("conflicting implementation in crate `{}`", cname),
|
||||
};
|
||||
err.note(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
for cause in &overlap.intercrate_ambiguity_causes {
|
||||
cause.add_intercrate_ambiguity_hint(&mut err);
|
||||
}
|
||||
|
||||
if overlap.involves_placeholder {
|
||||
coherence::add_placeholder_note(&mut err);
|
||||
}
|
||||
err.emit()
|
||||
};
|
||||
|
||||
match used_to_be_allowed {
|
||||
None => {
|
||||
sg.has_errored = true;
|
||||
let err = struct_span_err!(tcx.sess, impl_span, E0119, "");
|
||||
decorate(LintDiagnosticBuilder::new(err));
|
||||
}
|
||||
Some(kind) => {
|
||||
let lint = match kind {
|
||||
FutureCompatOverlapErrorKind::Issue33140 => {
|
||||
ORDER_DEPENDENT_TRAIT_OBJECTS
|
||||
}
|
||||
FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK,
|
||||
};
|
||||
tcx.struct_span_lint_hir(
|
||||
lint,
|
||||
tcx.hir().as_local_hir_id(impl_def_id).unwrap(),
|
||||
impl_span,
|
||||
decorate,
|
||||
)
|
||||
}
|
||||
};
|
||||
report_overlap_conflict(tcx, overlap, impl_def_id, used_to_be_allowed, &mut sg);
|
||||
}
|
||||
} else {
|
||||
let parent = tcx.impl_parent(impl_def_id).unwrap_or(trait_id);
|
||||
|
@ -414,6 +335,170 @@ pub(super) fn specialization_graph_provider(
|
|||
tcx.arena.alloc(sg)
|
||||
}
|
||||
|
||||
fn report_overlap_conflict(
|
||||
tcx: TyCtxt<'_>,
|
||||
overlap: OverlapError,
|
||||
impl_def_id: DefId,
|
||||
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
|
||||
sg: &mut specialization_graph::Graph,
|
||||
) {
|
||||
let impl_polarity = tcx.impl_polarity(impl_def_id);
|
||||
let other_polarity = tcx.impl_polarity(overlap.with_impl);
|
||||
match (impl_polarity, other_polarity) {
|
||||
(ty::ImplPolarity::Negative, ty::ImplPolarity::Positive) => {
|
||||
report_negative_positive_conflict(
|
||||
tcx,
|
||||
&overlap,
|
||||
impl_def_id,
|
||||
impl_def_id,
|
||||
overlap.with_impl,
|
||||
sg,
|
||||
);
|
||||
}
|
||||
|
||||
(ty::ImplPolarity::Positive, ty::ImplPolarity::Negative) => {
|
||||
report_negative_positive_conflict(
|
||||
tcx,
|
||||
&overlap,
|
||||
impl_def_id,
|
||||
overlap.with_impl,
|
||||
impl_def_id,
|
||||
sg,
|
||||
);
|
||||
}
|
||||
|
||||
_ => {
|
||||
report_conflicting_impls(tcx, overlap, impl_def_id, used_to_be_allowed, sg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn report_negative_positive_conflict(
|
||||
tcx: TyCtxt<'_>,
|
||||
overlap: &OverlapError,
|
||||
local_impl_def_id: DefId,
|
||||
negative_impl_def_id: DefId,
|
||||
positive_impl_def_id: DefId,
|
||||
sg: &mut specialization_graph::Graph,
|
||||
) {
|
||||
let impl_span =
|
||||
tcx.sess.source_map().guess_head_span(tcx.span_of_impl(local_impl_def_id).unwrap());
|
||||
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
impl_span,
|
||||
E0748,
|
||||
"found both positive and negative implementation of trait `{}`{}:",
|
||||
overlap.trait_desc,
|
||||
overlap.self_desc.clone().map_or(String::new(), |ty| format!(" for type `{}`", ty))
|
||||
);
|
||||
|
||||
match tcx.span_of_impl(negative_impl_def_id) {
|
||||
Ok(span) => {
|
||||
err.span_label(
|
||||
tcx.sess.source_map().guess_head_span(span),
|
||||
"negative implementation here".to_string(),
|
||||
);
|
||||
}
|
||||
Err(cname) => {
|
||||
err.note(&format!("negative implementation in crate `{}`", cname));
|
||||
}
|
||||
}
|
||||
|
||||
match tcx.span_of_impl(positive_impl_def_id) {
|
||||
Ok(span) => {
|
||||
err.span_label(
|
||||
tcx.sess.source_map().guess_head_span(span),
|
||||
"positive implementation here".to_string(),
|
||||
);
|
||||
}
|
||||
Err(cname) => {
|
||||
err.note(&format!("positive implementation in crate `{}`", cname));
|
||||
}
|
||||
}
|
||||
|
||||
sg.has_errored = true;
|
||||
err.emit();
|
||||
}
|
||||
|
||||
fn report_conflicting_impls(
|
||||
tcx: TyCtxt<'_>,
|
||||
overlap: OverlapError,
|
||||
impl_def_id: DefId,
|
||||
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
|
||||
sg: &mut specialization_graph::Graph,
|
||||
) {
|
||||
let impl_span = tcx.sess.source_map().guess_head_span(tcx.span_of_impl(impl_def_id).unwrap());
|
||||
|
||||
// Work to be done after we've built the DiagnosticBuilder. We have to define it
|
||||
// now because the struct_lint methods don't return back the DiagnosticBuilder
|
||||
// that's passed in.
|
||||
let decorate = |err: LintDiagnosticBuilder<'_>| {
|
||||
let msg = format!(
|
||||
"conflicting implementations of trait `{}`{}:{}",
|
||||
overlap.trait_desc,
|
||||
overlap.self_desc.clone().map_or(String::new(), |ty| { format!(" for type `{}`", ty) }),
|
||||
match used_to_be_allowed {
|
||||
Some(FutureCompatOverlapErrorKind::Issue33140) => " (E0119)",
|
||||
_ => "",
|
||||
}
|
||||
);
|
||||
let mut err = err.build(&msg);
|
||||
match tcx.span_of_impl(overlap.with_impl) {
|
||||
Ok(span) => {
|
||||
err.span_label(
|
||||
tcx.sess.source_map().guess_head_span(span),
|
||||
"first implementation here".to_string(),
|
||||
);
|
||||
|
||||
err.span_label(
|
||||
impl_span,
|
||||
format!(
|
||||
"conflicting implementation{}",
|
||||
overlap.self_desc.map_or(String::new(), |ty| format!(" for `{}`", ty))
|
||||
),
|
||||
);
|
||||
}
|
||||
Err(cname) => {
|
||||
let msg = match to_pretty_impl_header(tcx, overlap.with_impl) {
|
||||
Some(s) => format!("conflicting implementation in crate `{}`:\n- {}", cname, s),
|
||||
None => format!("conflicting implementation in crate `{}`", cname),
|
||||
};
|
||||
err.note(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
for cause in &overlap.intercrate_ambiguity_causes {
|
||||
cause.add_intercrate_ambiguity_hint(&mut err);
|
||||
}
|
||||
|
||||
if overlap.involves_placeholder {
|
||||
coherence::add_placeholder_note(&mut err);
|
||||
}
|
||||
err.emit()
|
||||
};
|
||||
|
||||
match used_to_be_allowed {
|
||||
None => {
|
||||
sg.has_errored = true;
|
||||
let err = struct_span_err!(tcx.sess, impl_span, E0119, "");
|
||||
decorate(LintDiagnosticBuilder::new(err));
|
||||
}
|
||||
Some(kind) => {
|
||||
let lint = match kind {
|
||||
FutureCompatOverlapErrorKind::Issue33140 => ORDER_DEPENDENT_TRAIT_OBJECTS,
|
||||
FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK,
|
||||
};
|
||||
tcx.struct_span_lint_hir(
|
||||
lint,
|
||||
tcx.hir().as_local_hir_id(impl_def_id).unwrap(),
|
||||
impl_span,
|
||||
decorate,
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a
|
||||
/// string.
|
||||
fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String> {
|
||||
|
|
|
@ -6,13 +6,11 @@ trait MyTrait {}
|
|||
|
||||
struct TestType<T>(::std::marker::PhantomData<T>);
|
||||
|
||||
unsafe impl<T: MyTrait+'static> Send for TestType<T> {}
|
||||
unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||
|
||||
impl<T: MyTrait> !Send for TestType<T> {}
|
||||
//~^ ERROR conflicting implementations
|
||||
impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and negative implementation
|
||||
|
||||
unsafe impl<T:'static> Send for TestType<T> {}
|
||||
//~^ ERROR conflicting implementations
|
||||
unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
|
||||
|
||||
impl !Send for TestType<i32> {}
|
||||
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<_>`:
|
||||
error[E0748]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`:
|
||||
--> $DIR/coherence-conflicting-negative-trait-impl.rs:11:1
|
||||
|
|
||||
LL | unsafe impl<T: MyTrait+'static> Send for TestType<T> {}
|
||||
| ---------------------------------------------------- first implementation here
|
||||
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||
| ------------------------------------------------------ positive implementation here
|
||||
LL |
|
||||
LL | impl<T: MyTrait> !Send for TestType<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
|
||||
|
||||
error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<_>`:
|
||||
--> $DIR/coherence-conflicting-negative-trait-impl.rs:14:1
|
||||
--> $DIR/coherence-conflicting-negative-trait-impl.rs:13:1
|
||||
|
|
||||
LL | unsafe impl<T: MyTrait+'static> Send for TestType<T> {}
|
||||
| ---------------------------------------------------- first implementation here
|
||||
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||
| ------------------------------------------------------ first implementation here
|
||||
...
|
||||
LL | unsafe impl<T:'static> Send for TestType<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
|
||||
LL | unsafe impl<T: 'static> Send for TestType<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
Some errors have detailed explanations: E0119, E0748.
|
||||
For more information about an error, try `rustc --explain E0119`.
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
// Check that the issue #33140 hack does not allow unintended things.
|
||||
|
||||
// OK
|
||||
trait Trait0 {
|
||||
}
|
||||
trait Trait0 {}
|
||||
|
||||
impl Trait0 for dyn Send {}
|
||||
impl Trait0 for dyn Send {}
|
||||
|
@ -20,58 +19,49 @@ impl Trait1 for dyn Send {}
|
|||
//~^ ERROR E0119
|
||||
|
||||
// Problem 2: negative impl
|
||||
trait Trait2 {
|
||||
}
|
||||
trait Trait2 {}
|
||||
|
||||
impl Trait2 for dyn Send {}
|
||||
impl !Trait2 for dyn Send {}
|
||||
//~^ ERROR E0119
|
||||
|
||||
//~^ ERROR E0748
|
||||
|
||||
// Problem 3: type parameter
|
||||
trait Trait3<T: ?Sized> {
|
||||
}
|
||||
trait Trait3<T: ?Sized> {}
|
||||
|
||||
impl Trait3<dyn Sync> for dyn Send {}
|
||||
impl Trait3<dyn Sync> for dyn Send {}
|
||||
//~^ ERROR E0119
|
||||
|
||||
// Problem 4a: not a trait object - generic
|
||||
trait Trait4a {
|
||||
}
|
||||
trait Trait4a {}
|
||||
|
||||
impl<T: ?Sized> Trait4a for T {}
|
||||
impl Trait4a for dyn Send {}
|
||||
//~^ ERROR E0119
|
||||
|
||||
// Problem 4b: not a trait object - misc
|
||||
trait Trait4b {
|
||||
}
|
||||
trait Trait4b {}
|
||||
|
||||
impl Trait4b for () {}
|
||||
impl Trait4b for () {}
|
||||
//~^ ERROR E0119
|
||||
|
||||
// Problem 4c: not a principal-less trait object
|
||||
trait Trait4c {
|
||||
}
|
||||
trait Trait4c {}
|
||||
|
||||
impl Trait4c for dyn Trait1 + Send {}
|
||||
impl Trait4c for dyn Trait1 + Send {}
|
||||
//~^ ERROR E0119
|
||||
|
||||
// Problem 4d: lifetimes
|
||||
trait Trait4d {
|
||||
}
|
||||
trait Trait4d {}
|
||||
|
||||
impl<'a> Trait4d for dyn Send + 'a {}
|
||||
impl<'a> Trait4d for dyn Send + 'a {}
|
||||
//~^ ERROR E0119
|
||||
|
||||
|
||||
// Problem 5: where-clauses
|
||||
trait Trait5 {
|
||||
}
|
||||
trait Trait5 {}
|
||||
|
||||
impl Trait5 for dyn Send {}
|
||||
impl Trait5 for dyn Send where u32: Copy {}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
error[E0119]: conflicting implementations of trait `Trait1` for type `(dyn std::marker::Send + 'static)`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:19:1
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:18:1
|
||||
|
|
||||
LL | impl Trait1 for dyn Send {}
|
||||
| ------------------------ first implementation here
|
||||
LL | impl Trait1 for dyn Send {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Trait2` for type `(dyn std::marker::Send + 'static)`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:27:1
|
||||
error[E0748]: found both positive and negative implementation of trait `Trait2` for type `(dyn std::marker::Send + 'static)`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:25:1
|
||||
|
|
||||
LL | impl Trait2 for dyn Send {}
|
||||
| ------------------------ first implementation here
|
||||
| ------------------------ positive implementation here
|
||||
LL | impl !Trait2 for dyn Send {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Trait3<(dyn std::marker::Sync + 'static)>` for type `(dyn std::marker::Send + 'static)`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:36:1
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:32:1
|
||||
|
|
||||
LL | impl Trait3<dyn Sync> for dyn Send {}
|
||||
| ---------------------------------- first implementation here
|
||||
|
@ -23,7 +23,7 @@ LL | impl Trait3<dyn Sync> for dyn Send {}
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Trait4a` for type `(dyn std::marker::Send + 'static)`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:44:1
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:39:1
|
||||
|
|
||||
LL | impl<T: ?Sized> Trait4a for T {}
|
||||
| ----------------------------- first implementation here
|
||||
|
@ -31,7 +31,7 @@ LL | impl Trait4a for dyn Send {}
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Trait4b` for type `()`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:52:1
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:46:1
|
||||
|
|
||||
LL | impl Trait4b for () {}
|
||||
| ------------------- first implementation here
|
||||
|
@ -39,7 +39,7 @@ LL | impl Trait4b for () {}
|
|||
| ^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Trait4c` for type `(dyn Trait1 + std::marker::Send + 'static)`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:60:1
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:53:1
|
||||
|
|
||||
LL | impl Trait4c for dyn Trait1 + Send {}
|
||||
| ---------------------------------- first implementation here
|
||||
|
@ -47,7 +47,7 @@ LL | impl Trait4c for dyn Trait1 + Send {}
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Trait1 + std::marker::Send + 'static)`
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Trait4d` for type `dyn std::marker::Send`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:68:1
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:60:1
|
||||
|
|
||||
LL | impl<'a> Trait4d for dyn Send + 'a {}
|
||||
| ---------------------------------- first implementation here
|
||||
|
@ -55,7 +55,7 @@ LL | impl<'a> Trait4d for dyn Send + 'a {}
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `dyn std::marker::Send`
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Trait5` for type `(dyn std::marker::Send + 'static)`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:77:1
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:67:1
|
||||
|
|
||||
LL | impl Trait5 for dyn Send {}
|
||||
| ------------------------ first implementation here
|
||||
|
@ -64,4 +64,5 @@ LL | impl Trait5 for dyn Send where u32: Copy {}
|
|||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
Some errors have detailed explanations: E0119, E0748.
|
||||
For more information about an error, try `rustc --explain E0119`.
|
||||
|
|
|
@ -6,6 +6,6 @@ trait MyTrait {}
|
|||
struct TestType<T>(::std::marker::PhantomData<T>);
|
||||
|
||||
unsafe impl<T: Clone> Send for TestType<T> {}
|
||||
impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR E0119
|
||||
impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR E0748
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<_>`:
|
||||
error[E0748]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`:
|
||||
--> $DIR/specialization-overlap-negative.rs:9:1
|
||||
|
|
||||
LL | unsafe impl<T: Clone> Send for TestType<T> {}
|
||||
| ------------------------------------------ first implementation here
|
||||
| ------------------------------------------ positive implementation here
|
||||
LL | impl<T: MyTrait> !Send for TestType<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
For more information about this error, try `rustc --explain E0748`.
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
auto trait Foo {}
|
||||
|
||||
impl<T> Foo for T {}
|
||||
impl !Foo for u8 {} //~ ERROR E0119
|
||||
impl !Foo for u8 {} //~ ERROR E0748
|
||||
|
||||
auto trait Bar {}
|
||||
|
||||
impl<T> !Bar for T {}
|
||||
impl Bar for u8 {} //~ ERROR E0119
|
||||
impl Bar for u8 {} //~ ERROR E0748
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
error[E0119]: conflicting implementations of trait `Foo` for type `u8`:
|
||||
error[E0748]: found both positive and negative implementation of trait `Foo` for type `u8`:
|
||||
--> $DIR/specialization-polarity.rs:9:1
|
||||
|
|
||||
LL | impl<T> Foo for T {}
|
||||
| ----------------- first implementation here
|
||||
| ----------------- positive implementation here
|
||||
LL | impl !Foo for u8 {}
|
||||
| ^^^^^^^^^^^^^^^^ conflicting implementation for `u8`
|
||||
| ^^^^^^^^^^^^^^^^ negative implementation here
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Bar` for type `u8`:
|
||||
error[E0748]: found both positive and negative implementation of trait `Bar` for type `u8`:
|
||||
--> $DIR/specialization-polarity.rs:14:1
|
||||
|
|
||||
LL | impl<T> !Bar for T {}
|
||||
| ------------------ first implementation here
|
||||
| ------------------ negative implementation here
|
||||
LL | impl Bar for u8 {}
|
||||
| ^^^^^^^^^^^^^^^ conflicting implementation for `u8`
|
||||
| ^^^^^^^^^^^^^^^ positive implementation here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
For more information about this error, try `rustc --explain E0748`.
|
||||
|
|
|
@ -6,8 +6,8 @@ trait MyTrait {
|
|||
fn foo();
|
||||
}
|
||||
impl<T> MyTrait for T {
|
||||
default fn foo() { }
|
||||
default fn foo() {}
|
||||
}
|
||||
impl !MyTrait for u32 { } //~ ERROR conflicting implementations
|
||||
impl !MyTrait for u32 {} //~ ERROR E0748
|
||||
|
||||
fn main() { }
|
||||
fn main() {}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
error[E0119]: conflicting implementations of trait `MyTrait` for type `u32`:
|
||||
error[E0748]: found both positive and negative implementation of trait `MyTrait` for type `u32`:
|
||||
--> $DIR/negative-specializes-positive-item.rs:11:1
|
||||
|
|
||||
LL | impl<T> MyTrait for T {
|
||||
| --------------------- first implementation here
|
||||
| --------------------- positive implementation here
|
||||
...
|
||||
LL | impl !MyTrait for u32 { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32`
|
||||
LL | impl !MyTrait for u32 {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ negative implementation here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
For more information about this error, try `rustc --explain E0748`.
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
#![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
|
||||
trait MyTrait {}
|
||||
impl<T> MyTrait for T {}
|
||||
impl !MyTrait for u32 {} //~ ERROR E0748
|
||||
|
||||
// The second impl specializes the first, no error.
|
||||
trait MyTrait2 { }
|
||||
impl<T> MyTrait2 for T { }
|
||||
impl MyTrait2 for u32 { }
|
||||
trait MyTrait2 {}
|
||||
impl<T> MyTrait2 for T {}
|
||||
impl MyTrait2 for u32 {}
|
||||
|
||||
fn main() { }
|
||||
fn main() {}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error[E0119]: conflicting implementations of trait `MyTrait` for type `u32`:
|
||||
error[E0748]: found both positive and negative implementation 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`
|
||||
LL | impl<T> MyTrait for T {}
|
||||
| --------------------- positive implementation here
|
||||
LL | impl !MyTrait for u32 {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ negative implementation here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
For more information about this error, try `rustc --explain E0748`.
|
||||
|
|
|
@ -4,13 +4,13 @@ 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
|
||||
impl<'a> Clone for &'a mut MyType<'a> {
|
||||
//~^ ERROR E0748
|
||||
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;
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
error[E0119]: conflicting implementations of trait `std::clone::Clone` for type `&mut MyType<'_>`:
|
||||
error[E0748]: found both positive and negative implementation 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> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ positive implementation here
|
||||
|
|
||||
= note: conflicting implementation in crate `core`:
|
||||
- impl<T> std::clone::Clone for &mut T
|
||||
where T: ?Sized;
|
||||
= note: negative implementation in crate `core`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
For more information about this error, try `rustc --explain E0748`.
|
||||
|
|
|
@ -9,13 +9,13 @@ use std::pin::Pin;
|
|||
|
||||
struct MyType<'a>(Cell<Option<&'a mut MyType<'a>>>, PhantomPinned);
|
||||
|
||||
impl<'a> DerefMut for &'a MyType<'a> { //~ ERROR conflicting implementations
|
||||
impl<'a> DerefMut for &'a MyType<'a> {
|
||||
//~^ ERROR E0748
|
||||
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;
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
error[E0119]: conflicting implementations of trait `std::ops::DerefMut` for type `&MyType<'_>`:
|
||||
error[E0748]: found both positive and negative implementation 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> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ positive implementation here
|
||||
|
|
||||
= note: conflicting implementation in crate `core`:
|
||||
- impl<T> std::ops::DerefMut for &T
|
||||
where T: ?Sized;
|
||||
= note: negative implementation in crate `core`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
For more information about this error, try `rustc --explain E0748`.
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#![feature(specialization)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait MyTrait { }
|
||||
trait MyTrait {}
|
||||
|
||||
impl<T> !MyTrait for T { }
|
||||
impl MyTrait for u32 { } //~ ERROR conflicting implementations
|
||||
impl<T> !MyTrait for T {}
|
||||
impl MyTrait for u32 {} //~ ERROR E0748
|
||||
|
||||
fn main() { }
|
||||
fn main() {}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error[E0119]: conflicting implementations of trait `MyTrait` for type `u32`:
|
||||
error[E0748]: found both positive and negative implementation 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`
|
||||
LL | impl<T> !MyTrait for T {}
|
||||
| ---------------------- negative implementation here
|
||||
LL | impl MyTrait for u32 {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^ positive implementation here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
For more information about this error, try `rustc --explain E0748`.
|
||||
|
|
Loading…
Reference in New Issue