diff options
Diffstat (limited to '')
63 files changed, 1240 insertions, 97 deletions
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr index aaa3159e0..0202a2fea 100644 --- a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr +++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr @@ -4,7 +4,6 @@ error: ambiguous associated item LL | fn f() -> Self::V { 0 } | ^^^^^^^ help: use fully-qualified syntax: `<E as Tr>::V` | - = note: `#[deny(ambiguous_associated_items)]` on by default = 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 #57644 <https://github.com/rust-lang/rust/issues/57644> note: `V` could refer to the variant defined here @@ -17,6 +16,7 @@ note: `V` could also refer to the associated type defined here | LL | type V; | ^^^^^^ + = note: `#[deny(ambiguous_associated_items)]` on by default error: ambiguous associated item --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:32:15 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() {} diff --git a/src/test/ui/type/issue-101866.rs b/src/test/ui/type/issue-101866.rs new file mode 100644 index 000000000..d332c4adb --- /dev/null +++ b/src/test/ui/type/issue-101866.rs @@ -0,0 +1,15 @@ +trait TraitA<T> { + fn func(); +} + +struct StructA {} + +impl TraitA<i32> for StructA { + fn func() {} +} + +fn main() { + TraitA::<i32>::func(); + //~^ ERROR: cannot call associated function on trait without specifying the corresponding `impl` type [E0790] + //~| help: use the fully-qualified path to the only available implementation +} diff --git a/src/test/ui/type/issue-101866.stderr b/src/test/ui/type/issue-101866.stderr new file mode 100644 index 000000000..fe9982119 --- /dev/null +++ b/src/test/ui/type/issue-101866.stderr @@ -0,0 +1,18 @@ +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type + --> $DIR/issue-101866.rs:12:5 + | +LL | fn func(); + | ---------- `TraitA::func` defined here +... +LL | TraitA::<i32>::func(); + | ^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait + | +help: use the fully-qualified path to the only available implementation + | +LL - TraitA::<i32>::func(); +LL + <StructA as TraitA<i32>>::func(); + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0790`. diff --git a/src/test/ui/type/issue-94187-verbose-type-name.rs b/src/test/ui/type/issue-94187-verbose-type-name.rs new file mode 100644 index 000000000..902ef5ade --- /dev/null +++ b/src/test/ui/type/issue-94187-verbose-type-name.rs @@ -0,0 +1,13 @@ +// Check to insure that the output of `std::any::type_name` does not change based on -Zverbose +// when printing constants +// run-pass +// edition: 2018 +// revisions: normal verbose +// [verbose]compile-flags:-Zverbose + +struct Wrapper<const VALUE: usize>; + +fn main() { + assert_eq!(std::any::type_name::<[u32; 0]>(), "[u32; 0]"); + assert_eq!(std::any::type_name::<Wrapper<0>>(), "issue_94187_verbose_type_name::Wrapper<0>"); +} diff --git a/src/test/ui/type/type-check/assignment-expected-bool.stderr b/src/test/ui/type/type-check/assignment-expected-bool.stderr index e2b821f7b..56494baff 100644 --- a/src/test/ui/type/type-check/assignment-expected-bool.stderr +++ b/src/test/ui/type/type-check/assignment-expected-bool.stderr @@ -7,7 +7,7 @@ LL | let _: bool = 0 = 0; help: you might have meant to compare for equality | LL | let _: bool = 0 == 0; - | ~~ + | + error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:9:14 @@ -18,7 +18,7 @@ LL | 0 => 0 = 0, help: you might have meant to compare for equality | LL | 0 => 0 == 0, - | ~~ + | + error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:10:14 @@ -29,7 +29,7 @@ LL | _ => 0 = 0, help: you might have meant to compare for equality | LL | _ => 0 == 0, - | ~~ + | + error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:14:17 @@ -40,7 +40,7 @@ LL | true => 0 = 0, help: you might have meant to compare for equality | LL | true => 0 == 0, - | ~~ + | + error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:18:8 @@ -51,7 +51,7 @@ LL | if 0 = 0 {} help: you might have meant to compare for equality | LL | if 0 == 0 {} - | ~~ + | + error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:20:24 @@ -62,7 +62,7 @@ LL | let _: bool = if { 0 = 0 } { help: you might have meant to compare for equality | LL | let _: bool = if { 0 == 0 } { - | ~~ + | + error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:21:9 @@ -73,7 +73,7 @@ LL | 0 = 0 help: you might have meant to compare for equality | LL | 0 == 0 - | ~~ + | + error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:23:9 @@ -84,7 +84,7 @@ LL | 0 = 0 help: you might have meant to compare for equality | LL | 0 == 0 - | ~~ + | + error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:26:13 @@ -95,7 +95,7 @@ LL | let _ = (0 = 0) help: you might have meant to compare for equality | LL | let _ = (0 == 0) - | ~~ + | + error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:27:14 @@ -106,7 +106,7 @@ LL | && { 0 = 0 } help: you might have meant to compare for equality | LL | && { 0 == 0 } - | ~~ + | + error[E0308]: mismatched types --> $DIR/assignment-expected-bool.rs:28:12 @@ -117,7 +117,7 @@ LL | || (0 = 0); help: you might have meant to compare for equality | LL | || (0 == 0); - | ~~ + | + error[E0070]: invalid left-hand side of assignment --> $DIR/assignment-expected-bool.rs:31:22 diff --git a/src/test/ui/type/type-check/assignment-in-if.rs b/src/test/ui/type/type-check/assignment-in-if.rs index 8da7b32b4..ada250df2 100644 --- a/src/test/ui/type/type-check/assignment-in-if.rs +++ b/src/test/ui/type/type-check/assignment-in-if.rs @@ -40,4 +40,23 @@ fn main() { ) { println!("{}", x); } + + if x == x && x = x && x == x { + //~^ ERROR mismatched types + //~| ERROR mismatched types + //~| ERROR mismatched types + println!("{}", x); + } + + if x == x && x == x && x = x { + //~^ ERROR mismatched types + //~| ERROR mismatched types + println!("{}", x); + } + + if x = 1 && x == 1 { + //~^ ERROR mismatched types + //~| ERROR mismatched types + println!("{}", x); + } } diff --git a/src/test/ui/type/type-check/assignment-in-if.stderr b/src/test/ui/type/type-check/assignment-in-if.stderr index f4ef44e24..8ab08e25e 100644 --- a/src/test/ui/type/type-check/assignment-in-if.stderr +++ b/src/test/ui/type/type-check/assignment-in-if.stderr @@ -7,7 +7,7 @@ LL | if x = x { help: you might have meant to compare for equality | LL | if x == x { - | ~~ + | + error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:20:8 @@ -18,7 +18,7 @@ LL | if (x = x) { help: you might have meant to compare for equality | LL | if (x == x) { - | ~~ + | + error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:25:8 @@ -29,7 +29,7 @@ LL | if y = (Foo { foo: x }) { help: you might have meant to compare for equality | LL | if y == (Foo { foo: x }) { - | ~~ + | + error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:30:8 @@ -40,7 +40,7 @@ LL | if 3 = x { help: you might have meant to compare for equality | LL | if 3 == x { - | ~~ + | + error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:36:13 @@ -51,7 +51,7 @@ LL | x = 4 help: you might have meant to compare for equality | LL | x == 4 - | ~~ + | + error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:38:13 @@ -62,8 +62,65 @@ LL | x = 5 help: you might have meant to compare for equality | LL | x == 5 - | ~~ + | + -error: aborting due to 6 previous errors +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:44:18 + | +LL | if x == x && x = x && x == x { + | ^ expected `bool`, found `usize` + +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:44:22 + | +LL | if x == x && x = x && x == x { + | ^ expected `bool`, found `usize` + +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:44:8 + | +LL | if x == x && x = x && x == x { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if x == x && x == x && x == x { + | + + +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:51:28 + | +LL | if x == x && x == x && x = x { + | ^ expected `bool`, found `usize` + +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:51:8 + | +LL | if x == x && x == x && x = x { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if x == x && x == x && x == x { + | + + +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:57:12 + | +LL | if x = 1 && x == 1 { + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:57:8 + | +LL | if x = 1 && x == 1 { + | ^^^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if x == 1 && x == 1 { + | + + +error: aborting due to 13 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-mismatch-same-crate-name.stderr b/src/test/ui/type/type-mismatch-same-crate-name.stderr index 783f747fa..fcafd315e 100644 --- a/src/test/ui/type/type-mismatch-same-crate-name.stderr +++ b/src/test/ui/type/type-mismatch-same-crate-name.stderr @@ -6,6 +6,17 @@ LL | a::try_foo(foo2); | | | arguments to this function are incorrect | + = note: struct `main::a::Foo` and struct `main::a::Foo` have similar names, but are actually distinct types +note: struct `main::a::Foo` is defined in crate `crate_a2` + --> $DIR/auxiliary/crate_a2.rs:1:1 + | +LL | pub struct Foo; + | ^^^^^^^^^^^^^^ +note: struct `main::a::Foo` is defined in crate `crate_a1` + --> $DIR/auxiliary/crate_a1.rs:1:1 + | +LL | pub struct Foo; + | ^^^^^^^^^^^^^^ = note: perhaps two different versions of crate `crate_a1` are being used? note: function defined here --> $DIR/auxiliary/crate_a1.rs:10:8 diff --git a/src/test/ui/type/type-recursive-box-shadowed.stderr b/src/test/ui/type/type-recursive-box-shadowed.stderr index c22d848f3..cb0e98287 100644 --- a/src/test/ui/type/type-recursive-box-shadowed.stderr +++ b/src/test/ui/type/type-recursive-box-shadowed.stderr @@ -2,12 +2,12 @@ error[E0072]: recursive type `Foo` has infinite size --> $DIR/type-recursive-box-shadowed.rs:7:1 | LL | struct Foo { - | ^^^^^^^^^^ recursive type has infinite size + | ^^^^^^^^^^ LL | LL | inner: Foo, | --- recursive without indirection | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Foo` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle | LL | inner: Box<Foo>, | ++++ + diff --git a/src/test/ui/type/type-recursive.stderr b/src/test/ui/type/type-recursive.stderr index 320271028..9a4d798f6 100644 --- a/src/test/ui/type/type-recursive.stderr +++ b/src/test/ui/type/type-recursive.stderr @@ -2,12 +2,12 @@ error[E0072]: recursive type `T1` has infinite size --> $DIR/type-recursive.rs:1:1 | LL | struct T1 { - | ^^^^^^^^^ recursive type has infinite size + | ^^^^^^^^^ LL | foo: isize, LL | foolish: T1, | -- recursive without indirection | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T1` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle | LL | foolish: Box<T1>, | ++++ + @@ -16,11 +16,11 @@ error[E0072]: recursive type `T2` has infinite size --> $DIR/type-recursive.rs:6:1 | LL | struct T2 { - | ^^^^^^^^^ recursive type has infinite size + | ^^^^^^^^^ LL | inner: Option<T2>, - | ---------- recursive without indirection + | -- recursive without indirection | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T2` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle | LL | inner: Option<Box<T2>>, | ++++ + @@ -29,11 +29,11 @@ error[E0072]: recursive type `T3` has infinite size --> $DIR/type-recursive.rs:12:1 | LL | struct T3 { - | ^^^^^^^^^ recursive type has infinite size + | ^^^^^^^^^ LL | inner: OptionT3, | -------- recursive without indirection | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T3` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle | LL | inner: Box<OptionT3>, | ++++ + @@ -42,11 +42,9 @@ error[E0072]: recursive type `T4` has infinite size --> $DIR/type-recursive.rs:16:1 | LL | struct T4(Option<T4>); - | ^^^^^^^^^ ---------- recursive without indirection - | | - | recursive type has infinite size + | ^^^^^^^^^ -- recursive without indirection | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T4` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle | LL | struct T4(Option<Box<T4>>); | ++++ + @@ -55,11 +53,11 @@ error[E0072]: recursive type `T5` has infinite size --> $DIR/type-recursive.rs:18:1 | LL | enum T5 { - | ^^^^^^^ recursive type has infinite size + | ^^^^^^^ LL | Variant(Option<T5>), - | ---------- recursive without indirection + | -- recursive without indirection | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T5` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle | LL | Variant(Option<Box<T5>>), | ++++ + @@ -68,11 +66,11 @@ error[E0072]: recursive type `T6` has infinite size --> $DIR/type-recursive.rs:22:1 | LL | enum T6 { - | ^^^^^^^ recursive type has infinite size + | ^^^^^^^ LL | Variant{ field: Option<T6> }, - | ---------- recursive without indirection + | -- recursive without indirection | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T6` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle | LL | Variant{ field: Option<Box<T6>> }, | ++++ + @@ -81,14 +79,14 @@ error[E0072]: recursive type `T7` has infinite size --> $DIR/type-recursive.rs:26:1 | LL | struct T7 { - | ^^^^^^^^^ recursive type has infinite size + | ^^^^^^^^^ LL | foo: std::cell::Cell<Option<T7>>, - | --------------------------- recursive without indirection + | -- recursive without indirection | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T7` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle | -LL | foo: Box<std::cell::Cell<Option<T7>>>, - | ++++ + +LL | foo: std::cell::Cell<Option<Box<T7>>>, + | ++++ + error: aborting due to 7 previous errors diff --git a/src/test/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.stderr b/src/test/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.stderr index 6bc9c8498..fc7c23a22 100644 --- a/src/test/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.stderr +++ b/src/test/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.stderr @@ -2,7 +2,9 @@ error: expected identifier, found `0` --> $DIR/issue-69378-ice-on-invalid-type-node-after-recovery.rs:3:14 | LL | struct Foo { 0: u8 } - | ^ expected identifier + | --- ^ expected identifier + | | + | while parsing this struct error: aborting due to previous error diff --git a/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr b/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr index a18c54a29..23e7b7cc3 100644 --- a/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr +++ b/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr @@ -4,7 +4,7 @@ error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo}` in the LL | thing.bar.foo(); | ^^^ method not found in `fn() -> Foo {Foo}` | -help: use parentheses to instantiate this tuple struct +help: use parentheses to construct this tuple struct | LL | (thing.bar)().foo(); | + +++ diff --git a/src/test/ui/typeck/issue-87181/enum-variant.stderr b/src/test/ui/typeck/issue-87181/enum-variant.stderr index 90641410d..2247ea270 100644 --- a/src/test/ui/typeck/issue-87181/enum-variant.stderr +++ b/src/test/ui/typeck/issue-87181/enum-variant.stderr @@ -4,7 +4,7 @@ error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo::Tup}` i LL | thing.bar.foo(); | ^^^ method not found in `fn() -> Foo {Foo::Tup}` | -help: use parentheses to instantiate this tuple variant +help: use parentheses to construct this tuple variant | LL | (thing.bar)().foo(); | + +++ diff --git a/src/test/ui/typeck/issue-87181/tuple-field.stderr b/src/test/ui/typeck/issue-87181/tuple-field.stderr index c1ca26ee9..0a7d30b61 100644 --- a/src/test/ui/typeck/issue-87181/tuple-field.stderr +++ b/src/test/ui/typeck/issue-87181/tuple-field.stderr @@ -4,7 +4,7 @@ error[E0609]: no field `0` on type `fn(char, u16) -> Foo {Foo}` LL | thing.bar.0; | ^ | -help: use parentheses to instantiate this tuple struct +help: use parentheses to construct this tuple struct | LL | (thing.bar)(/* char */, /* u16 */).0; | + ++++++++++++++++++++++++ diff --git a/src/test/ui/typeck/slow-lhs-suggestion.rs b/src/test/ui/typeck/slow-lhs-suggestion.rs new file mode 100644 index 000000000..80dfd6835 --- /dev/null +++ b/src/test/ui/typeck/slow-lhs-suggestion.rs @@ -0,0 +1,26 @@ +fn main() { + 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + //~^ ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment + //~| ERROR invalid left-hand side of assignment +} diff --git a/src/test/ui/typeck/slow-lhs-suggestion.stderr b/src/test/ui/typeck/slow-lhs-suggestion.stderr new file mode 100644 index 000000000..c5bf795ee --- /dev/null +++ b/src/test/ui/typeck/slow-lhs-suggestion.stderr @@ -0,0 +1,187 @@ +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:95 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:91 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:87 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:83 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:79 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:75 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:71 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:67 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:63 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:59 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:55 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:51 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:47 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:43 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:39 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:35 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:31 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:27 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:23 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:19 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:15 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:11 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error[E0070]: invalid left-hand side of assignment + --> $DIR/slow-lhs-suggestion.rs:2:7 + | +LL | 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1 = 1; + | - ^ + | | + | cannot assign to this expression + +error: aborting due to 23 previous errors + +For more information about this error, try `rustc --explain E0070`. |