diff options
Diffstat (limited to 'tests/ui/associated-inherent-types')
46 files changed, 772 insertions, 67 deletions
diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.rs b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.rs new file mode 100644 index 000000000..f41574403 --- /dev/null +++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.rs @@ -0,0 +1,10 @@ +// known-bug: #108491 + +// FIXME(inherent_associated_types): This should pass. + +struct Foo { + bar: Self::Bar, +} +impl Foo { + pub type Bar = usize; +} diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr new file mode 100644 index 000000000..f313c4946 --- /dev/null +++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr @@ -0,0 +1,49 @@ +error[E0601]: `main` function not found in crate `cycle_iat_inside_of_adt` + --> $DIR/cycle-iat-inside-of-adt.rs:10:2 + | +LL | } + | ^ consider adding a `main` function to `$DIR/cycle-iat-inside-of-adt.rs` + +error[E0391]: cycle detected when computing predicates of `Foo` + --> $DIR/cycle-iat-inside-of-adt.rs:5:1 + | +LL | struct Foo { + | ^^^^^^^^^^ + | +note: ...which requires computing predicates of `Foo`... + --> $DIR/cycle-iat-inside-of-adt.rs:5:1 + | +LL | struct Foo { + | ^^^^^^^^^^ +note: ...which requires computing inferred outlives predicates of `Foo`... + --> $DIR/cycle-iat-inside-of-adt.rs:5:1 + | +LL | struct Foo { + | ^^^^^^^^^^ + = note: ...which requires computing the inferred outlives predicates for items in this crate... +note: ...which requires computing type of `Foo::bar`... + --> $DIR/cycle-iat-inside-of-adt.rs:6:5 + | +LL | bar: Self::Bar, + | ^^^^^^^^^^^^^^ +note: ...which requires computing normalized predicates of `Foo`... + --> $DIR/cycle-iat-inside-of-adt.rs:5:1 + | +LL | struct Foo { + | ^^^^^^^^^^ + = note: ...which again requires computing predicates of `Foo`, completing the cycle +note: cycle used when collecting item types in top-level module + --> $DIR/cycle-iat-inside-of-adt.rs:5:1 + | +LL | / struct Foo { +LL | | bar: Self::Bar, +LL | | } +LL | | impl Foo { +LL | | pub type Bar = usize; +LL | | } + | |_^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0391, E0601. +For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.rs b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.rs new file mode 100644 index 000000000..0c2a38b11 --- /dev/null +++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.rs @@ -0,0 +1,16 @@ +// known-bug: unknown + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// FIXME(inherent_associated_types): This shouldn't lead to a cycle error. + +fn user<T>() where S<T>::P: std::fmt::Debug {} + +struct S<T>; + +impl<T: Copy> S<T> { + type P = (); +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr new file mode 100644 index 000000000..aaa9a39ea --- /dev/null +++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr @@ -0,0 +1,37 @@ +error[E0391]: cycle detected when computing predicates of `user` + --> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1 + | +LL | fn user<T>() where S<T>::P: std::fmt::Debug {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires computing predicates of `user`... + --> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1 + | +LL | fn user<T>() where S<T>::P: std::fmt::Debug {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires computing explicit predicates of `user`... + --> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1 + | +LL | fn user<T>() where S<T>::P: std::fmt::Debug {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires computing normalized predicates of `user`... + --> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1 + | +LL | fn user<T>() where S<T>::P: std::fmt::Debug {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which again requires computing predicates of `user`, completing the cycle +note: cycle used when collecting item types in top-level module + --> $DIR/cycle-iat-inside-of-where-predicate.rs:3:1 + | +LL | / #![feature(inherent_associated_types)] +LL | | #![allow(incomplete_features)] +LL | | +LL | | // FIXME(inherent_associated_types): This shouldn't lead to a cycle error. +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/associated-inherent-types/bugs/ice-substitution.rs b/tests/ui/associated-inherent-types/bugs/ice-substitution.rs deleted file mode 100644 index 53ac79e05..000000000 --- a/tests/ui/associated-inherent-types/bugs/ice-substitution.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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 deleted file mode 100644 index 7b0d1c505..000000000 --- a/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr +++ /dev/null @@ -1,6 +0,0 @@ -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 deleted file mode 100644 index a920b412b..000000000 --- a/tests/ui/associated-inherent-types/bugs/inference-fail.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/lack-of-regionck.rs b/tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs deleted file mode 100644 index 632dbf385..000000000 --- a/tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/bugs/wf-check-skipped.rs b/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs new file mode 100644 index 000000000..c7f66e645 --- /dev/null +++ b/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs @@ -0,0 +1,15 @@ +// known-bug: #100041 +// check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// FIXME(inherent_associated_types): This should fail. + +struct Foo; + +impl Foo { + type Bar<T> = (); +} + +fn main() -> Foo::Bar::<Vec<[u32]>> {} diff --git a/tests/ui/associated-inherent-types/const-generics.rs b/tests/ui/associated-inherent-types/const-generics.rs new file mode 100644 index 000000000..5b7c00bcc --- /dev/null +++ b/tests/ui/associated-inherent-types/const-generics.rs @@ -0,0 +1,23 @@ +// Regression test for issue #109759. +// check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Foo; + +struct Bar<const X: usize>([(); X]); + +impl<const X: usize> Bar<X> { + pub fn new() -> Self { + Self([(); X]) + } +} + +impl Foo { + type Bar<const X: usize> = Bar<X>; +} + +fn main() { + let _ = Foo::Bar::<10>::new(); +} 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 index f846bfa41..83be4f43b 100644 --- a/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs +++ b/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs @@ -31,7 +31,7 @@ fn main() { let _: Select<u8>::Projection = (); let _: Choose<NonCopy>::Result = (); - let _: Choose<bool>::Result = vec![true]; + let _: Choose<&str>::Result = vec!["…"]; // regression test for issue #108957 } // Test if we use the correct `ParamEnv` when proving obligations. diff --git a/tests/ui/associated-inherent-types/former-subst-ice.rs b/tests/ui/associated-inherent-types/former-subst-ice.rs new file mode 100644 index 000000000..48390b943 --- /dev/null +++ b/tests/ui/associated-inherent-types/former-subst-ice.rs @@ -0,0 +1,16 @@ +// check-pass + +#![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/generic-associated-types-bad.item.stderr b/tests/ui/associated-inherent-types/generic-associated-types-bad.item.stderr new file mode 100644 index 000000000..464b59c24 --- /dev/null +++ b/tests/ui/associated-inherent-types/generic-associated-types-bad.item.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/generic-associated-types-bad.rs:16:10 + | +LL | const _: Ty::Pr<String> = String::new(); + | ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `Ty::Pr` + --> $DIR/generic-associated-types-bad.rs:10:16 + | +LL | type Pr<T: Copy> = T; + | ^^^^ required by this bound in `Ty::Pr` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-inherent-types/generic-associated-types-bad.local.stderr b/tests/ui/associated-inherent-types/generic-associated-types-bad.local.stderr new file mode 100644 index 000000000..4f371b24e --- /dev/null +++ b/tests/ui/associated-inherent-types/generic-associated-types-bad.local.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `Vec<()>: Copy` is not satisfied + --> $DIR/generic-associated-types-bad.rs:20:12 + | +LL | let _: Ty::Pr<Vec<()>>; + | ^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Vec<()>` + | +note: required by a bound in `Ty::Pr` + --> $DIR/generic-associated-types-bad.rs:10:16 + | +LL | type Pr<T: Copy> = T; + | ^^^^ required by this bound in `Ty::Pr` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-inherent-types/generic-associated-types-bad.region.stderr b/tests/ui/associated-inherent-types/generic-associated-types-bad.region.stderr new file mode 100644 index 000000000..74ec39424 --- /dev/null +++ b/tests/ui/associated-inherent-types/generic-associated-types-bad.region.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/generic-associated-types-bad.rs:25:12 + | +LL | fn user<'a>() { + | -- lifetime `'a` defined here +LL | #[cfg(region)] +LL | let _: Ty::Static<&'a str> = ""; + | ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/tests/ui/associated-inherent-types/generic-associated-types-bad.rs b/tests/ui/associated-inherent-types/generic-associated-types-bad.rs new file mode 100644 index 000000000..e66392a0a --- /dev/null +++ b/tests/ui/associated-inherent-types/generic-associated-types-bad.rs @@ -0,0 +1,26 @@ +// revisions: item local region + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +#[derive(Clone, Copy)] +pub enum Ty {} + +impl Ty { + type Pr<T: Copy> = T; + + type Static<Q: 'static> = Q; +} + +#[cfg(item)] +const _: Ty::Pr<String> = String::new(); //[item]~ the trait bound `String: Copy` is not satisfied + +fn main() { + #[cfg(local)] + let _: Ty::Pr<Vec<()>>; //[local]~ ERROR the trait bound `Vec<()>: Copy` is not satisfied +} + +fn user<'a>() { + #[cfg(region)] + let _: Ty::Static<&'a str> = ""; //[region]~ ERROR lifetime may not live long enough +} diff --git a/tests/ui/associated-inherent-types/generic-const-exprs.rs b/tests/ui/associated-inherent-types/generic-const-exprs.rs new file mode 100644 index 000000000..a4ac0ecfa --- /dev/null +++ b/tests/ui/associated-inherent-types/generic-const-exprs.rs @@ -0,0 +1,28 @@ +// check-pass + +#![feature(inherent_associated_types, generic_const_exprs)] +#![allow(incomplete_features)] + +struct Parent<const O: usize>; + +impl<const O: usize> Parent<O> { + type Mapping<const I: usize> = Store<{ O + I }> + where + [(); O + I]: + ; +} + +struct Store<const N: usize>; + +impl<const N: usize> Store<N> { + const REIFIED: usize = N; + + fn reify() -> usize { + N + } +} + +fn main() { + let _ = Parent::<2>::Mapping::<{ 12 * 2 }>::REIFIED; + let _ = Parent::<1>::Mapping::<{ 2 * 5 }>::reify(); +} diff --git a/tests/ui/associated-inherent-types/inference-fail.rs b/tests/ui/associated-inherent-types/inference-fail.rs new file mode 100644 index 000000000..939a4ff60 --- /dev/null +++ b/tests/ui/associated-inherent-types/inference-fail.rs @@ -0,0 +1,11 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S<T>(T); + +impl<T> S<T> { type P = (); } + +fn main() { + // There is no way to infer this type. + let _: S<_>::P = (); //~ ERROR type annotations needed +} diff --git a/tests/ui/associated-inherent-types/bugs/inference-fail.stderr b/tests/ui/associated-inherent-types/inference-fail.stderr index 425691bd6..f29144e4a 100644 --- a/tests/ui/associated-inherent-types/bugs/inference-fail.stderr +++ b/tests/ui/associated-inherent-types/inference-fail.stderr @@ -1,8 +1,8 @@ error[E0282]: type annotations needed - --> $DIR/inference-fail.rs:14:14 + --> $DIR/inference-fail.rs:10:12 | -LL | let _: S<_>::P; - | ^ cannot infer type +LL | let _: S<_>::P = (); + | ^^^^^^^ cannot infer type for type parameter `T` error: aborting due to previous error diff --git a/tests/ui/associated-inherent-types/inference.rs b/tests/ui/associated-inherent-types/inference.rs new file mode 100644 index 000000000..ebd8e1d55 --- /dev/null +++ b/tests/ui/associated-inherent-types/inference.rs @@ -0,0 +1,40 @@ +// Testing inference capabilities. +// check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] +#![allow(dropping_copy_types)] + +use std::convert::identity; + +struct Container<T>(T); + +impl Container<u32> { + type Sink = (); +} + +impl<Any> Container<Any> { + type Thing = Any; +} + +impl<T> Container<(T, ())> { + type Output = ((), Wrapped<T>); +} + +fn main() { + // Inferred via the Self type of the impl. + let _: Container<_>::Sink; + + // Inferred via the RHS: + + let _: Container<_>::Thing = 0; + + let _: Container<Wrapped<_>>::Thing = Wrapped(false); + + let _: Container<_>::Output = (drop(1), Wrapped("...")); + + let binding: Container<_>::Thing = Default::default(); // unsolved at this point + identity::<String>(binding); // constrained and solved here +} + +struct Wrapped<T>(T); diff --git a/tests/ui/associated-inherent-types/issue-109768.rs b/tests/ui/associated-inherent-types/issue-109768.rs new file mode 100644 index 000000000..a3ae2e2ab --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-109768.rs @@ -0,0 +1,12 @@ +// incremental + +struct Wrapper<T>(T); + +struct Local<T, U>(T, U); + +impl<T> Local { //~ ERROR missing generics for struct `Local` + type AssocType3 = T; //~ ERROR inherent associated types are unstable + + const WRAPPED_ASSOC_3: Wrapper<Self::AssocType3> = Wrapper(); +} +//~^ ERROR `main` function not found diff --git a/tests/ui/associated-inherent-types/issue-109768.stderr b/tests/ui/associated-inherent-types/issue-109768.stderr new file mode 100644 index 000000000..97706d406 --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-109768.stderr @@ -0,0 +1,35 @@ +error[E0601]: `main` function not found in crate `issue_109768` + --> $DIR/issue-109768.rs:11:2 + | +LL | } + | ^ consider adding a `main` function to `$DIR/issue-109768.rs` + +error[E0107]: missing generics for struct `Local` + --> $DIR/issue-109768.rs:7:9 + | +LL | impl<T> Local { + | ^^^^^ expected 2 generic arguments + | +note: struct defined here, with 2 generic parameters: `T`, `U` + --> $DIR/issue-109768.rs:5:8 + | +LL | struct Local<T, U>(T, U); + | ^^^^^ - - +help: add missing generic arguments + | +LL | impl<T> Local<T, U> { + | ++++++ + +error[E0658]: inherent associated types are unstable + --> $DIR/issue-109768.rs:8:5 + | +LL | type AssocType3 = T; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information + = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0601, E0658. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/associated-inherent-types/issue-109789.rs b/tests/ui/associated-inherent-types/issue-109789.rs new file mode 100644 index 000000000..0b5ba7d1f --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-109789.rs @@ -0,0 +1,22 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Foo<T>(T); + +impl Foo<fn(&'static ())> { + type Assoc = u32; +} + +trait Other {} +impl Other for u32 {} + +// FIXME(inherent_associated_types): Avoid emitting two diagnostics (they only differ in span). +// FIXME(inherent_associated_types): Enhancement: Spruce up the diagnostic by saying something like +// "implementation is not general enough" as is done for traits via +// `try_report_trait_placeholder_mismatch`. + +fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {} +//~^ ERROR mismatched types +//~| ERROR mismatched types + +fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-109789.stderr b/tests/ui/associated-inherent-types/issue-109789.stderr new file mode 100644 index 000000000..7af338274 --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-109789.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/issue-109789.rs:18:1 + | +LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected struct `Foo<fn(&'static ())>` + found struct `Foo<for<'a> fn(&'a ())>` + +error[E0308]: mismatched types + --> $DIR/issue-109789.rs:18:11 + | +LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected struct `Foo<fn(&'static ())>` + found struct `Foo<for<'a> fn(&'a ())>` + +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/issue-109790.rs b/tests/ui/associated-inherent-types/issue-109790.rs new file mode 100644 index 000000000..88327f864 --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-109790.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] +#![deny(single_use_lifetimes)] + +struct Foo<T>(T); + +impl<'a> Foo<fn(&'a ())> { + type Assoc = &'a (); +} + +trait Other {} +impl Other for u32 {} + +fn bar(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-111879-0.rs b/tests/ui/associated-inherent-types/issue-111879-0.rs new file mode 100644 index 000000000..e37f7d34a --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-111879-0.rs @@ -0,0 +1,14 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// Check that we don't crash when printing inherent projections in diagnostics. + +pub struct Carrier<'a>(&'a ()); + +pub type User = for<'b> fn(Carrier<'b>::Focus<i32>); + +impl<'a> Carrier<'a> { + pub type Focus<T> = &'a mut User; //~ ERROR overflow evaluating associated type +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-111879-0.stderr b/tests/ui/associated-inherent-types/issue-111879-0.stderr new file mode 100644 index 000000000..7bdbad440 --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-111879-0.stderr @@ -0,0 +1,8 @@ +error: overflow evaluating associated type `Carrier<'b>::Focus<i32>` + --> $DIR/issue-111879-0.rs:11:25 + | +LL | pub type Focus<T> = &'a mut User; + | ^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/associated-inherent-types/issue-111879-1.rs b/tests/ui/associated-inherent-types/issue-111879-1.rs new file mode 100644 index 000000000..7acc4f945 --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-111879-1.rs @@ -0,0 +1,12 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// Check that we don't crash when printing inherent projections in diagnostics. + +struct Foo<T>(T); + +impl<'a> Foo<fn(&'a ())> { + type Assoc = &'a (); +} + +fn main(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {} //~ ERROR `main` function has wrong type diff --git a/tests/ui/associated-inherent-types/issue-111879-1.stderr b/tests/ui/associated-inherent-types/issue-111879-1.stderr new file mode 100644 index 000000000..689b45e09 --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-111879-1.stderr @@ -0,0 +1,12 @@ +error[E0580]: `main` function has wrong type + --> $DIR/issue-111879-1.rs:12:1 + | +LL | fn main(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters + | + = note: expected fn pointer `fn()` + found fn pointer `fn(for<'a> fn(Foo<fn(&'a ())>::Assoc))` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0580`. diff --git a/tests/ui/associated-inherent-types/late-bound-regions.rs b/tests/ui/associated-inherent-types/late-bound-regions.rs new file mode 100644 index 000000000..488a2cda6 --- /dev/null +++ b/tests/ui/associated-inherent-types/late-bound-regions.rs @@ -0,0 +1,25 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// Test if we correctly normalize `S<'a>::P` with respect to late-bound regions. + +type Function = for<'a> fn(&'a i32) -> S<'a>::P; + +struct S<'a>(&'a ()); + +trait Inter { + type P; +} + +impl<'a> S<'a> { + type P = &'a i32; +} + +fn ret_ref_local<'e>() -> &'e i32 { + let f: Function = |x| x; + + let local = 0; + f(&local) //~ ERROR cannot return value referencing local variable `local` +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/late-bound-regions.stderr b/tests/ui/associated-inherent-types/late-bound-regions.stderr new file mode 100644 index 000000000..4706fcca9 --- /dev/null +++ b/tests/ui/associated-inherent-types/late-bound-regions.stderr @@ -0,0 +1,12 @@ +error[E0515]: cannot return value referencing local variable `local` + --> $DIR/late-bound-regions.rs:22:5 + | +LL | f(&local) + | ^^------^ + | | | + | | `local` is borrowed here + | returns a value referencing data owned by the current function + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0515`. diff --git a/tests/ui/associated-inherent-types/normalization-overflow.rs b/tests/ui/associated-inherent-types/normalization-overflow.rs new file mode 100644 index 000000000..4228238aa --- /dev/null +++ b/tests/ui/associated-inherent-types/normalization-overflow.rs @@ -0,0 +1,12 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// FIXME(fmease): I'd prefer to report a cycle error here instead of an overflow one. + +struct T; + +impl T { + type This = Self::This; //~ ERROR overflow evaluating associated type `T::This` +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/normalization-overflow.stderr b/tests/ui/associated-inherent-types/normalization-overflow.stderr new file mode 100644 index 000000000..16bb64281 --- /dev/null +++ b/tests/ui/associated-inherent-types/normalization-overflow.stderr @@ -0,0 +1,8 @@ +error: overflow evaluating associated type `T::This` + --> $DIR/normalization-overflow.rs:9:17 + | +LL | type This = Self::This; + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/associated-inherent-types/private-in-public.rs b/tests/ui/associated-inherent-types/private-in-public.rs new file mode 100644 index 000000000..a4b372537 --- /dev/null +++ b/tests/ui/associated-inherent-types/private-in-public.rs @@ -0,0 +1,26 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] +#![crate_type = "lib"] + +#![deny(private_in_public)] + +pub type PubAlias0 = PubTy::PrivAssocTy; +//~^ ERROR private associated type `PubTy::PrivAssocTy` in public interface (error E0446) +//~| WARNING this was previously accepted +pub type PubAlias1 = PrivTy::PubAssocTy; +//~^ ERROR private type `PrivTy` in public interface (error E0446) +//~| WARNING this was previously accepted +pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>; +//~^ ERROR private type `PrivTy` in public interface (error E0446) +//~| WARNING this was previously accepted + +pub struct PubTy; +impl PubTy { + type PrivAssocTy = (); + pub type PubAssocTy<T> = T; +} + +struct PrivTy; +impl PrivTy { + pub type PubAssocTy = (); +} diff --git a/tests/ui/associated-inherent-types/private-in-public.stderr b/tests/ui/associated-inherent-types/private-in-public.stderr new file mode 100644 index 000000000..f0a64e961 --- /dev/null +++ b/tests/ui/associated-inherent-types/private-in-public.stderr @@ -0,0 +1,34 @@ +error: private associated type `PubTy::PrivAssocTy` in public interface (error E0446) + --> $DIR/private-in-public.rs:7:1 + | +LL | pub type PubAlias0 = PubTy::PrivAssocTy; + | ^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: the lint level is defined here + --> $DIR/private-in-public.rs:5:9 + | +LL | #![deny(private_in_public)] + | ^^^^^^^^^^^^^^^^^ + +error: private type `PrivTy` in public interface (error E0446) + --> $DIR/private-in-public.rs:10:1 + | +LL | pub type PubAlias1 = PrivTy::PubAssocTy; + | ^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> + +error: private type `PrivTy` in public interface (error E0446) + --> $DIR/private-in-public.rs:13:1 + | +LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>; + | ^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> + +error: aborting due to 3 previous errors + diff --git a/tests/ui/associated-inherent-types/regionck-0.rs b/tests/ui/associated-inherent-types/regionck-0.rs new file mode 100644 index 000000000..7c94539ac --- /dev/null +++ b/tests/ui/associated-inherent-types/regionck-0.rs @@ -0,0 +1,14 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S<T>(T); + +impl S<&'static ()> { + type T = (); +} + +fn user<'a>() { + let _: S::<&'a ()>::T; //~ ERROR lifetime may not live long enough +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/regionck-0.stderr b/tests/ui/associated-inherent-types/regionck-0.stderr new file mode 100644 index 000000000..3a438ee63 --- /dev/null +++ b/tests/ui/associated-inherent-types/regionck-0.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/regionck-0.rs:11:12 + | +LL | fn user<'a>() { + | -- lifetime `'a` defined here +LL | let _: S::<&'a ()>::T; + | ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/tests/ui/associated-inherent-types/regionck-1.rs b/tests/ui/associated-inherent-types/regionck-1.rs new file mode 100644 index 000000000..ec663cd0f --- /dev/null +++ b/tests/ui/associated-inherent-types/regionck-1.rs @@ -0,0 +1,13 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct U; + +impl U { + // Don't imply any bounds here. + + type NoTyOutliv<'a, T> = &'a T; //~ ERROR the parameter type `T` may not live long enough + type NoReOutliv<'a, 'b> = &'a &'b (); //~ ERROR reference has a longer lifetime than the data it references +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/regionck-1.stderr b/tests/ui/associated-inherent-types/regionck-1.stderr new file mode 100644 index 000000000..b17d89ca3 --- /dev/null +++ b/tests/ui/associated-inherent-types/regionck-1.stderr @@ -0,0 +1,29 @@ +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/regionck-1.rs:9:30 + | +LL | type NoTyOutliv<'a, T> = &'a T; + | ^^^^^- help: consider adding a where clause: `where T: 'a` + | | + | ...so that the reference type `&'a T` does not outlive the data it points at + +error[E0491]: in type `&'a &'b ()`, reference has a longer lifetime than the data it references + --> $DIR/regionck-1.rs:10:31 + | +LL | type NoReOutliv<'a, 'b> = &'a &'b (); + | ^^^^^^^^^^ + | +note: the pointer is valid for the lifetime `'a` as defined here + --> $DIR/regionck-1.rs:10:21 + | +LL | type NoReOutliv<'a, 'b> = &'a &'b (); + | ^^ +note: but the referenced data is only valid for the lifetime `'b` as defined here + --> $DIR/regionck-1.rs:10:25 + | +LL | type NoReOutliv<'a, 'b> = &'a &'b (); + | ^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0309, E0491. +For more information about an error, try `rustc --explain E0309`. diff --git a/tests/ui/associated-inherent-types/regionck-2.rs b/tests/ui/associated-inherent-types/regionck-2.rs new file mode 100644 index 000000000..7a0b8b083 --- /dev/null +++ b/tests/ui/associated-inherent-types/regionck-2.rs @@ -0,0 +1,14 @@ +// Regression test for issue #109299. + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Lexer<'d>(&'d ()); + +impl Lexer<'static> { + type Cursor = (); +} + +fn test(_: Lexer::Cursor) {} //~ ERROR mismatched types + +fn main() {} diff --git a/tests/ui/associated-inherent-types/regionck-2.stderr b/tests/ui/associated-inherent-types/regionck-2.stderr new file mode 100644 index 000000000..b0a4ed35d --- /dev/null +++ b/tests/ui/associated-inherent-types/regionck-2.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/regionck-2.rs:12:12 + | +LL | fn test(_: Lexer::Cursor) {} + | ^^^^^^^^^^^^^ lifetime mismatch + | + = note: expected struct `Lexer<'static>` + found struct `Lexer<'_>` +note: the anonymous lifetime defined here... + --> $DIR/regionck-2.rs:12:12 + | +LL | fn test(_: Lexer::Cursor) {} + | ^^^^^ + = note: ...does not necessarily outlive the static lifetime + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs new file mode 100644 index 000000000..b32b4288a --- /dev/null +++ b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs @@ -0,0 +1,26 @@ +// check-pass +// compile-flags: --crate-type=lib + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// Bounds on the self type play a major role in the resolution of inherent associated types (*). +// As a result of that, if a type alias contains any then its bounds have to be respected and the +// lint `type_alias_bounds` should not fire. +// +// FIXME(inherent_associated_types): In the current implementation that is. We might move the +// selection phase of IATs from hir_typeck to trait_selection resulting in us not requiring the +// ParamEnv that early allowing us to ignore bounds on type aliases again. +// Triage this before stabilization. + +#![deny(type_alias_bounds)] + +pub type Alias<T: Bound> = (Source<T>::Assoc,); + + +pub struct Source<T>(T); +pub trait Bound {} + +impl<T: Bound> Source<T> { + pub type Assoc = (); +} diff --git a/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.rs b/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.rs new file mode 100644 index 000000000..d081c4d5b --- /dev/null +++ b/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.rs @@ -0,0 +1,12 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S<T>(T); + +impl<T: Copy> S<T> { + type T = T; +} + +fn main() { + let _: S<_>::T = String::new(); //~ ERROR the trait bound `String: Copy` is not satisfied +} diff --git a/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.stderr b/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.stderr new file mode 100644 index 000000000..ecf30f4cd --- /dev/null +++ b/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/unsatisfied-bounds-inferred-type.rs:11:12 + | +LL | let _: S<_>::T = String::new(); + | ^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `S<T>::T` + --> $DIR/unsatisfied-bounds-inferred-type.rs:6:9 + | +LL | impl<T: Copy> S<T> { + | ^^^^ required by this bound in `S<T>::T` +LL | type T = T; + | - required by a bound in this associated type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.rs b/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.rs new file mode 100644 index 000000000..97bd2c421 --- /dev/null +++ b/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.rs @@ -0,0 +1,14 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S<T>(T); + +impl<T> S<T> { + type X = () + where + T: Copy; +} + +fn main() { + let _: S::<String>::X; //~ ERROR the trait bound `String: Copy` is not satisfied +} diff --git a/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.stderr b/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.stderr new file mode 100644 index 000000000..d4968cd05 --- /dev/null +++ b/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/unsatisfied-bounds-where-clause-on-assoc-ty.rs:13:12 + | +LL | let _: S::<String>::X; + | ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `S<T>::X` + --> $DIR/unsatisfied-bounds-where-clause-on-assoc-ty.rs:9:12 + | +LL | type X = () + | - required by a bound in this associated type +LL | where +LL | T: Copy; + | ^^^^ required by this bound in `S<T>::X` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. |