diff options
Diffstat (limited to 'tests/ui/associated-inherent-types')
26 files changed, 504 insertions, 0 deletions
diff --git a/tests/ui/associated-inherent-types/ambiguity.rs b/tests/ui/associated-inherent-types/ambiguity.rs new file mode 100644 index 000000000..73920555b --- /dev/null +++ b/tests/ui/associated-inherent-types/ambiguity.rs @@ -0,0 +1,16 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Wrapper<T>(T); + +impl Wrapper<i32> { + type Foo = i32; +} + +impl Wrapper<()> { + type Foo = (); +} + +fn main() { + let _: Wrapper<_>::Foo = (); //~ ERROR multiple applicable items in scope +} diff --git a/tests/ui/associated-inherent-types/ambiguity.stderr b/tests/ui/associated-inherent-types/ambiguity.stderr new file mode 100644 index 000000000..155c296cb --- /dev/null +++ b/tests/ui/associated-inherent-types/ambiguity.stderr @@ -0,0 +1,20 @@ +error[E0034]: multiple applicable items in scope + --> $DIR/ambiguity.rs:15:24 + | +LL | let _: Wrapper<_>::Foo = (); + | ^^^ multiple `Foo` found + | +note: candidate #1 is defined in an impl for the type `Wrapper<i32>` + --> $DIR/ambiguity.rs:7:5 + | +LL | type Foo = i32; + | ^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Wrapper<()>` + --> $DIR/ambiguity.rs:11:5 + | +LL | type Foo = (); + | ^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0034`. diff --git a/tests/ui/associated-inherent-types/bugs/ice-substitution.rs b/tests/ui/associated-inherent-types/bugs/ice-substitution.rs new file mode 100644 index 000000000..53ac79e05 --- /dev/null +++ b/tests/ui/associated-inherent-types/bugs/ice-substitution.rs @@ -0,0 +1,23 @@ +// known-bug: unknown +// failure-status: 101 +// normalize-stderr-test "note: .*\n\n" -> "" +// normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" +// rustc-env:RUST_BACKTRACE=0 + +// FIXME: I presume a type variable that couldn't be solved by `resolve_vars_if_possible` +// escapes the InferCtxt snapshot. + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Cont<T>(T); + +impl<T: Copy> Cont<T> { + type Out = Vec<T>; +} + +pub fn weird<T: Copy>(x: T) { + let _: Cont<_>::Out = vec![true]; +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr b/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr new file mode 100644 index 000000000..7b0d1c505 --- /dev/null +++ b/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr @@ -0,0 +1,6 @@ +error: the compiler unexpectedly panicked. this is a bug. + +query stack during panic: +#0 [typeck] type-checking `weird` +#1 [typeck_item_bodies] type-checking all item bodies +end of query stack diff --git a/tests/ui/associated-inherent-types/bugs/inference-fail.rs b/tests/ui/associated-inherent-types/bugs/inference-fail.rs new file mode 100644 index 000000000..a920b412b --- /dev/null +++ b/tests/ui/associated-inherent-types/bugs/inference-fail.rs @@ -0,0 +1,15 @@ +// known-bug: unknown + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S<T>(T); + +impl S<()> { + type P = i128; +} + +fn main() { + // We fail to infer `_ == ()` here. + let _: S<_>::P; +} diff --git a/tests/ui/associated-inherent-types/bugs/inference-fail.stderr b/tests/ui/associated-inherent-types/bugs/inference-fail.stderr new file mode 100644 index 000000000..425691bd6 --- /dev/null +++ b/tests/ui/associated-inherent-types/bugs/inference-fail.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/inference-fail.rs:14:14 + | +LL | let _: S<_>::P; + | ^ cannot infer type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs b/tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs new file mode 100644 index 000000000..632dbf385 --- /dev/null +++ b/tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs @@ -0,0 +1,19 @@ +// known-bug: unknown +// check-pass + +// We currently don't region-check inherent associated type projections at all. + +#![feature(inherent_associated_types)] +#![allow(incomplete_features, dead_code)] + +struct S<T>(T); + +impl S<&'static ()> { + type T = (); +} + +fn usr<'a>() { + let _: S::<&'a ()>::T; // this should *fail* but it doesn't! +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs b/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs new file mode 100644 index 000000000..f846bfa41 --- /dev/null +++ b/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs @@ -0,0 +1,41 @@ +// check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// Check that inherent associated types are dispatched on the concrete Self type. + +struct Select<T>(T); + +impl Select<u8> { + type Projection = (); +} + +impl Select<String> { + type Projection = bool; +} + +struct Choose<T>(T); +struct NonCopy; + +impl<T: Copy> Choose<T> { + type Result = Vec<T>; +} + +impl Choose<NonCopy> { + type Result = (); +} + +fn main() { + let _: Select<String>::Projection = false; + let _: Select<u8>::Projection = (); + + let _: Choose<NonCopy>::Result = (); + let _: Choose<bool>::Result = vec![true]; +} + +// Test if we use the correct `ParamEnv` when proving obligations. + +pub fn parameterized<T: Copy>(x: T) { + let _: Choose<T>::Result = vec![x]; +} diff --git a/tests/ui/associated-inherent-types/dispatch-on-self-type-1.rs b/tests/ui/associated-inherent-types/dispatch-on-self-type-1.rs new file mode 100644 index 000000000..9b0fa8dc6 --- /dev/null +++ b/tests/ui/associated-inherent-types/dispatch-on-self-type-1.rs @@ -0,0 +1,39 @@ +// check-pass + +#![feature(inherent_associated_types, auto_traits, negative_impls)] +#![allow(incomplete_features)] + +use std::cmp::Ordering; + +// Check that inherent associated types are dispatched on the concrete Self type. + +struct Select<T, U>(T, U); + +impl<T: Ordinary, U: Ordinary> Select<T, U> { + type Type = (); +} + +impl<T: Ordinary> Select<T, Special> { + type Type = bool; +} + +impl<T: Ordinary> Select<Special, T> { + type Type = Ordering; +} + +impl Select<Special, Special> { + type Type = (bool, bool); +} + +fn main() { + let _: Select<String, Special>::Type = false; + let _: Select<Special, Special>::Type = (true, false); + let _: Select<Special, u8>::Type = Ordering::Equal; + let _: Select<i128, ()>::Type = (); +} + +enum Special {} + +impl !Ordinary for Special {} + +auto trait Ordinary {} diff --git a/tests/ui/associated-inherent-types/dispatch-on-self-type-2.rs b/tests/ui/associated-inherent-types/dispatch-on-self-type-2.rs new file mode 100644 index 000000000..7b205952f --- /dev/null +++ b/tests/ui/associated-inherent-types/dispatch-on-self-type-2.rs @@ -0,0 +1,17 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Parameterized<T, U>(T, U); + +impl Parameterized<(), ()> { + type Output = bool; +} + +impl<T> Parameterized<bool, T> { + type Result = T; +} + +fn main() { + let _: Parameterized<(), ()>::Output = String::new(); //~ ERROR mismatched types + let _: Parameterized<bool, u32>::Result = (); //~ ERROR mismatched types +} diff --git a/tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr b/tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr new file mode 100644 index 000000000..c9a48872a --- /dev/null +++ b/tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr @@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/dispatch-on-self-type-2.rs:15:44 + | +LL | let _: Parameterized<(), ()>::Output = String::new(); + | ----------------------------- ^^^^^^^^^^^^^ expected `bool`, found `String` + | | + | expected due to this + +error[E0308]: mismatched types + --> $DIR/dispatch-on-self-type-2.rs:16:47 + | +LL | let _: Parameterized<bool, u32>::Result = (); + | -------------------------------- ^^ expected `u32`, found `()` + | | + | expected due to this + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.rs b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.rs new file mode 100644 index 000000000..d2efb24c6 --- /dev/null +++ b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.rs @@ -0,0 +1,31 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// Check that it's okay to report “[inherent] associated type […] not found” for inherent associated +// type candidates that are not applicable (due to unsuitable Self type) even if there exists a +// “shadowed” associated type from a trait with the same name since its use would be ambiguous +// anyway if the IAT didn't exist. +// FIXME(inherent_associated_types): Figure out which error would be more helpful here. + +// revisions: shadowed uncovered + +struct S<T>(T); + +trait Tr { + type Pr; +} + +impl<T> Tr for S<T> { + type Pr = (); +} + +#[cfg(shadowed)] +impl S<()> { + type Pr = i32; +} + +fn main() { + let _: S::<bool>::Pr = (); + //[shadowed]~^ ERROR associated type `Pr` not found + //[uncovered]~^^ ERROR ambiguous associated type +} diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr new file mode 100644 index 000000000..3561db354 --- /dev/null +++ b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr @@ -0,0 +1,15 @@ +error[E0220]: associated type `Pr` not found for `S<bool>` in the current scope + --> $DIR/not-found-self-type-differs-shadowing-trait-item.rs:28:23 + | +LL | struct S<T>(T); + | ----------- associated item `Pr` not found for this struct +... +LL | let _: S::<bool>::Pr = (); + | ^^ associated item not found in `S<bool>` + | + = note: the associated type was found for + - `S<()>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0220`. diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.uncovered.stderr b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.uncovered.stderr new file mode 100644 index 000000000..88c72042c --- /dev/null +++ b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.uncovered.stderr @@ -0,0 +1,9 @@ +error[E0223]: ambiguous associated type + --> $DIR/not-found-self-type-differs-shadowing-trait-item.rs:28:12 + | +LL | let _: S::<bool>::Pr = (); + | ^^^^^^^^^^^^^ help: use the fully-qualified path: `<S<bool> as Tr>::Pr` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0223`. diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs.alias.stderr b/tests/ui/associated-inherent-types/not-found-self-type-differs.alias.stderr new file mode 100644 index 000000000..4396435a6 --- /dev/null +++ b/tests/ui/associated-inherent-types/not-found-self-type-differs.alias.stderr @@ -0,0 +1,16 @@ +error[E0220]: associated type `Proj` not found for `Family<Option<()>>` in the current scope + --> $DIR/not-found-self-type-differs.rs:17:34 + | +LL | struct Family<T>(T); + | ---------------- associated item `Proj` not found for this struct +... +LL | type Alias = Family<Option<()>>::Proj; + | ^^^^ associated item not found in `Family<Option<()>>` + | + = note: the associated type was found for + - `Family<()>` + - `Family<Result<T, ()>>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0220`. diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs.local.stderr b/tests/ui/associated-inherent-types/not-found-self-type-differs.local.stderr new file mode 100644 index 000000000..d527db022 --- /dev/null +++ b/tests/ui/associated-inherent-types/not-found-self-type-differs.local.stderr @@ -0,0 +1,16 @@ +error[E0220]: associated type `Proj` not found for `Family<PathBuf>` in the current scope + --> $DIR/not-found-self-type-differs.rs:21:40 + | +LL | struct Family<T>(T); + | ---------------- associated item `Proj` not found for this struct +... +LL | let _: Family<std::path::PathBuf>::Proj = (); + | ^^^^ associated item not found in `Family<PathBuf>` + | + = note: the associated type was found for + - `Family<()>` + - `Family<Result<T, ()>>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0220`. diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs.rs b/tests/ui/associated-inherent-types/not-found-self-type-differs.rs new file mode 100644 index 000000000..93f58dcb6 --- /dev/null +++ b/tests/ui/associated-inherent-types/not-found-self-type-differs.rs @@ -0,0 +1,22 @@ +// revisions: local alias + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Family<T>(T); + +impl Family<()> { + type Proj = (); +} + +impl<T> Family<Result<T, ()>> { + type Proj = Self; +} + +#[cfg(alias)] +type Alias = Family<Option<()>>::Proj; //[alias]~ ERROR associated type `Proj` not found for `Family<Option<()>>` + +fn main() { + #[cfg(local)] + let _: Family<std::path::PathBuf>::Proj = (); //[local]~ ERROR associated type `Proj` not found for `Family<PathBuf>` +} diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.rs b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.rs new file mode 100644 index 000000000..b00830fa1 --- /dev/null +++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.rs @@ -0,0 +1,21 @@ +// Regression test for issue #104251. + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Container<T: ?Sized>(T); + +impl<T> Container<T> { + type Yield = i32; +} + +struct Duple<T, U>(T, U); + +impl<T: Copy, U: Send> Duple<T, U> { + type Combination = (T, U); +} + +fn main() { + let _: Container<[u8]>::Yield = 1; //~ ERROR the associated type `Yield` exists for `Container<[u8]>`, but its trait bounds were not satisfied + let _: Duple<String, std::rc::Rc<str>>::Combination; //~ ERROR the associated type `Combination` exists for `Duple<String, Rc<str>>`, but its trait bounds were not satisfied +} diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr new file mode 100644 index 000000000..736579067 --- /dev/null +++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr @@ -0,0 +1,27 @@ +error: the associated type `Yield` exists for `Container<[u8]>`, but its trait bounds were not satisfied + --> $DIR/not-found-unsatisfied-bounds-0.rs:19:29 + | +LL | struct Container<T: ?Sized>(T); + | --------------------------- associated item `Yield` not found for this struct +... +LL | let _: Container<[u8]>::Yield = 1; + | ^^^^^ associated type cannot be referenced on `Container<[u8]>` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `[u8]: Sized` + +error: the associated type `Combination` exists for `Duple<String, Rc<str>>`, but its trait bounds were not satisfied + --> $DIR/not-found-unsatisfied-bounds-0.rs:20:45 + | +LL | struct Duple<T, U>(T, U); + | ------------------ associated item `Combination` not found for this struct +... +LL | let _: Duple<String, std::rc::Rc<str>>::Combination; + | ^^^^^^^^^^^ associated type cannot be referenced on `Duple<String, Rc<str>>` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `Rc<str>: Send` + `String: Copy` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.rs b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.rs new file mode 100644 index 000000000..c80b1364a --- /dev/null +++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.rs @@ -0,0 +1,18 @@ +// fail-check + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// Test if we use the correct `ParamEnv` when proving obligations. + +fn parameterized<T>() { + let _: Container<T>::Proj = String::new(); //~ ERROR the associated type `Proj` exists for `Container<T>`, but its trait bounds were not satisfied +} + +struct Container<T>(T); + +impl<T: Clone> Container<T> { + type Proj = String; +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr new file mode 100644 index 000000000..230bfa538 --- /dev/null +++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr @@ -0,0 +1,14 @@ +error: the associated type `Proj` exists for `Container<T>`, but its trait bounds were not satisfied + --> $DIR/not-found-unsatisfied-bounds-1.rs:9:26 + | +LL | let _: Container<T>::Proj = String::new(); + | ^^^^ associated type cannot be referenced on `Container<T>` due to unsatisfied trait bounds +... +LL | struct Container<T>(T); + | ------------------- associated item `Proj` not found for this struct + | + = note: the following trait bounds were not satisfied: + `T: Clone` + +error: aborting due to previous error + diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.rs b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.rs new file mode 100644 index 000000000..5b0e8de9c --- /dev/null +++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.rs @@ -0,0 +1,20 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S<A, B>(A, B); +struct Featureless; + +trait One {} +trait Two {} + +impl<T: One> S<Featureless, T> { + type X = (); +} + +impl<T: Two> S<T, Featureless> { + type X = String; +} + +fn main() { + let _: S::<Featureless, Featureless>::X; //~ ERROR the associated type `X` exists for `S<Featureless, Featureless>`, but its trait bounds were not satisfied +} diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr new file mode 100644 index 000000000..3ddab25de --- /dev/null +++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr @@ -0,0 +1,20 @@ +error: the associated type `X` exists for `S<Featureless, Featureless>`, but its trait bounds were not satisfied + --> $DIR/not-found-unsatisfied-bounds-in-multiple-impls.rs:19:43 + | +LL | struct S<A, B>(A, B); + | -------------- associated item `X` not found for this struct +LL | struct Featureless; + | ------------------ + | | + | doesn't satisfy `Featureless: One` + | doesn't satisfy `Featureless: Two` +... +LL | let _: S::<Featureless, Featureless>::X; + | ^ associated type cannot be referenced on `S<Featureless, Featureless>` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `Featureless: One` + `Featureless: Two` + +error: aborting due to previous error + diff --git a/tests/ui/associated-inherent-types/substitute-params-bad.rs b/tests/ui/associated-inherent-types/substitute-params-bad.rs new file mode 100644 index 000000000..00eb1a14d --- /dev/null +++ b/tests/ui/associated-inherent-types/substitute-params-bad.rs @@ -0,0 +1,23 @@ +// Regression test for issue #105305 and for +// https://github.com/rust-lang/rust/issues/107468#issuecomment-1409096700 + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S<T>(T); + +impl<T, 'a> S<T> { //~ ERROR lifetime parameters must be declared prior to type and const parameters + type P = T; +} + +struct Subj<T>(T); + +impl<T, S> Subj<(T, S)> { + type Un = (T, S); +} + +fn main() { + type A = S<()>::P; + + let _: Subj<(i32, i32)>::Un = 0i32; //~ ERROR mismatched types +} diff --git a/tests/ui/associated-inherent-types/substitute-params-bad.stderr b/tests/ui/associated-inherent-types/substitute-params-bad.stderr new file mode 100644 index 000000000..7a7808ba6 --- /dev/null +++ b/tests/ui/associated-inherent-types/substitute-params-bad.stderr @@ -0,0 +1,20 @@ +error: lifetime parameters must be declared prior to type and const parameters + --> $DIR/substitute-params-bad.rs:9:9 + | +LL | impl<T, 'a> S<T> { + | ----^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, T>` + +error[E0308]: mismatched types + --> $DIR/substitute-params-bad.rs:22:35 + | +LL | let _: Subj<(i32, i32)>::Un = 0i32; + | -------------------- ^^^^ expected `(i32, i32)`, found `i32` + | | + | expected due to this + | + = note: expected tuple `(i32, i32)` + found type `i32` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-inherent-types/struct-generics.rs b/tests/ui/associated-inherent-types/substitute-params.rs index 8952b3791..e94d68331 100644 --- a/tests/ui/associated-inherent-types/struct-generics.rs +++ b/tests/ui/associated-inherent-types/substitute-params.rs @@ -9,7 +9,15 @@ impl<T> S<T> { type P = T; } +impl<T> S<(T,)> { + type Un = T; +} + fn main() { + // Regression test for issue #104240. type A = S<()>::P; let _: A = (); + + // Regression test for issue #107468. + let _: S<(i32,)>::Un = 0i32; } |