Make rustdoc tests use always applicable negative auto impls
This commit is contained in:
parent
3d62b279dd
commit
05a80608b3
8 changed files with 102 additions and 62 deletions
|
@ -140,7 +140,7 @@ fn ensure_impl_params_and_item_params_correspond<'tcx>(
|
|||
return Ok(());
|
||||
};
|
||||
|
||||
let drop_impl_span = tcx.def_span(impl_def_id);
|
||||
let impl_span = tcx.def_span(impl_def_id);
|
||||
let item_span = tcx.def_span(adt_def_id);
|
||||
let self_descr = tcx.def_descr(adt_def_id);
|
||||
let polarity = match tcx.impl_polarity(impl_def_id) {
|
||||
|
@ -151,7 +151,7 @@ fn ensure_impl_params_and_item_params_correspond<'tcx>(
|
|||
.item_name(tcx.trait_id_of_impl(impl_def_id.to_def_id()).expect("expected impl of trait"));
|
||||
let mut err = struct_span_code_err!(
|
||||
tcx.dcx(),
|
||||
drop_impl_span,
|
||||
impl_span,
|
||||
E0366,
|
||||
"`{polarity}{trait_name}` impls cannot be specialized",
|
||||
);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
extern crate rustdoc_impl_parts_crosscrate;
|
||||
|
||||
pub struct Bar<T> { t: T }
|
||||
pub struct Bar<T: Copy + Send> { t: T }
|
||||
|
||||
// The output file is html embedded in javascript, so the html tags
|
||||
// aren't stripped by the processing script and we can't check for the
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
pub auto trait AnAutoTrait {}
|
||||
|
||||
pub struct Foo<T> { field: T }
|
||||
pub struct Foo<T: Clone + Sync> { field: T }
|
||||
|
||||
//@ has impl_parts/struct.Foo.html '//*[@class="impl"]//h3[@class="code-header"]' \
|
||||
// "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone,"
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
// Should fail. The `0` and `1` impls overlap, violating coherence. Eg, with
|
||||
// `T = Test, F = ()`, all bounds are true, making both impls applicable.
|
||||
// `Test: Fold<Nil>`, `Test: Fold<()>` are true because of `2`.
|
||||
// `Is<Test>: NotNil` is true because of `auto trait` and lack of negative impl.
|
||||
|
||||
#![feature(negative_impls)]
|
||||
#![feature(auto_traits)]
|
||||
|
||||
struct Nil;
|
||||
struct Cons<H>(H);
|
||||
struct Test;
|
||||
|
||||
trait Fold<F> {}
|
||||
|
||||
impl<T, F> Fold<F> for Cons<T>
|
||||
// 0
|
||||
where
|
||||
T: Fold<Nil>,
|
||||
{
|
||||
}
|
||||
|
||||
impl<T, F> Fold<F> for Cons<T>
|
||||
// 1
|
||||
where
|
||||
T: Fold<F>,
|
||||
private::Is<T>: private::NotNil,
|
||||
{
|
||||
}
|
||||
|
||||
impl<F> Fold<F> for Test {} // 2
|
||||
|
||||
mod private {
|
||||
use crate::Nil;
|
||||
|
||||
pub struct Is<T>(T);
|
||||
pub auto trait NotNil {}
|
||||
|
||||
impl !NotNil for Is<Nil> {}
|
||||
//~^ ERROR `!NotNil` impls cannot be specialized
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -1,16 +0,0 @@
|
|||
error[E0366]: `!NotNil` impls cannot be specialized
|
||||
--> $DIR/coherence-overlap-negative-impls.rs:38:5
|
||||
|
|
||||
LL | impl !NotNil for Is<Nil> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `Nil` is not a generic parameter
|
||||
note: use the same sequence of generic lifetime, type and const parameters as the struct definition
|
||||
--> $DIR/coherence-overlap-negative-impls.rs:35:5
|
||||
|
|
||||
LL | pub struct Is<T>(T);
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0366`.
|
|
@ -0,0 +1,22 @@
|
|||
#![feature(auto_traits, negative_impls)]
|
||||
|
||||
auto trait Foo {}
|
||||
|
||||
struct AdditionalLt<'a, T>(&'a (), T);
|
||||
impl<'a, T: 'a> !Foo for AdditionalLt<'a, T> {}
|
||||
//~^ ERROR `!Foo` impl requires `T: 'a` but the struct it is implemented for does not
|
||||
|
||||
struct AdditionalBound<T>(T);
|
||||
trait Bound {}
|
||||
impl<T: Bound> !Foo for AdditionalBound<T> {}
|
||||
//~^ ERROR `!Foo` impl requires `T: Bound` but the struct it is implemented for does not
|
||||
|
||||
struct TwoParam<T, U>(T, U);
|
||||
impl<T> !Foo for TwoParam<T, T> {}
|
||||
//~^ ERROR `!Foo` impls cannot be specialized
|
||||
|
||||
struct ConcreteParam<T>(T);
|
||||
impl !Foo for ConcreteParam<i32> {}
|
||||
//~^ ERROR `!Foo` impls cannot be specialized
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,54 @@
|
|||
error[E0367]: `!Foo` impl requires `T: 'a` but the struct it is implemented for does not
|
||||
--> $DIR/negated-auto-traits-validity-error.rs:6:13
|
||||
|
|
||||
LL | impl<'a, T: 'a> !Foo for AdditionalLt<'a, T> {}
|
||||
| ^^
|
||||
|
|
||||
note: the implementor must specify the same requirement
|
||||
--> $DIR/negated-auto-traits-validity-error.rs:5:1
|
||||
|
|
||||
LL | struct AdditionalLt<'a, T>(&'a (), T);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0367]: `!Foo` impl requires `T: Bound` but the struct it is implemented for does not
|
||||
--> $DIR/negated-auto-traits-validity-error.rs:11:9
|
||||
|
|
||||
LL | impl<T: Bound> !Foo for AdditionalBound<T> {}
|
||||
| ^^^^^
|
||||
|
|
||||
note: the implementor must specify the same requirement
|
||||
--> $DIR/negated-auto-traits-validity-error.rs:9:1
|
||||
|
|
||||
LL | struct AdditionalBound<T>(T);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0366]: `!Foo` impls cannot be specialized
|
||||
--> $DIR/negated-auto-traits-validity-error.rs:15:1
|
||||
|
|
||||
LL | impl<T> !Foo for TwoParam<T, T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `T` is mentioned multiple times
|
||||
note: use the same sequence of generic lifetime, type and const parameters as the struct definition
|
||||
--> $DIR/negated-auto-traits-validity-error.rs:14:1
|
||||
|
|
||||
LL | struct TwoParam<T, U>(T, U);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0366]: `!Foo` impls cannot be specialized
|
||||
--> $DIR/negated-auto-traits-validity-error.rs:19:1
|
||||
|
|
||||
LL | impl !Foo for ConcreteParam<i32> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `i32` is not a generic parameter
|
||||
note: use the same sequence of generic lifetime, type and const parameters as the struct definition
|
||||
--> $DIR/negated-auto-traits-validity-error.rs:18:1
|
||||
|
|
||||
LL | struct ConcreteParam<T>(T);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0366, E0367.
|
||||
For more information about an error, try `rustc --explain E0366`.
|
|
@ -0,0 +1,22 @@
|
|||
//@ check-pass
|
||||
|
||||
#![feature(auto_traits, negative_impls)]
|
||||
|
||||
auto trait Foo {}
|
||||
auto trait Bar {}
|
||||
|
||||
struct NeedsOutlives<'a, T>(&'a T);
|
||||
|
||||
impl<'a, T: 'a> !Foo for NeedsOutlives<'a, T> {}
|
||||
|
||||
// Leaving out the lifetime bound
|
||||
impl<'a, T> !Bar for NeedsOutlives<'a, T> {}
|
||||
|
||||
struct NeedsSend<T: Send>(T);
|
||||
|
||||
impl<T: Send> !Foo for NeedsSend<T> {}
|
||||
|
||||
// Leaving off the trait bound
|
||||
impl<T> !Bar for NeedsSend<T> {}
|
||||
|
||||
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue