From 66bd6453e033ae3e502a540595a9b31a0f25b55f Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Tue, 16 Aug 2022 02:31:16 +0300 Subject: [PATCH] test that we do not support higher-ranked regions in opaque type inference --- .../impl-trait/higher-ranked-regions-diag.rs | 25 ++++ .../higher-ranked-regions-diag.stderr | 13 ++ .../higher-ranked-regions-basic.rs | 84 ++++++++++++ .../higher-ranked-regions-basic.stderr | 125 ++++++++++++++++++ .../higher-ranked-regions-gat.rs | 21 +++ .../higher-ranked-regions-gat.stderr | 24 ++++ 6 files changed, 292 insertions(+) create mode 100644 tests/ui/rfcs/impl-trait/higher-ranked-regions-diag.rs create mode 100644 tests/ui/rfcs/impl-trait/higher-ranked-regions-diag.stderr create mode 100644 tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.rs create mode 100644 tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.stderr create mode 100644 tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.rs create mode 100644 tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.stderr diff --git a/tests/ui/rfcs/impl-trait/higher-ranked-regions-diag.rs b/tests/ui/rfcs/impl-trait/higher-ranked-regions-diag.rs new file mode 100644 index 00000000000..470022565f6 --- /dev/null +++ b/tests/ui/rfcs/impl-trait/higher-ranked-regions-diag.rs @@ -0,0 +1,25 @@ +// Regression test for #97099. +// This was an ICE because `impl Sized` captures the lifetime 'a. + +// check-fail + +trait Trait { + type Assoc; +} + +struct Foo; + +impl<'a> Trait<&'a ()> for Foo { + type Assoc = (); +} + +fn foo() -> impl for<'a> Trait<&'a ()> { + Foo +} + +fn bar() -> impl for<'a> Trait<&'a (), Assoc = impl Sized> { + foo() + //~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds +} + +fn main() {} diff --git a/tests/ui/rfcs/impl-trait/higher-ranked-regions-diag.stderr b/tests/ui/rfcs/impl-trait/higher-ranked-regions-diag.stderr new file mode 100644 index 00000000000..8e6724fb901 --- /dev/null +++ b/tests/ui/rfcs/impl-trait/higher-ranked-regions-diag.stderr @@ -0,0 +1,13 @@ +error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds + --> $DIR/higher-ranked-regions-diag.rs:21:5 + | +LL | fn bar() -> impl for<'a> Trait<&'a (), Assoc = impl Sized> { + | -- ---------- opaque type defined here + | | + | hidden type ` Trait<&'a ()> as Trait<&'a ()>>::Assoc` captures the lifetime `'a` as defined here +LL | foo() + | ^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.rs b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.rs new file mode 100644 index 00000000000..83c3adca0e1 --- /dev/null +++ b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.rs @@ -0,0 +1,84 @@ +// Basic tests for opaque type inference under for<_> binders. + +// check-fail + +#![feature(type_alias_impl_trait)] + +trait Trait<'a> { + type Ty; +} +impl<'a, T> Trait<'a> for T { + type Ty = &'a (); +} + +mod basic_pass { + use super::*; + type Opq<'a> = impl Sized + 'a; + fn test() -> impl for<'a> Trait<'a, Ty = Opq<'a>> {} + //~^ ERROR: expected generic lifetime parameter, found `'a` +} + +mod capture_rpit { + use super::*; + fn test() -> impl for<'a> Trait<'a, Ty = impl Sized> {} + //~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds +} + +mod capture_tait { + use super::*; + type Opq0 = impl Sized; + type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0>; + type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; + fn test() -> Opq2 {} + //~^ ERROR hidden type for `capture_tait::Opq0` captures lifetime that does not appear in bounds +} + +mod capture_tait_complex_pass { + use super::*; + type Opq0<'a> = impl Sized; + type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'b>>; // <- Note 'b + //~^ ERROR: concrete type differs from previous defining opaque type use + type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; + fn test() -> Opq2 {} + //~^ ERROR: expected generic lifetime parameter, found `'a` +} + +// Same as the above, but make sure that different placeholder regions are not equal. +mod capture_tait_complex_fail { + use super::*; + type Opq0<'a> = impl Sized; + type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a>>; // <- Note 'a + type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; + fn test() -> Opq2 {} + //~^ ERROR hidden type for `capture_tait_complex_fail::Opq0<'a>` captures lifetime that does not appear in bounds +} + +// non-defining use because 'static is used. +mod constrain_fail0 { + use super::*; + type Opq0<'a, 'b> = impl Sized; + fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {} + //~^ ERROR non-defining opaque type use in defining scope + //~| ERROR: expected generic lifetime parameter, found `'a` +} + +// non-defining use because generic lifetime is used multiple times. +mod constrain_fail { + use super::*; + type Opq0<'a, 'b> = impl Sized; + fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'a>> {} + //~^ ERROR non-defining opaque type use in defining scope + //~| ERROR: expected generic lifetime parameter, found `'a` +} + +mod constrain_pass { + use super::*; + type Opq0<'a, 'b> = impl Sized; + type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a, 'b>>; + //~^ ERROR concrete type differs + type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; + fn test() -> Opq2 {} + //~^ ERROR: expected generic lifetime parameter, found `'a` +} + +fn main() {} diff --git a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.stderr b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.stderr new file mode 100644 index 00000000000..65b3a449efb --- /dev/null +++ b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-basic.stderr @@ -0,0 +1,125 @@ +error[E0792]: expected generic lifetime parameter, found `'a` + --> $DIR/higher-ranked-regions-basic.rs:17:55 + | +LL | type Opq<'a> = impl Sized + 'a; + | -- this generic parameter must be used with a generic lifetime parameter +LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq<'a>> {} + | ^^ + +error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds + --> $DIR/higher-ranked-regions-basic.rs:23:58 + | +LL | fn test() -> impl for<'a> Trait<'a, Ty = impl Sized> {} + | -- ---------- ^^ + | | | + | | opaque type defined here + | hidden type `&'a ()` captures the lifetime `'a` as defined here + +error[E0700]: hidden type for `capture_tait::Opq0` captures lifetime that does not appear in bounds + --> $DIR/higher-ranked-regions-basic.rs:32:23 + | +LL | type Opq0 = impl Sized; + | ---------- opaque type defined here +LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0>; + | -- hidden type `&'b ()` captures the lifetime `'b` as defined here +LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; +LL | fn test() -> Opq2 {} + | ^^ + +error[E0792]: expected generic lifetime parameter, found `'a` + --> $DIR/higher-ranked-regions-basic.rs:42:23 + | +LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'b>>; // <- Note 'b + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | fn test() -> Opq2 {} + | ^^ + +error: concrete type differs from previous defining opaque type use + --> $DIR/higher-ranked-regions-basic.rs:39:21 + | +LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'b>>; // <- Note 'b + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&'a ()`, got `{type error}` + | +note: previous use here + --> $DIR/higher-ranked-regions-basic.rs:41:17 + | +LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0700]: hidden type for `capture_tait_complex_fail::Opq0<'a>` captures lifetime that does not appear in bounds + --> $DIR/higher-ranked-regions-basic.rs:52:23 + | +LL | type Opq0<'a> = impl Sized; + | ---------- opaque type defined here +LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a>>; // <- Note 'a + | -- hidden type `&'b ()` captures the lifetime `'b` as defined here +LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; +LL | fn test() -> Opq2 {} + | ^^ + +error[E0792]: non-defining opaque type use in defining scope + --> $DIR/higher-ranked-regions-basic.rs:60:41 + | +LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {} + | ^^^^^^^^^^^^^^^^^^^^^^ argument `'static` is not a generic parameter + | +note: for this opaque type + --> $DIR/higher-ranked-regions-basic.rs:59:25 + | +LL | type Opq0<'a, 'b> = impl Sized; + | ^^^^^^^^^^ + +error[E0792]: expected generic lifetime parameter, found `'a` + --> $DIR/higher-ranked-regions-basic.rs:60:65 + | +LL | type Opq0<'a, 'b> = impl Sized; + | -- this generic parameter must be used with a generic lifetime parameter +LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'static>> {} + | ^^ + +error: non-defining opaque type use in defining scope + --> $DIR/higher-ranked-regions-basic.rs:69:41 + | +LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'a>> {} + | ^^^^^^^^^^^^^^^^^ generic argument `'a` used twice + | +note: for this opaque type + --> $DIR/higher-ranked-regions-basic.rs:68:25 + | +LL | type Opq0<'a, 'b> = impl Sized; + | ^^^^^^^^^^ + +error[E0792]: expected generic lifetime parameter, found `'a` + --> $DIR/higher-ranked-regions-basic.rs:69:60 + | +LL | type Opq0<'a, 'b> = impl Sized; + | -- this generic parameter must be used with a generic lifetime parameter +LL | fn test() -> impl for<'a> Trait<'a, Ty = Opq0<'a, 'a>> {} + | ^^ + +error[E0792]: expected generic lifetime parameter, found `'a` + --> $DIR/higher-ranked-regions-basic.rs:80:23 + | +LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a, 'b>>; + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | fn test() -> Opq2 {} + | ^^ + +error: concrete type differs from previous defining opaque type use + --> $DIR/higher-ranked-regions-basic.rs:77:21 + | +LL | type Opq1<'a> = impl for<'b> Trait<'b, Ty = Opq0<'a, 'b>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&'a ()`, got `{type error}` + | +note: previous use here + --> $DIR/higher-ranked-regions-basic.rs:79:17 + | +LL | type Opq2 = impl for<'a> Trait<'a, Ty = Opq1<'a>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 12 previous errors + +Some errors have detailed explanations: E0700, E0792. +For more information about an error, try `rustc --explain E0700`. diff --git a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.rs b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.rs new file mode 100644 index 00000000000..be7fa1a7c0a --- /dev/null +++ b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.rs @@ -0,0 +1,21 @@ +// Regression test for #97098. + +#![feature(type_alias_impl_trait)] + +pub trait Trait { + type Assoc<'a>; +} + +pub type Foo = impl for<'a> Trait = FooAssoc<'a>>; +pub type FooAssoc<'a> = impl Sized; +//~^ ERROR: concrete type differs from previous defining opaque type use + +struct Struct; +impl Trait for Struct { + type Assoc<'a> = &'a u32; +} + +const FOO: Foo = Struct; +//~^ ERROR: expected generic lifetime parameter, found `'a` + +fn main() {} diff --git a/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.stderr b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.stderr new file mode 100644 index 00000000000..2538c4bc225 --- /dev/null +++ b/tests/ui/rfcs/type-alias-impl-trait/higher-ranked-regions-gat.stderr @@ -0,0 +1,24 @@ +error[E0792]: expected generic lifetime parameter, found `'a` + --> $DIR/higher-ranked-regions-gat.rs:18:18 + | +LL | pub type FooAssoc<'a> = impl Sized; + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | const FOO: Foo = Struct; + | ^^^^^^ + +error: concrete type differs from previous defining opaque type use + --> $DIR/higher-ranked-regions-gat.rs:10:25 + | +LL | pub type FooAssoc<'a> = impl Sized; + | ^^^^^^^^^^ expected `&'a u32`, got `{type error}` + | +note: previous use here + --> $DIR/higher-ranked-regions-gat.rs:9:16 + | +LL | pub type Foo = impl for<'a> Trait = FooAssoc<'a>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0792`.