diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:11:38 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:13:23 +0000 |
commit | 20431706a863f92cb37dc512fef6e48d192aaf2c (patch) | |
tree | 2867f13f5fd5437ba628c67d7f87309ccadcd286 /src/test/ui/type-alias-impl-trait | |
parent | Releasing progress-linux version 1.65.0+dfsg1-2~progress7.99u1. (diff) | |
download | rustc-20431706a863f92cb37dc512fef6e48d192aaf2c.tar.xz rustc-20431706a863f92cb37dc512fef6e48d192aaf2c.zip |
Merging upstream version 1.66.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/type-alias-impl-trait')
47 files changed, 847 insertions, 50 deletions
diff --git a/src/test/ui/type-alias-impl-trait/closure_parent_substs.rs b/src/test/ui/type-alias-impl-trait/closure_parent_substs.rs new file mode 100644 index 000000000..475f4724f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/closure_parent_substs.rs @@ -0,0 +1,65 @@ +// When WF checking the hidden type in the ParamEnv of the opaque type, +// one complication arises when the hidden type is a closure/generator: +// the "parent_substs" of the type may reference lifetime parameters +// not present in the opaque type. +// These region parameters are not really useful in this check. +// So here we ignore them and replace them with fresh region variables. + +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +// Basic test +mod test1 { + // Hidden type = Closure['_#0r] + type Opaque = impl Sized; + + fn define<'a: 'a>() -> Opaque { + || {} + } +} + +// the region vars cannot both be equal to `'static` or `'empty` +mod test2 { + trait Trait {} + + // Hidden type = Closure['a, '_#0r, '_#1r] + // Constraints = [('_#0r: 'a), ('a: '_#1r)] + type Opaque<'a> + where + &'a (): Trait, + = impl Sized + 'a; + + fn define<'a, 'x, 'y>() -> Opaque<'a> + where + &'a (): Trait, + 'x: 'a, + 'a: 'y, + { + || {} + } +} + +// the region var cannot be equal to `'a` or `'b` +mod test3 { + trait Trait {} + + // Hidden type = Closure['a, 'b, '_#0r] + // Constraints = [('_#0r: 'a), ('_#0r: 'b)] + type Opaque<'a, 'b> + where + (&'a (), &'b ()): Trait, + = impl Sized + 'a + 'b; + + fn define<'a, 'b, 'x>() -> Opaque<'a, 'b> + where + (&'a (), &'b ()): Trait, + 'x: 'a, + 'x: 'b, + { + || {} + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs new file mode 100644 index 000000000..53974dbb3 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs @@ -0,0 +1,65 @@ +// If the hidden type is a closure, we require the "outlives" bounds that appear on the +// defining site to also appear on the opaque type. +// +// It's not clear if this is the desired behavior but at least +// it's consistent and has no back-compat risk. + +// check-fail + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +// requires `'a: 'b` bound +mod test1 { + type Opaque<'a, 'b> = impl Sized + 'a + 'b; + //~^ ERROR lifetime bound not satisfied + + fn define<'a, 'b>() -> Opaque<'a, 'b> + where + 'a: 'b, + { + || {} + } +} + +// Same as the above but through indirection `'x` +mod test2 { + type Opaque<'a, 'b> = impl Sized + 'a + 'b; + //~^ ERROR cannot infer an appropriate lifetime + + fn define<'a, 'b, 'x>() -> Opaque<'a, 'b> + where + 'a: 'x, + 'x: 'b, + { + || {} + } +} + +// fixed version of the above +mod test2_fixed { + type Opaque<'a: 'b, 'b> = impl Sized + 'a + 'b; + + fn define<'a, 'b, 'x>() -> Opaque<'a, 'b> + where + 'a: 'x, + 'x: 'b, + { + || {} + } +} + +// requires `T: 'static` +mod test3 { + type Opaque<T> = impl Sized; + //~^ ERROR the parameter type `T` may not live long enough + + fn define<T>() -> Opaque<T> + where + T: 'static, + { + || {} + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr new file mode 100644 index 000000000..ae6462bb6 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr @@ -0,0 +1,64 @@ +error[E0478]: lifetime bound not satisfied + --> $DIR/closure_wf_outlives.rs:14:27 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^^^^^^^^^^^^^^^^^^^ + | +note: lifetime parameter instantiated with the lifetime `'a` as defined here + --> $DIR/closure_wf_outlives.rs:14:17 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^ +note: but lifetime parameter must outlive the lifetime `'b` as defined here + --> $DIR/closure_wf_outlives.rs:14:21 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^ + +error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements + --> $DIR/closure_wf_outlives.rs:27:27 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^^^^^^^^^^^^^^^^^^^ + | +note: first, the lifetime cannot outlive the lifetime `'a` as defined here... + --> $DIR/closure_wf_outlives.rs:27:17 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^ +note: ...so that the declared lifetime parameter bounds are satisfied + --> $DIR/closure_wf_outlives.rs:27:27 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^^^^^^^^^^^^^^^^^^^ +note: but, the lifetime must be valid for the lifetime `'b` as defined here... + --> $DIR/closure_wf_outlives.rs:27:21 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^ +note: ...so that the declared lifetime parameter bounds are satisfied + --> $DIR/closure_wf_outlives.rs:27:27 + | +LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/closure_wf_outlives.rs:54:22 + | +LL | type Opaque<T> = impl Sized; + | ^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds... + | +note: ...that is required by this bound + --> $DIR/closure_wf_outlives.rs:59:12 + | +LL | T: 'static, + | ^^^^^^^ +help: consider adding an explicit lifetime bound... + | +LL | type Opaque<T: 'static> = impl Sized; + | +++++++++ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0310, E0478, E0495. +For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs index 811832848..9a50c0f98 100644 --- a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs +++ b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs @@ -1,8 +1,9 @@ // compile-flags: --edition=2021 +// check-pass #![feature(type_alias_impl_trait)] fn main() { - type T = impl Copy; //~ ERROR unconstrained opaque type + type T = impl Copy; let foo: T = (1u32, 2u32); let (a, b): (u32, u32) = foo; } diff --git a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.stderr b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.stderr deleted file mode 100644 index 03b172e6d..000000000 --- a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: unconstrained opaque type - --> $DIR/cross_inference_pattern_bug.rs:5:14 - | -LL | type T = impl Copy; - | ^^^^^^^^^ - | - = note: `T` must be used in combination with a concrete type within the same module - -error: aborting due to previous error - diff --git a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs index 328096d44..b929122a6 100644 --- a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs +++ b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs @@ -1,13 +1,13 @@ -// known-bug: #96572 // compile-flags: --edition=2021 --crate-type=lib // rustc-env:RUST_BACKTRACE=0 +// check-pass // tracked in https://github.com/rust-lang/rust/issues/96572 #![feature(type_alias_impl_trait)] fn main() { - type T = impl Copy; // error: unconstrained opaque type + type T = impl Copy; let foo: T = (1u32, 2u32); - let (a, b) = foo; // removing this line makes the code compile + let (a, b) = foo; // this line used to make the code fail } diff --git a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.stderr b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.stderr deleted file mode 100644 index 8aa1f4956..000000000 --- a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: unconstrained opaque type - --> $DIR/cross_inference_pattern_bug_no_type.rs:10:14 - | -LL | type T = impl Copy; // error: unconstrained opaque type - | ^^^^^^^^^ - | - = note: `T` must be used in combination with a concrete type within the same module - -error: aborting due to previous error - diff --git a/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs index 7740f774e..0b8157fe3 100644 --- a/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs @@ -1,5 +1,5 @@ #![feature(type_alias_impl_trait)] -// check-pass + fn main() {} // two definitions with different types @@ -9,7 +9,7 @@ fn foo() -> Foo { "" } -fn bar() -> Foo { +fn bar() -> Foo { //~ ERROR: concrete type differs from previous defining opaque type use panic!() } diff --git a/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr new file mode 100644 index 000000000..09dadb0af --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr @@ -0,0 +1,14 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/different_defining_uses_never_type.rs:12:13 + | +LL | fn bar() -> Foo { + | ^^^ expected `&'static str`, got `()` + | +note: previous use here + --> $DIR/different_defining_uses_never_type.rs:9:5 + | +LL | "" + | ^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs new file mode 100644 index 000000000..bc827a8f2 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs @@ -0,0 +1,12 @@ +#![feature(type_alias_impl_trait)] + +type Tait = impl Sized; + +struct One; +fn one() -> Tait { One } + +struct Two<T>(T); +fn two() -> Tait { Two::<()>(todo!()) } +//~^ ERROR concrete type differs from previous defining opaque type use + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr new file mode 100644 index 000000000..146a57cbb --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr @@ -0,0 +1,14 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/different_defining_uses_never_type3.rs:9:13 + | +LL | fn two() -> Tait { Two::<()>(todo!()) } + | ^^^^ expected `One`, got `Two<()>` + | +note: previous use here + --> $DIR/different_defining_uses_never_type3.rs:6:20 + | +LL | fn one() -> Tait { One } + | ^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs b/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs index 4f424b8c6..5f75fdc71 100644 --- a/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs +++ b/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs @@ -1,7 +1,11 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -type OneLifetime<'a, 'b> = impl std::fmt::Debug; +pub trait Captures<'a> {} + +impl<'a, T: ?Sized> Captures<'a> for T {} + +type OneLifetime<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>; fn foo<'a, 'b>(a: &'a u32, b: &'b u32) -> OneLifetime<'a, 'b> { a diff --git a/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr b/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr index 0c50a84e8..546598e8a 100644 --- a/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr +++ b/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr @@ -1,11 +1,11 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/different_lifetimes_defining_uses.rs:11:5 + --> $DIR/different_lifetimes_defining_uses.rs:15:5 | LL | b | ^ expected `&'a u32`, got `&'b u32` | note: previous use here - --> $DIR/different_lifetimes_defining_uses.rs:7:5 + --> $DIR/different_lifetimes_defining_uses.rs:11:5 | LL | a | ^ diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs index c9b9e128f..9d938a616 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs @@ -2,8 +2,11 @@ fn main() {} -type Two<'a, 'b> = impl std::fmt::Debug; +pub trait Captures<'a> {} +impl<'a, T: ?Sized> Captures<'a> for T {} + +type Two<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>; fn one<'a>(t: &'a ()) -> Two<'a, 'a> { t diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr index 222aaea78..72e1ef4b4 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr @@ -1,13 +1,13 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_lifetime_param.rs:9:5 + --> $DIR/generic_duplicate_lifetime_param.rs:12:5 | LL | t | ^ | note: lifetime used multiple times - --> $DIR/generic_duplicate_lifetime_param.rs:5:10 + --> $DIR/generic_duplicate_lifetime_param.rs:9:10 | -LL | type Two<'a, 'b> = impl std::fmt::Debug; +LL | type Two<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>; | ^^ ^^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs index 093c1c231..80462f8ac 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs @@ -7,7 +7,12 @@ fn main() {} // test that unused generic parameters are ok type TwoTys<T, U> = impl Debug; -type TwoLifetimes<'a, 'b> = impl Debug; + +pub trait Captures<'a> {} + +impl<'a, T: ?Sized> Captures<'a> for T {} + +type TwoLifetimes<'a, 'b> = impl Debug + Captures<'a> + Captures<'b>; type TwoConsts<const X: usize, const Y: usize> = impl Debug; diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr index b2edcc552..98e4bfea1 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr @@ -1,5 +1,5 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:16:5 + --> $DIR/generic_duplicate_param_use.rs:21:5 | LL | t | ^ @@ -11,25 +11,25 @@ LL | type TwoTys<T, U> = impl Debug; | ^ ^ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:21:5 + --> $DIR/generic_duplicate_param_use.rs:26:5 | LL | t | ^ | note: lifetime used multiple times - --> $DIR/generic_duplicate_param_use.rs:10:19 + --> $DIR/generic_duplicate_param_use.rs:15:19 | -LL | type TwoLifetimes<'a, 'b> = impl Debug; +LL | type TwoLifetimes<'a, 'b> = impl Debug + Captures<'a> + Captures<'b>; | ^^ ^^ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:26:5 + --> $DIR/generic_duplicate_param_use.rs:31:5 | LL | t | ^ | note: constant used multiple times - --> $DIR/generic_duplicate_param_use.rs:12:16 + --> $DIR/generic_duplicate_param_use.rs:17:16 | LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug; | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ diff --git a/src/test/ui/type-alias-impl-trait/generic_lifetime_param.rs b/src/test/ui/type-alias-impl-trait/generic_lifetime_param.rs index e109c38c9..106efefba 100644 --- a/src/test/ui/type-alias-impl-trait/generic_lifetime_param.rs +++ b/src/test/ui/type-alias-impl-trait/generic_lifetime_param.rs @@ -1,10 +1,11 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![feature(type_alias_impl_trait)] fn main() {} -type Region<'a> = impl std::fmt::Debug; +type Region<'a> = impl std::fmt::Debug + 'a; + fn region<'b>(a: &'b ()) -> Region<'b> { a diff --git a/src/test/ui/type-alias-impl-trait/implied_bounds.rs b/src/test/ui/type-alias-impl-trait/implied_bounds.rs new file mode 100644 index 000000000..53cbf8d22 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/implied_bounds.rs @@ -0,0 +1,51 @@ +#![feature(type_alias_impl_trait)] + +type WithLifetime<'a> = impl Equals<SelfType = ()>; +fn _defining_use<'a>() -> WithLifetime<'a> {} + +trait Convert<'a> { + type Witness; + fn convert<'b, T: ?Sized>(_proof: &'b Self::Witness, x: &'a T) -> &'b T; +} + +impl<'a> Convert<'a> for () { + type Witness = WithLifetime<'a>; + + fn convert<'b, T: ?Sized>(_proof: &'b WithLifetime<'a>, x: &'a T) -> &'b T { + // compiler used to think it gets to assume 'a: 'b here because + // of the `&'b WithLifetime<'a>` argument + x + //~^ ERROR lifetime may not live long enough + } +} + +fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T { + WithLifetime::<'a>::convert_helper::<(), T>(&(), x) +} + +trait Equals { + type SelfType; + fn convert_helper<'a, 'b, W: Convert<'a, Witness = Self>, T: ?Sized>( + proof: &'b Self::SelfType, + x: &'a T, + ) -> &'b T; +} + +impl<S> Equals for S { + type SelfType = Self; + fn convert_helper<'a, 'b, W: Convert<'a, Witness = Self>, T: ?Sized>( + proof: &'b Self, + x: &'a T, + ) -> &'b T { + W::convert(proof, x) + } +} + +fn main() { + let r; + { + let x = String::from("Hello World?"); + r = extend_lifetime(&x); + } + println!("{}", r); +} diff --git a/src/test/ui/type-alias-impl-trait/implied_bounds.stderr b/src/test/ui/type-alias-impl-trait/implied_bounds.stderr new file mode 100644 index 000000000..6f11b6663 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/implied_bounds.stderr @@ -0,0 +1,16 @@ +error: lifetime may not live long enough + --> $DIR/implied_bounds.rs:17:9 + | +LL | impl<'a> Convert<'a> for () { + | -- lifetime `'a` defined here +... +LL | fn convert<'b, T: ?Sized>(_proof: &'b WithLifetime<'a>, x: &'a T) -> &'b T { + | -- lifetime `'b` defined here +... +LL | x + | ^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/implied_bounds2.rs b/src/test/ui/type-alias-impl-trait/implied_bounds2.rs new file mode 100644 index 000000000..b4c4c013c --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/implied_bounds2.rs @@ -0,0 +1,10 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +type Ty<'a, A> = impl Sized + 'a; +fn defining<'a, A>() -> Ty<'a, A> {} +fn assert_static<T: 'static>() {} +fn test<'a, A>() where Ty<'a, A>: 'static, { assert_static::<Ty<'a, A>>() } + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/implied_bounds3.rs b/src/test/ui/type-alias-impl-trait/implied_bounds3.rs new file mode 100644 index 000000000..e39c61328 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/implied_bounds3.rs @@ -0,0 +1,18 @@ +// check-pass + +fn foo<F>(_: F) +where + F: 'static, +{ +} + +fn from<F: Send>(f: F) -> impl Send { + f +} + +fn bar<T>() { + foo(from(|| ())) +} + +fn main() { +} diff --git a/src/test/ui/type-alias-impl-trait/implied_bounds_closure.rs b/src/test/ui/type-alias-impl-trait/implied_bounds_closure.rs new file mode 100644 index 000000000..4cf35f951 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/implied_bounds_closure.rs @@ -0,0 +1,31 @@ +trait StaticDefaultRef: 'static { + fn default_ref() -> &'static Self; +} + +impl StaticDefaultRef for str { + fn default_ref() -> &'static str { + "" + } +} + +fn into_impl(x: &str) -> &(impl ?Sized + AsRef<str> + StaticDefaultRef + '_) { + x +} + +fn extend_lifetime<'a>(x: &'a str) -> &'static str { + let t = into_impl(x); + helper(|_| t) //~ ERROR lifetime may not live long enough +} + +fn helper<T: ?Sized + AsRef<str> + StaticDefaultRef>(f: impl FnOnce(&T) -> &T) -> &'static str { + f(T::default_ref()).as_ref() +} + +fn main() { + let r; + { + let x = String::from("Hello World?"); + r = extend_lifetime(&x); + } + println!("{}", r); +} diff --git a/src/test/ui/type-alias-impl-trait/implied_bounds_closure.stderr b/src/test/ui/type-alias-impl-trait/implied_bounds_closure.stderr new file mode 100644 index 000000000..151564c3b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/implied_bounds_closure.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/implied_bounds_closure.rs:17:16 + | +LL | fn extend_lifetime<'a>(x: &'a str) -> &'static str { + | -- lifetime `'a` defined here +LL | let t = into_impl(x); +LL | helper(|_| t) + | ^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/implied_bounds_from_types.rs b/src/test/ui/type-alias-impl-trait/implied_bounds_from_types.rs new file mode 100644 index 000000000..8023cd24f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/implied_bounds_from_types.rs @@ -0,0 +1,51 @@ +#![feature(type_alias_impl_trait)] + +type WithLifetime<T> = impl Equals<SelfType = ()>; +fn _defining_use<T>() -> WithLifetime<T> {} + +trait Convert<'a> { + type Witness; + fn convert<'b, T: ?Sized>(_proof: &'b Self::Witness, x: &'a T) -> &'b T; +} + +impl<'a> Convert<'a> for () { + type Witness = WithLifetime<&'a ()>; + + fn convert<'b, T: ?Sized>(_proof: &'b WithLifetime<&'a ()>, x: &'a T) -> &'b T { + // compiler used to think it gets to assume 'a: 'b here because + // of the `&'b WithLifetime<&'a ()>` argument + x + //~^ ERROR lifetime may not live long enough + } +} + +fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T { + WithLifetime::<&'a ()>::convert_helper::<(), T>(&(), x) +} + +trait Equals { + type SelfType; + fn convert_helper<'a, 'b, W: Convert<'a, Witness = Self>, T: ?Sized>( + proof: &'b Self::SelfType, + x: &'a T, + ) -> &'b T; +} + +impl<S> Equals for S { + type SelfType = Self; + fn convert_helper<'a, 'b, W: Convert<'a, Witness = Self>, T: ?Sized>( + proof: &'b Self, + x: &'a T, + ) -> &'b T { + W::convert(proof, x) + } +} + +fn main() { + let r; + { + let x = String::from("Hello World?"); + r = extend_lifetime(&x); + } + println!("{}", r); +} diff --git a/src/test/ui/type-alias-impl-trait/implied_bounds_from_types.stderr b/src/test/ui/type-alias-impl-trait/implied_bounds_from_types.stderr new file mode 100644 index 000000000..cbc5e6073 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/implied_bounds_from_types.stderr @@ -0,0 +1,16 @@ +error: lifetime may not live long enough + --> $DIR/implied_bounds_from_types.rs:17:9 + | +LL | impl<'a> Convert<'a> for () { + | -- lifetime `'a` defined here +... +LL | fn convert<'b, T: ?Sized>(_proof: &'b WithLifetime<&'a ()>, x: &'a T) -> &'b T { + | -- lifetime `'b` defined here +... +LL | x + | ^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs b/src/test/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs new file mode 100644 index 000000000..b6a7264a5 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs @@ -0,0 +1,27 @@ +#![feature(type_alias_impl_trait)] + +// known-bug: #99840 +// this should not compile +// check-pass + +type Alias = impl Sized; + +fn constrain() -> Alias { + 1i32 +} + +trait HideIt { + type Assoc; +} + +impl HideIt for () { + type Assoc = Alias; +} + +pub trait Yay {} + +impl Yay for <() as HideIt>::Assoc {} +// impl Yay for i32 {} // this already errors +// impl Yay for u32 {} // this also already errors + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs b/src/test/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs new file mode 100644 index 000000000..07f825aea --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs @@ -0,0 +1,43 @@ +#![feature(type_alias_impl_trait)] + +mod test_lifetime_param { + type Ty<'a> = impl Sized + 'a; + fn defining(a: &str) -> Ty<'_> { a } + fn assert_static<'a: 'static>() {} + //~^ WARN: unnecessary lifetime parameter `'a` + fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() } + //~^ ERROR: lifetime may not live long enough +} + +mod test_higher_kinded_lifetime_param { + type Ty<'a> = impl Sized + 'a; + fn defining(a: &str) -> Ty<'_> { a } + fn assert_static<'a: 'static>() {} + //~^ WARN: unnecessary lifetime parameter `'a` + fn test<'a>() where for<'b> Ty<'b>: 'a { assert_static::<'a>() } + //~^ ERROR: lifetime may not live long enough +} + +mod test_higher_kinded_lifetime_param2 { + fn assert_static<'a: 'static>() {} + //~^ WARN: unnecessary lifetime parameter `'a` + fn test<'a>() { assert_static::<'a>() } + //~^ ERROR: lifetime may not live long enough +} + +mod test_type_param { + type Ty<A> = impl Sized; + fn defining<A>(s: A) -> Ty<A> { s } + fn assert_static<A: 'static>() {} + fn test<A>() where Ty<A>: 'static { assert_static::<A>() } + //~^ ERROR: parameter type `A` may not live long enough +} + +mod test_implied_from_fn_sig { + type Opaque<T: 'static> = impl Sized; + fn defining<T: 'static>() -> Opaque<T> {} + fn assert_static<T: 'static>() {} + fn test<T>(_: Opaque<T>) { assert_static::<T>(); } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr b/src/test/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr new file mode 100644 index 000000000..887620a4d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr @@ -0,0 +1,58 @@ +warning: unnecessary lifetime parameter `'a` + --> $DIR/implied_lifetime_wf_check3.rs:6:22 + | +LL | fn assert_static<'a: 'static>() {} + | ^^ + | + = help: you can use the `'static` lifetime directly, in place of `'a` + +warning: unnecessary lifetime parameter `'a` + --> $DIR/implied_lifetime_wf_check3.rs:15:22 + | +LL | fn assert_static<'a: 'static>() {} + | ^^ + | + = help: you can use the `'static` lifetime directly, in place of `'a` + +warning: unnecessary lifetime parameter `'a` + --> $DIR/implied_lifetime_wf_check3.rs:22:22 + | +LL | fn assert_static<'a: 'static>() {} + | ^^ + | + = help: you can use the `'static` lifetime directly, in place of `'a` + +error: lifetime may not live long enough + --> $DIR/implied_lifetime_wf_check3.rs:8:43 + | +LL | fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() } + | -- lifetime `'a` defined here ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/implied_lifetime_wf_check3.rs:17:46 + | +LL | fn test<'a>() where for<'b> Ty<'b>: 'a { assert_static::<'a>() } + | -- lifetime `'a` defined here ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/implied_lifetime_wf_check3.rs:24:21 + | +LL | fn test<'a>() { assert_static::<'a>() } + | -- ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + | | + | lifetime `'a` defined here + +error[E0310]: the parameter type `A` may not live long enough + --> $DIR/implied_lifetime_wf_check3.rs:32:41 + | +LL | fn test<A>() where Ty<A>: 'static { assert_static::<A>() } + | ^^^^^^^^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn test<A: 'static>() where Ty<A>: 'static { assert_static::<A>() } + | +++++++++ + +error: aborting due to 4 previous errors; 3 warnings emitted + +For more information about this error, try `rustc --explain E0310`. diff --git a/src/test/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs b/src/test/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs new file mode 100644 index 000000000..ac32dbde0 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs @@ -0,0 +1,11 @@ +#![feature(type_alias_impl_trait)] + +mod test_type_param_static { + type Ty<A> = impl Sized + 'static; + //~^ ERROR: the parameter type `A` may not live long enough + fn defining<A: 'static>(s: A) -> Ty<A> { s } + fn assert_static<A: 'static>() {} + fn test<A>() where Ty<A>: 'static { assert_static::<A>() } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr b/src/test/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr new file mode 100644 index 000000000..47bc31e78 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr @@ -0,0 +1,14 @@ +error[E0310]: the parameter type `A` may not live long enough + --> $DIR/implied_lifetime_wf_check4_static.rs:4:18 + | +LL | type Ty<A> = impl Sized + 'static; + | ^^^^^^^^^^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | type Ty<A: 'static> = impl Sized + 'static; + | +++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/src/test/ui/type-alias-impl-trait/issue-101750.rs b/src/test/ui/type-alias-impl-trait/issue-101750.rs new file mode 100644 index 000000000..f564f4fa7 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-101750.rs @@ -0,0 +1,37 @@ +#![feature(type_alias_impl_trait)] + +// check-pass + +trait Trait {} + +type TAIT = impl Trait; + +struct Concrete; +impl Trait for Concrete {} + +fn tait() -> TAIT { + Concrete +} + +trait OuterTrait { + type Item; +} +struct Dummy<T> { + t: T, +} +impl<T> OuterTrait for Dummy<T> { + type Item = T; +} + +fn tait_and_impl_trait() -> impl OuterTrait<Item = (TAIT, impl Trait)> { + Dummy { + t: (tait(), Concrete), + } +} + +fn tait_and_dyn_trait() -> impl OuterTrait<Item = (TAIT, Box<dyn Trait>)> { + let b: Box<dyn Trait> = Box::new(Concrete); + Dummy { t: (tait(), b) } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr index d20b1cc6d..0a34e8486 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr @@ -1,10 +1,11 @@ -error[E0275]: overflow evaluating the requirement `fn() -> Foo {foo}: Sized` +error[E0275]: overflow evaluating the requirement `Foo: Sized` --> $DIR/issue-53398-cyclic-types.rs:5:13 | LL | fn foo() -> Foo { | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_53398_cyclic_types`) + = note: required because it appears within the type `fn() -> Foo {foo}` error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr index f14bf6b0f..6344f114a 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | |x| x | ^^^^^ one type is more general than the other | - = note: expected trait `for<'r> Fn<(&'r X,)>` + = note: expected trait `for<'a> Fn<(&'a X,)>` found trait `Fn<(&X,)>` note: this closure does not fulfill the lifetime requirements --> $DIR/issue-57611-trait-alias.rs:21:9 diff --git a/src/test/ui/type-alias-impl-trait/issue-58662-generator-with-lifetime.rs b/src/test/ui/type-alias-impl-trait/issue-58662-generator-with-lifetime.rs index f20ddf020..477b61390 100644 --- a/src/test/ui/type-alias-impl-trait/issue-58662-generator-with-lifetime.rs +++ b/src/test/ui/type-alias-impl-trait/issue-58662-generator-with-lifetime.rs @@ -16,7 +16,7 @@ fn rand_generator<'a>(rng: &'a ()) -> RandGenerator<'a> { } } -pub type RandGeneratorWithIndirection<'a> = impl Generator<Return = (), Yield = u64> + 'a; +pub type RandGeneratorWithIndirection<'c> = impl Generator<Return = (), Yield = u64> + 'c; pub fn rand_generator_with_indirection<'a>(rng: &'a ()) -> RandGeneratorWithIndirection<'a> { fn helper<'b>(rng: &'b ()) -> impl 'b + Generator<Return = (), Yield = u64> { move || { diff --git a/src/test/ui/type-alias-impl-trait/issue-58662-simplified.rs b/src/test/ui/type-alias-impl-trait/issue-58662-simplified.rs new file mode 100644 index 000000000..27ca7d0fd --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-58662-simplified.rs @@ -0,0 +1,20 @@ +// check-pass + +#![feature(generators, generator_trait)] +#![feature(type_alias_impl_trait)] + +trait Trait {} + +impl<T> Trait for T {} + +type Foo<'c> = impl Trait + 'c; +fn foo<'a>(rng: &'a ()) -> Foo<'a> { + fn helper<'b>(rng: &'b ()) -> impl 'b + Trait { + rng + } + + helper(rng) +} + +fn main() { +} diff --git a/src/test/ui/type-alias-impl-trait/issue-89686.rs b/src/test/ui/type-alias-impl-trait/issue-89686.rs index de070fc9d..058417bdb 100644 --- a/src/test/ui/type-alias-impl-trait/issue-89686.rs +++ b/src/test/ui/type-alias-impl-trait/issue-89686.rs @@ -4,7 +4,7 @@ use std::future::Future; -type G<'a, T> = impl Future<Output = ()>; +type G<'a, T> = impl Future<Output = ()> + 'a; trait Trait { type F: Future<Output = ()>; diff --git a/src/test/ui/type-alias-impl-trait/issue-89686.stderr b/src/test/ui/type-alias-impl-trait/issue-89686.stderr index b636ada8b..3b95a575a 100644 --- a/src/test/ui/type-alias-impl-trait/issue-89686.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-89686.stderr @@ -6,7 +6,7 @@ LL | async move { self.f().await } | help: consider restricting type parameter `T` | -LL | type G<'a, T: Trait> = impl Future<Output = ()>; +LL | type G<'a, T: Trait> = impl Future<Output = ()> + 'a; | +++++++ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/issue-96572-unconstrained-mismatch.rs b/src/test/ui/type-alias-impl-trait/issue-96572-unconstrained-mismatch.rs new file mode 100644 index 000000000..825710851 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-96572-unconstrained-mismatch.rs @@ -0,0 +1,10 @@ +#![feature(type_alias_impl_trait)] + +fn main() { + type T = impl Copy; + let foo: T = Some((1u32, 2u32)); + match foo { + None => (), + Some((a, b, c)) => (), //~ ERROR mismatched types + } +} diff --git a/src/test/ui/type-alias-impl-trait/issue-96572-unconstrained-mismatch.stderr b/src/test/ui/type-alias-impl-trait/issue-96572-unconstrained-mismatch.stderr new file mode 100644 index 000000000..728244a18 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-96572-unconstrained-mismatch.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/issue-96572-unconstrained-mismatch.rs:8:14 + | +LL | match foo { + | --- this expression has type `T` +LL | None => (), +LL | Some((a, b, c)) => (), + | ^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements + | + = note: expected tuple `(u32, u32)` + found tuple `(_, _, _)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/issue-96572-unconstrained.rs b/src/test/ui/type-alias-impl-trait/issue-96572-unconstrained.rs new file mode 100644 index 000000000..2c740ccc1 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-96572-unconstrained.rs @@ -0,0 +1,92 @@ +#![feature(type_alias_impl_trait)] +// check-pass + +fn main() { + type T = impl Copy; + let foo: T = Some((1u32, 2u32)); + match foo { + None => (), + Some((a, b)) => (), + } +} + +fn upvar() { + #[derive(Copy, Clone)] + struct Foo((u32, u32)); + + type T = impl Copy; + let foo: T = Foo((1u32, 2u32)); + let x = move || { + let Foo((a, b)) = foo; + }; +} + +fn enum_upvar() { + type T = impl Copy; + let foo: T = Some((1u32, 2u32)); + let x = move || { + match foo { + None => (), + Some((a, b)) => (), + } + }; +} + +fn r#struct() { + #[derive(Copy, Clone)] + struct Foo((u32, u32)); + + type U = impl Copy; + let foo: U = Foo((1u32, 2u32)); + let Foo((a, b)) = foo; +} + +mod only_pattern { + type T = impl Copy; + + fn foo(foo: T) { + let (mut x, mut y) = foo; + x = 42; + y = "foo"; + } + + type U = impl Copy; + + fn bar(bar: Option<U>) { + match bar { + Some((mut x, mut y)) => { + x = 42; + y = "foo"; + } + None => {} + } + } +} + +mod only_pattern_rpit { + #[allow(unconditional_recursion)] + fn foo(b: bool) -> impl Copy { + let (mut x, mut y) = foo(false); + x = 42; + y = "foo"; + if b { + panic!() + } else { + foo(true) + } + } + + fn bar(b: bool) -> Option<impl Copy> { + if b { + return None; + } + match bar(!b) { + Some((mut x, mut y)) => { + x = 42; + y = "foo"; + } + None => {} + } + None + } +} diff --git a/src/test/ui/type-alias-impl-trait/missing_lifetime_bound.rs b/src/test/ui/type-alias-impl-trait/missing_lifetime_bound.rs new file mode 100644 index 000000000..428194058 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/missing_lifetime_bound.rs @@ -0,0 +1,7 @@ +#![feature(type_alias_impl_trait)] + +type Opaque<'a, T> = impl Sized; +fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x } +//~^ ERROR: non-defining opaque type use in defining scope + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/missing_lifetime_bound.stderr b/src/test/ui/type-alias-impl-trait/missing_lifetime_bound.stderr new file mode 100644 index 000000000..df2b3ed19 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/missing_lifetime_bound.stderr @@ -0,0 +1,8 @@ +error: non-defining opaque type use in defining scope + --> $DIR/missing_lifetime_bound.rs:4:47 + | +LL | fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x } + | ^ lifetime `'a` is part of concrete type but not used in parameter list of the `impl Trait` type alias + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs index 3f122f106..65eb2952e 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs @@ -1,6 +1,10 @@ #![feature(type_alias_impl_trait)] -type Foo<'a, 'b> = impl std::fmt::Debug; +pub trait Captures<'a> {} + +impl<'a, T: ?Sized> Captures<'a> for T {} + +type Foo<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>; fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) { (i, i) //~ ERROR concrete type differs from previous diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr index 81e603e23..d7676b8e9 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr @@ -1,5 +1,5 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5 + --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:10:5 | LL | (i, i) | ^^^^^^ diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs index 83fd9a1da..21fca047a 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs @@ -7,7 +7,11 @@ fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) (a.clone(), a) } -type Foo<'a, 'b> = impl std::fmt::Debug; +pub trait Captures<'a> {} + +impl<'a, T: ?Sized> Captures<'a> for T {} + +type Foo<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>; fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) { (i, j) diff --git a/src/test/ui/type-alias-impl-trait/unbounded_opaque_type.rs b/src/test/ui/type-alias-impl-trait/unbounded_opaque_type.rs new file mode 100644 index 000000000..f43ad7dce --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/unbounded_opaque_type.rs @@ -0,0 +1,14 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +type Opaque<T> = impl Sized; +fn defining<T>() -> Opaque<T> {} +struct Ss<'a, T>(&'a Opaque<T>); + + +fn test<'a, T>(_: Ss<'a, T>) { + // test that we have an implied bound `Opaque<T>: 'a` from fn signature + None::<&'a Opaque<T>>; +} + +fn main() {} |