diff options
| author | Michael Goulet <michael@errs.io> | 2025-02-28 02:43:12 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-03-04 18:04:07 +0000 |
| commit | 05a80608b36f71f49e6cc8d586f54c023264ac12 (patch) | |
| tree | 44aabd80068abc07e319cec697ce0f9de9e78f4e | |
| parent | 3d62b279ddc2095b94aa5921540b27f3003365ff (diff) | |
| download | rust-05a80608b36f71f49e6cc8d586f54c023264ac12.tar.gz rust-05a80608b36f71f49e6cc8d586f54c023264ac12.zip | |
Make rustdoc tests use always applicable negative auto impls
8 files changed, 102 insertions, 62 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/always_applicable.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs index 64377ffa347..ba5b61d3fce 100644 --- a/compiler/rustc_hir_analysis/src/check/always_applicable.rs +++ b/compiler/rustc_hir_analysis/src/check/always_applicable.rs @@ -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", ); diff --git a/tests/rustdoc/impl-parts-crosscrate.rs b/tests/rustdoc/impl-parts-crosscrate.rs index 49752ab75d5..631c8bb3eb3 100644 --- a/tests/rustdoc/impl-parts-crosscrate.rs +++ b/tests/rustdoc/impl-parts-crosscrate.rs @@ -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 diff --git a/tests/rustdoc/impl-parts.rs b/tests/rustdoc/impl-parts.rs index 820f51008a4..4f281bfd63c 100644 --- a/tests/rustdoc/impl-parts.rs +++ b/tests/rustdoc/impl-parts.rs @@ -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," diff --git a/tests/ui/coherence/coherence-overlap-negative-impls.rs b/tests/ui/coherence/coherence-overlap-negative-impls.rs deleted file mode 100644 index ba90a37cb2a..00000000000 --- a/tests/ui/coherence/coherence-overlap-negative-impls.rs +++ /dev/null @@ -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() {} diff --git a/tests/ui/coherence/coherence-overlap-negative-impls.stderr b/tests/ui/coherence/coherence-overlap-negative-impls.stderr deleted file mode 100644 index fe22cf61b75..00000000000 --- a/tests/ui/coherence/coherence-overlap-negative-impls.stderr +++ /dev/null @@ -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`. diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.rs b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.rs new file mode 100644 index 00000000000..cd675a5efd1 --- /dev/null +++ b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.rs @@ -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() {} diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.stderr b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.stderr new file mode 100644 index 00000000000..ef783e90155 --- /dev/null +++ b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.stderr @@ -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`. diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-validity.rs b/tests/ui/traits/negative-impls/negated-auto-traits-validity.rs new file mode 100644 index 00000000000..76996b5593e --- /dev/null +++ b/tests/ui/traits/negative-impls/negated-auto-traits-validity.rs @@ -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() {} |
