diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/type | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
622 files changed, 15359 insertions, 0 deletions
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs new file mode 100644 index 000000000..0aa644db0 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs @@ -0,0 +1,59 @@ +// run-pass + +// Check that resolving, in the value namespace, to an `enum` variant +// through a type alias is well behaved in the presence of generics. +// We check for situations with: +// 1. a generic type `Alias<T>`, we can type-apply `Alias` when referring to a variant. +// 2. a monotype `AliasFixed` of generic `Enum<T>`, we can refer to variants +// and the type-application of `T` in `AliasFixed` is kept. + +#![allow(irrefutable_let_patterns)] + +enum Enum<T> { TSVariant(#[allow(unused_tuple_struct_fields)] T), SVariant { _v: T }, UVariant } +type Alias<T> = Enum<T>; +type AliasFixed = Enum<()>; + +macro_rules! is_variant { + (TSVariant, $expr:expr) => (is_variant!(@check TSVariant, (_), $expr)); + (SVariant, $expr:expr) => (is_variant!(@check SVariant, { _v: _ }, $expr)); + (UVariant, $expr:expr) => (is_variant!(@check UVariant, {}, $expr)); + (@check $variant:ident, $matcher:tt, $expr:expr) => ( + assert!(if let Enum::$variant::<()> $matcher = $expr { true } else { false }, + "expr does not have correct type"); + ); +} + +fn main() { + // Tuple struct variant + + is_variant!(TSVariant, Enum::TSVariant(())); + is_variant!(TSVariant, Enum::TSVariant::<()>(())); + is_variant!(TSVariant, Enum::<()>::TSVariant(())); + + is_variant!(TSVariant, Alias::TSVariant(())); + is_variant!(TSVariant, Alias::<()>::TSVariant(())); + + is_variant!(TSVariant, AliasFixed::TSVariant(())); + + // Struct variant + + is_variant!(SVariant, Enum::SVariant { _v: () }); + is_variant!(SVariant, Enum::SVariant::<()> { _v: () }); + is_variant!(SVariant, Enum::<()>::SVariant { _v: () }); + + is_variant!(SVariant, Alias::SVariant { _v: () }); + is_variant!(SVariant, Alias::<()>::SVariant { _v: () }); + + is_variant!(SVariant, AliasFixed::SVariant { _v: () }); + + // Unit variant + + is_variant!(UVariant, Enum::UVariant); + is_variant!(UVariant, Enum::UVariant::<()>); + is_variant!(UVariant, Enum::<()>::UVariant); + + is_variant!(UVariant, Alias::UVariant); + is_variant!(UVariant, Alias::<()>::UVariant); + + is_variant!(UVariant, AliasFixed::UVariant); +} diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs new file mode 100644 index 000000000..0031a4665 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs @@ -0,0 +1,105 @@ +// Checks that applied type arguments of enums, and aliases to them, are respected. +// For example, `Self` is never a type constructor. Therefore, no types can be applied to it. +// +// We also check that the variant to an type-aliased enum cannot be type applied whether +// that alias is generic or monomorphic. + +enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } +type Alias<T> = Enum<T>; +type AliasFixed = Enum<()>; + +impl<T> Enum<T> { + fn ts_variant() { + Self::TSVariant(()); + //~^ ERROR mismatched types [E0308] + Self::TSVariant::<()>(()); + //~^ ERROR type arguments are not allowed on this type [E0109] + Self::<()>::TSVariant(()); + //~^ ERROR type arguments are not allowed on self type [E0109] + //~| ERROR mismatched types [E0308] + Self::<()>::TSVariant::<()>(()); + //~^ ERROR type arguments are not allowed on self type [E0109] + //~| ERROR type arguments are not allowed on this type [E0109] + } + + fn s_variant() { + Self::SVariant { v: () }; + //~^ ERROR mismatched types [E0308] + Self::SVariant::<()> { v: () }; + //~^ ERROR type arguments are not allowed on this type [E0109] + //~| ERROR mismatched types [E0308] + Self::<()>::SVariant { v: () }; + //~^ ERROR type arguments are not allowed on self type [E0109] + //~| ERROR mismatched types [E0308] + Self::<()>::SVariant::<()> { v: () }; + //~^ ERROR type arguments are not allowed on self type [E0109] + //~| ERROR type arguments are not allowed on this type [E0109] + //~| ERROR mismatched types [E0308] + } + + fn u_variant() { + Self::UVariant::<()>; + //~^ ERROR type arguments are not allowed on this type [E0109] + Self::<()>::UVariant; + //~^ ERROR type arguments are not allowed on self type [E0109] + Self::<()>::UVariant::<()>; + //~^ ERROR type arguments are not allowed on self type [E0109] + //~| ERROR type arguments are not allowed on this type [E0109] + } +} + +fn main() { + // Tuple struct variant + + Enum::<()>::TSVariant::<()>(()); + //~^ ERROR type arguments are not allowed on tuple variant `TSVariant` [E0109] + + Alias::TSVariant::<()>(()); + //~^ ERROR type arguments are not allowed on this type [E0109] + Alias::<()>::TSVariant::<()>(()); + //~^ ERROR type arguments are not allowed on this type [E0109] + + AliasFixed::TSVariant::<()>(()); + //~^ ERROR type arguments are not allowed on this type [E0109] + AliasFixed::<()>::TSVariant(()); + //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] + AliasFixed::<()>::TSVariant::<()>(()); + //~^ ERROR type arguments are not allowed on this type [E0109] + //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] + + // Struct variant + + Enum::<()>::SVariant::<()> { v: () }; + //~^ ERROR type arguments are not allowed on variant `SVariant` [E0109] + + Alias::SVariant::<()> { v: () }; + //~^ ERROR type arguments are not allowed on this type [E0109] + Alias::<()>::SVariant::<()> { v: () }; + //~^ ERROR type arguments are not allowed on this type [E0109] + + AliasFixed::SVariant::<()> { v: () }; + //~^ ERROR type arguments are not allowed on this type [E0109] + AliasFixed::<()>::SVariant { v: () }; + //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] + AliasFixed::<()>::SVariant::<()> { v: () }; + //~^ ERROR type arguments are not allowed on this type [E0109] + //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] + + // Unit variant + + Enum::<()>::UVariant::<()>; + //~^ ERROR type arguments are not allowed on unit variant `UVariant` [E0109] + + Alias::UVariant::<()>; + //~^ ERROR type arguments are not allowed on this type [E0109] + Alias::<()>::UVariant::<()>; + //~^ ERROR type arguments are not allowed on this type [E0109] + + AliasFixed::UVariant::<()>; + //~^ ERROR type arguments are not allowed on this type [E0109] + AliasFixed::<()>::UVariant; + //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] + AliasFixed::<()>::UVariant::<()>; + //~^ ERROR type arguments are not allowed on this type [E0109] + //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] +} diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr new file mode 100644 index 000000000..a922d7a5e --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr @@ -0,0 +1,512 @@ +error[E0308]: mismatched types + --> $DIR/enum-variant-generic-args.rs:13:25 + | +LL | impl<T> Enum<T> { + | - this type parameter +LL | fn ts_variant() { +LL | Self::TSVariant(()); + | --------------- ^^ expected type parameter `T`, found `()` + | | + | arguments to this enum variant are incorrect + | + = note: expected type parameter `T` + found unit type `()` +note: tuple variant defined here + --> $DIR/enum-variant-generic-args.rs:7:16 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^^^^^^ + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:15:27 + | +LL | Self::TSVariant::<()>(()); + | --------- ^^ type argument not allowed + | | + | not allowed on this type + +error[E0109]: type arguments are not allowed on self type + --> $DIR/enum-variant-generic-args.rs:17:16 + | +LL | Self::<()>::TSVariant(()); + | ---- ^^ type argument not allowed + | | + | not allowed on self type + | +note: `Self` is of type `Enum<T>` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl<T> Enum<T> { + | --------------- `Self` is on type `Enum` in this `impl` +help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters + | +LL | Enum::<()>::TSVariant(()); + | ~~~~ + +error[E0308]: mismatched types + --> $DIR/enum-variant-generic-args.rs:17:31 + | +LL | impl<T> Enum<T> { + | - this type parameter +... +LL | Self::<()>::TSVariant(()); + | --------------------- ^^ expected type parameter `T`, found `()` + | | + | arguments to this enum variant are incorrect + | + = note: expected type parameter `T` + found unit type `()` +note: tuple variant defined here + --> $DIR/enum-variant-generic-args.rs:7:16 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^^^^^^ + +error[E0109]: type arguments are not allowed on self type + --> $DIR/enum-variant-generic-args.rs:20:16 + | +LL | Self::<()>::TSVariant::<()>(()); + | ---- ^^ type argument not allowed + | | + | not allowed on self type + | +note: `Self` is of type `Enum<T>` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl<T> Enum<T> { + | --------------- `Self` is on type `Enum` in this `impl` +help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters + | +LL | Enum::<()>::TSVariant::<()>(()); + | ~~~~ + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:20:33 + | +LL | Self::<()>::TSVariant::<()>(()); + | --------- ^^ type argument not allowed + | | + | not allowed on this type + +error[E0308]: mismatched types + --> $DIR/enum-variant-generic-args.rs:26:29 + | +LL | impl<T> Enum<T> { + | - this type parameter +... +LL | Self::SVariant { v: () }; + | ^^ expected type parameter `T`, found `()` + | + = note: expected type parameter `T` + found unit type `()` + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:28:26 + | +LL | Self::SVariant::<()> { v: () }; + | -------- ^^ type argument not allowed + | | + | not allowed on this type + | + = note: enum variants can't have type parameters +help: you might have meant to specity type parameters on enum `Enum` + | +LL - Self::SVariant::<()> { v: () }; +LL + Enum::<()>::SVariant { v: () }; + | + +error[E0308]: mismatched types + --> $DIR/enum-variant-generic-args.rs:28:35 + | +LL | impl<T> Enum<T> { + | - this type parameter +... +LL | Self::SVariant::<()> { v: () }; + | ^^ expected type parameter `T`, found `()` + | + = note: expected type parameter `T` + found unit type `()` + +error[E0109]: type arguments are not allowed on self type + --> $DIR/enum-variant-generic-args.rs:31:16 + | +LL | Self::<()>::SVariant { v: () }; + | ---- ^^ type argument not allowed + | | + | not allowed on self type + | +note: `Self` is of type `Enum<T>` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl<T> Enum<T> { + | --------------- `Self` is on type `Enum` in this `impl` +help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters + | +LL | Enum::<()>::SVariant { v: () }; + | ~~~~ + +error[E0308]: mismatched types + --> $DIR/enum-variant-generic-args.rs:31:35 + | +LL | impl<T> Enum<T> { + | - this type parameter +... +LL | Self::<()>::SVariant { v: () }; + | ^^ expected type parameter `T`, found `()` + | + = note: expected type parameter `T` + found unit type `()` + +error[E0109]: type arguments are not allowed on self type + --> $DIR/enum-variant-generic-args.rs:34:16 + | +LL | Self::<()>::SVariant::<()> { v: () }; + | ---- ^^ type argument not allowed + | | + | not allowed on self type + | +note: `Self` is of type `Enum<T>` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl<T> Enum<T> { + | --------------- `Self` is on type `Enum` in this `impl` +help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters + | +LL | Enum::<()>::SVariant::<()> { v: () }; + | ~~~~ + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:34:32 + | +LL | Self::<()>::SVariant::<()> { v: () }; + | -------- ^^ type argument not allowed + | | + | not allowed on this type + | + = note: enum variants can't have type parameters +help: you might have meant to specity type parameters on enum `Enum` + | +LL - Self::<()>::SVariant::<()> { v: () }; +LL + Enum::<()>::SVariant { v: () }; + | + +error[E0308]: mismatched types + --> $DIR/enum-variant-generic-args.rs:34:41 + | +LL | impl<T> Enum<T> { + | - this type parameter +... +LL | Self::<()>::SVariant::<()> { v: () }; + | ^^ expected type parameter `T`, found `()` + | + = note: expected type parameter `T` + found unit type `()` + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:41:26 + | +LL | Self::UVariant::<()>; + | -------- ^^ type argument not allowed + | | + | not allowed on this type + +error[E0109]: type arguments are not allowed on self type + --> $DIR/enum-variant-generic-args.rs:43:16 + | +LL | Self::<()>::UVariant; + | ---- ^^ type argument not allowed + | | + | not allowed on self type + | +note: `Self` is of type `Enum<T>` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl<T> Enum<T> { + | --------------- `Self` is on type `Enum` in this `impl` +help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters + | +LL | Enum::<()>::UVariant; + | ~~~~ + +error[E0109]: type arguments are not allowed on self type + --> $DIR/enum-variant-generic-args.rs:45:16 + | +LL | Self::<()>::UVariant::<()>; + | ---- ^^ type argument not allowed + | | + | not allowed on self type + | +note: `Self` is of type `Enum<T>` + --> $DIR/enum-variant-generic-args.rs:7:6 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^ `Self` corresponds to this type +... +LL | impl<T> Enum<T> { + | --------------- `Self` is on type `Enum` in this `impl` +help: the `Self` type doesn't accept type parameters, use the concrete type's name `Enum` instead if you want to specify its type parameters + | +LL | Enum::<()>::UVariant::<()>; + | ~~~~ + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:45:32 + | +LL | Self::<()>::UVariant::<()>; + | -------- ^^ type argument not allowed + | | + | not allowed on this type + +error[E0109]: type arguments are not allowed on tuple variant `TSVariant` + --> $DIR/enum-variant-generic-args.rs:54:29 + | +LL | Enum::<()>::TSVariant::<()>(()); + | --------- ^^ type argument not allowed + | | + | not allowed on tuple variant `TSVariant` + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:57:24 + | +LL | Alias::TSVariant::<()>(()); + | --------- ^^ type argument not allowed + | | + | not allowed on this type + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:59:30 + | +LL | Alias::<()>::TSVariant::<()>(()); + | --------- ^^ type argument not allowed + | | + | not allowed on this type + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:62:29 + | +LL | AliasFixed::TSVariant::<()>(()); + | --------- ^^ type argument not allowed + | | + | not allowed on this type + +error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/enum-variant-generic-args.rs:64:5 + | +LL | AliasFixed::<()>::TSVariant(()); + | ^^^^^^^^^^------ help: remove these generics + | | + | expected 0 generic arguments + | +note: type alias defined here, with 0 generic parameters + --> $DIR/enum-variant-generic-args.rs:9:6 + | +LL | type AliasFixed = Enum<()>; + | ^^^^^^^^^^ + +error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/enum-variant-generic-args.rs:66:5 + | +LL | AliasFixed::<()>::TSVariant::<()>(()); + | ^^^^^^^^^^------ help: remove these generics + | | + | expected 0 generic arguments + | +note: type alias defined here, with 0 generic parameters + --> $DIR/enum-variant-generic-args.rs:9:6 + | +LL | type AliasFixed = Enum<()>; + | ^^^^^^^^^^ + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:66:35 + | +LL | AliasFixed::<()>::TSVariant::<()>(()); + | --------- ^^ type argument not allowed + | | + | not allowed on this type + +error[E0109]: type arguments are not allowed on variant `SVariant` + --> $DIR/enum-variant-generic-args.rs:72:28 + | +LL | Enum::<()>::SVariant::<()> { v: () }; + | -------- ^^ type argument not allowed + | | + | not allowed on variant `SVariant` + | + = note: enum variants can't have type parameters + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:75:23 + | +LL | Alias::SVariant::<()> { v: () }; + | -------- ^^ type argument not allowed + | | + | not allowed on this type + | + = note: enum variants can't have type parameters +help: you might have meant to specity type parameters on enum `Enum` + | +LL - Alias::SVariant::<()> { v: () }; +LL + Alias::<()>::SVariant { v: () }; + | + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:77:29 + | +LL | Alias::<()>::SVariant::<()> { v: () }; + | -------- ^^ type argument not allowed + | | + | not allowed on this type + | + = note: enum variants can't have type parameters +help: you might have meant to specity type parameters on enum `Enum` + | +LL - Alias::<()>::SVariant::<()> { v: () }; +LL + Alias::<()>::SVariant { v: () }; + | + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:80:28 + | +LL | AliasFixed::SVariant::<()> { v: () }; + | -------- ^^ type argument not allowed + | | + | not allowed on this type + | + = note: enum variants can't have type parameters +help: you might have meant to specity type parameters on enum `Enum` + | +LL - AliasFixed::SVariant::<()> { v: () }; +LL + AliasFixed::<()>::SVariant { v: () }; + | + +error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/enum-variant-generic-args.rs:82:5 + | +LL | AliasFixed::<()>::SVariant { v: () }; + | ^^^^^^^^^^------ help: remove these generics + | | + | expected 0 generic arguments + | +note: type alias defined here, with 0 generic parameters + --> $DIR/enum-variant-generic-args.rs:9:6 + | +LL | type AliasFixed = Enum<()>; + | ^^^^^^^^^^ + +error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/enum-variant-generic-args.rs:84:5 + | +LL | AliasFixed::<()>::SVariant::<()> { v: () }; + | ^^^^^^^^^^------ help: remove these generics + | | + | expected 0 generic arguments + | +note: type alias defined here, with 0 generic parameters + --> $DIR/enum-variant-generic-args.rs:9:6 + | +LL | type AliasFixed = Enum<()>; + | ^^^^^^^^^^ + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:84:34 + | +LL | AliasFixed::<()>::SVariant::<()> { v: () }; + | -------- ^^ type argument not allowed + | | + | not allowed on this type + | + = note: enum variants can't have type parameters +help: you might have meant to specity type parameters on enum `Enum` + | +LL - AliasFixed::<()>::SVariant::<()> { v: () }; +LL + AliasFixed::<()>::SVariant { v: () }; + | + +error[E0109]: type arguments are not allowed on unit variant `UVariant` + --> $DIR/enum-variant-generic-args.rs:90:28 + | +LL | Enum::<()>::UVariant::<()>; + | -------- ^^ type argument not allowed + | | + | not allowed on unit variant `UVariant` + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:93:23 + | +LL | Alias::UVariant::<()>; + | -------- ^^ type argument not allowed + | | + | not allowed on this type + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:95:29 + | +LL | Alias::<()>::UVariant::<()>; + | -------- ^^ type argument not allowed + | | + | not allowed on this type + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:98:28 + | +LL | AliasFixed::UVariant::<()>; + | -------- ^^ type argument not allowed + | | + | not allowed on this type + +error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/enum-variant-generic-args.rs:100:5 + | +LL | AliasFixed::<()>::UVariant; + | ^^^^^^^^^^------ help: remove these generics + | | + | expected 0 generic arguments + | +note: type alias defined here, with 0 generic parameters + --> $DIR/enum-variant-generic-args.rs:9:6 + | +LL | type AliasFixed = Enum<()>; + | ^^^^^^^^^^ + +error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/enum-variant-generic-args.rs:102:5 + | +LL | AliasFixed::<()>::UVariant::<()>; + | ^^^^^^^^^^------ help: remove these generics + | | + | expected 0 generic arguments + | +note: type alias defined here, with 0 generic parameters + --> $DIR/enum-variant-generic-args.rs:9:6 + | +LL | type AliasFixed = Enum<()>; + | ^^^^^^^^^^ + +error[E0109]: type arguments are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:102:34 + | +LL | AliasFixed::<()>::UVariant::<()>; + | -------- ^^ type argument not allowed + | | + | not allowed on this type + +error: aborting due to 39 previous errors + +Some errors have detailed explanations: E0107, E0109, E0308. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs new file mode 100644 index 000000000..3a8712f2a --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs @@ -0,0 +1,23 @@ +// Check that an `enum` variant is resolved, in the value namespace, +// with higher priority than other inherent items when there is a conflict. + +enum E { + V(u8) +} + +impl E { + fn V() {} +} + +enum E2 { + V, +} + +impl E2 { + const V: u8 = 0; +} + +fn main() { + <E>::V(); //~ ERROR this enum variant takes 1 argument but 0 arguments were supplied + let _: u8 = <E2>::V; //~ ERROR mismatched types +} diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr new file mode 100644 index 000000000..006253f84 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr @@ -0,0 +1,28 @@ +error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied + --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:21:5 + | +LL | <E>::V(); + | ^^^^^^-- an argument of type `u8` is missing + | +note: tuple variant defined here + --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:5:5 + | +LL | V(u8) + | ^ +help: provide the argument + | +LL | <E>::V(/* u8 */); + | ~~~~~~~~~~~~~~~~ + +error[E0308]: mismatched types + --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:22:17 + | +LL | let _: u8 = <E2>::V; + | -- ^^^^^^^ expected `u8`, found enum `E2` + | | + | expected due to this + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0061, E0308. +For more information about an error, try `rustc --explain E0061`. diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs new file mode 100644 index 000000000..acbf15dcb --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs @@ -0,0 +1,41 @@ +// Check that a projection `Self::V` in a trait implementation, +// with an associated type named `V`, for an `enum` with a variant named `V`, +// results in triggering the deny-by-default lint `ambiguous_associated_items`. +// The lint suggests that qualified syntax should be used instead. +// That is, the user would write `<Self as Tr>::V`. +// +// The rationale for this is that while `enum` variants do currently +// not exist in the type namespace but solely in the value namespace, +// RFC #2593 "Enum variant types", would add enum variants to the type namespace. +// However, currently `enum` variants are resolved with high priority as +// they are resolved as inherent associated items. +// Should #2953 therefore be implemented, `Self::V` would suddenly switch +// from referring to the associated type `V` instead of the variant `V`. +// The lint exists to keep us forward compatible with #2593. +// +// As a closing note, provided that #2933 was implemented and +// if `enum` variants were given lower priority than associated types, +// it would be impossible to refer to the `enum` variant `V` whereas +// the associated type could be referred to with qualified syntax as seen above. + +enum E { + V +} + +trait Tr { + type V; + fn f() -> Self::V; +} + +impl Tr for E { + type V = u8; + fn f() -> Self::V { 0 } + //~^ ERROR ambiguous associated item + //~| ERROR ambiguous associated item + //~| WARN this was previously accepted + //~| WARN this was previously accepted + //~| HELP use fully-qualified syntax + //~| HELP use fully-qualified syntax +} + +fn main() {} 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 new file mode 100644 index 000000000..aaa3159e0 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr @@ -0,0 +1,41 @@ +error: ambiguous associated item + --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:32:15 + | +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 + --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:22:5 + | +LL | V + | ^ +note: `V` could also refer to the associated type defined here + --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:26:5 + | +LL | type V; + | ^^^^^^ + +error: ambiguous associated item + --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:32:15 + | +LL | fn f() -> Self::V { 0 } + | ^^^^^^^ help: use fully-qualified syntax: `<E as Tr>::V` + | + = 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 + --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:22:5 + | +LL | V + | ^ +note: `V` could also refer to the associated type defined here + --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:26:5 + | +LL | type V; + | ^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs new file mode 100644 index 000000000..ab40bf580 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs @@ -0,0 +1,14 @@ +pub enum Enum { + A(usize), +} + +impl Enum { + fn foo(&self) -> () { + match self { + Self::A => (), + //~^ ERROR expected unit struct, unit variant or constant, found tuple variant + } + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr new file mode 100644 index 000000000..15d15f2f4 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr @@ -0,0 +1,9 @@ +error[E0533]: expected unit struct, unit variant or constant, found tuple variant `Self::A` + --> $DIR/incorrect-variant-form-through-Self-issue-58006.rs:8:13 + | +LL | Self::A => (), + | ^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0533`. diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs new file mode 100644 index 000000000..e4abb96b4 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs @@ -0,0 +1,19 @@ +// Check that creating/matching on an enum variant through an alias with +// the wrong braced/unit form is caught as an error. + +enum Enum { Braced {}, Unit, Tuple() } +type Alias = Enum; + +fn main() { + Alias::Braced; + //~^ ERROR expected unit struct, unit variant or constant, found struct variant `Alias::Braced` [E0533] + let Alias::Braced = panic!(); + //~^ ERROR expected unit struct, unit variant or constant, found struct variant `Alias::Braced` [E0533] + let Alias::Braced(..) = panic!(); + //~^ ERROR expected tuple struct or tuple variant, found struct variant `Alias::Braced` [E0164] + + Alias::Unit(); + //~^ ERROR expected function, found enum variant `Alias::Unit` + let Alias::Unit() = panic!(); + //~^ ERROR expected tuple struct or tuple variant, found unit variant `Alias::Unit` [E0164] +} diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr new file mode 100644 index 000000000..8f3180a86 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr @@ -0,0 +1,45 @@ +error[E0533]: expected unit struct, unit variant or constant, found struct variant `Alias::Braced` + --> $DIR/incorrect-variant-form-through-alias-caught.rs:8:5 + | +LL | Alias::Braced; + | ^^^^^^^^^^^^^ + +error[E0533]: expected unit struct, unit variant or constant, found struct variant `Alias::Braced` + --> $DIR/incorrect-variant-form-through-alias-caught.rs:10:9 + | +LL | let Alias::Braced = panic!(); + | ^^^^^^^^^^^^^ + +error[E0164]: expected tuple struct or tuple variant, found struct variant `Alias::Braced` + --> $DIR/incorrect-variant-form-through-alias-caught.rs:12:9 + | +LL | let Alias::Braced(..) = panic!(); + | ^^^^^^^^^^^^^^^^^ not a tuple variant or struct + +error[E0618]: expected function, found enum variant `Alias::Unit` + --> $DIR/incorrect-variant-form-through-alias-caught.rs:15:5 + | +LL | enum Enum { Braced {}, Unit, Tuple() } + | ---- enum variant `Alias::Unit` defined here +... +LL | Alias::Unit(); + | ^^^^^^^^^^^-- + | | + | call expression requires function + | +help: `Alias::Unit` is a unit enum variant, and does not take parentheses to be constructed + | +LL - Alias::Unit(); +LL + Alias::Unit; + | + +error[E0164]: expected tuple struct or tuple variant, found unit variant `Alias::Unit` + --> $DIR/incorrect-variant-form-through-alias-caught.rs:17:9 + | +LL | let Alias::Unit() = panic!(); + | ^^^^^^^^^^^^^ not a tuple variant or struct + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0164, E0533, E0618. +For more information about an error, try `rustc --explain E0164`. diff --git a/src/test/ui/type-alias-enum-variants/issue-57866.rs b/src/test/ui/type-alias-enum-variants/issue-57866.rs new file mode 100644 index 000000000..5e105b20a --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/issue-57866.rs @@ -0,0 +1,24 @@ +// check-pass + +enum Outer<T> { + A(T) +} + +enum Inner { + A(i32) +} + +type OuterAlias = Outer<Inner>; + +fn ice(x: OuterAlias) { + // Fine + match x { + OuterAlias::A(Inner::A(_)) => (), + } + // Not fine + match x { + OuterAlias::A(Inner::A(y)) => (), + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs b/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs new file mode 100644 index 000000000..9c9eaab8d --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs @@ -0,0 +1,28 @@ +// In this regression test we check that a path pattern referring to a unit variant +// through a type alias is successful in inferring the generic argument. + +// check-pass + +enum Opt<T> { + N, + S(T), +} + +type OptAlias<T> = Opt<T>; + +fn f1(x: OptAlias<u8>) { + match x { + OptAlias::N // We previously failed to infer `T` to `u8`. + => (), + _ => (), + } + + match x { + < + OptAlias<_> // And we failed to infer this type also. + >::N => (), + _ => (), + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs b/src/test/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs new file mode 100644 index 000000000..66fb8dd0d --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs @@ -0,0 +1,26 @@ +// check-pass + +// Regression test for the issue #63151: +// Spurious unused field warning when matching variants under a `Self` scope +// +// This test checks that the `dead_code` lint properly inspects fields +// in struct patterns that use a type relative path. + +#![deny(dead_code)] + +enum Enum { + Variant { field: usize } +} + +impl Enum { + fn read_field(self) -> usize { + match self { + Self::Variant { field } => field + } + } +} + +fn main() { + let e = Enum::Variant { field: 42 }; + println!("{}", e.read_field()); +} diff --git a/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs new file mode 100644 index 000000000..872ece0c0 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs @@ -0,0 +1,14 @@ +// Check that a generic type for an `enum` admits type application +// on both the type constructor and the generic type's variant. +// +// Also check that a type alias to said generic type admits type application +// on the type constructor but *NOT* the variant. + +type Alias<T> = Option<T>; + +fn main() { + let _ = Option::<u8>::None; // OK + let _ = Option::None::<u8>; // OK (Lint in future!) + let _ = Alias::<u8>::None; // OK + let _ = Alias::None::<u8>; //~ ERROR type arguments are not allowed on this type +} diff --git a/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr new file mode 100644 index 000000000..51b1c8a10 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.stderr @@ -0,0 +1,11 @@ +error[E0109]: type arguments are not allowed on this type + --> $DIR/no-type-application-on-aliased-enum-variant.rs:13:27 + | +LL | let _ = Alias::None::<u8>; + | ---- ^^ type argument not allowed + | | + | not allowed on this type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0109`. diff --git a/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs new file mode 100644 index 000000000..11f4b05d0 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs @@ -0,0 +1,11 @@ +// Check that the compiler will resolve `<E>::V` to the variant `V` in the type namespace +// but will reject this because `enum` variants do not exist in the type namespace. + +enum E { + V +} + +fn check() -> <E>::V {} +//~^ ERROR expected type, found variant `V` + +fn main() {} diff --git a/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.stderr b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.stderr new file mode 100644 index 000000000..f190bfb69 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.stderr @@ -0,0 +1,8 @@ +error: expected type, found variant `V` + --> $DIR/resolve-to-enum-variant-in-type-namespace-and-error.rs:8:15 + | +LL | fn check() -> <E>::V {} + | ^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-enum-variants/self-in-enum-definition.rs b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.rs new file mode 100644 index 000000000..8dadd77fc --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.rs @@ -0,0 +1,8 @@ +#[repr(u8)] +enum Alpha { + V1 = 41, + V2 = Self::V1 as u8 + 1, // OK; See #50072. + V3 = Self::V1 {} as u8 + 2, //~ ERROR cycle detected when simplifying constant +} + +fn main() {} diff --git a/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr new file mode 100644 index 000000000..4775e6882 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr @@ -0,0 +1,33 @@ +error[E0391]: cycle detected when simplifying constant for the type system `Alpha::V3::{constant#0}` + --> $DIR/self-in-enum-definition.rs:5:10 + | +LL | V3 = Self::V1 {} as u8 + 2, + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires simplifying constant for the type system `Alpha::V3::{constant#0}`... + --> $DIR/self-in-enum-definition.rs:5:10 + | +LL | V3 = Self::V1 {} as u8 + 2, + | ^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating + checking `Alpha::V3::{constant#0}`... + --> $DIR/self-in-enum-definition.rs:5:10 + | +LL | V3 = Self::V1 {} as u8 + 2, + | ^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires computing layout of `Alpha`... + = note: ...which again requires simplifying constant for the type system `Alpha::V3::{constant#0}`, completing the cycle +note: cycle used when collecting item types in top-level module + --> $DIR/self-in-enum-definition.rs:1:1 + | +LL | / #[repr(u8)] +LL | | enum Alpha { +LL | | V1 = 41, +LL | | V2 = Self::V1 as u8 + 1, // OK; See #50072. +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs b/src/test/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs new file mode 100644 index 000000000..39677733d --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs @@ -0,0 +1,69 @@ +// run-pass + +// Check that it is possible to resolve, in the value namespace, +// to an `enum` variant through a type alias. This includes `Self`. +// Type qualified syntax `<Type>::Variant` also works when syntactically valid. + +#[derive(Debug, PartialEq, Eq)] +enum Foo { + Bar(i32), + Baz { i: i32 }, + Qux, +} + +type FooAlias = Foo; +type OptionAlias = Option<i32>; + +macro_rules! check_pat { + ($x:expr, $p:pat) => { + assert!(if let $p = $x { true } else { false }); + }; +} + +impl Foo { + fn bar() -> Self { + let x = Self::Bar(3); + assert_eq!(x, <Self>::Bar(3)); + check_pat!(x, Self::Bar(3)); + x + } + + fn baz() -> Self { + let x = Self::Baz { i: 42 }; + check_pat!(x, Self::Baz { i: 42 }); + x + } + + fn qux() -> Self { + let x = Self::Qux; + assert_eq!(x, <Self>::Qux); + check_pat!(x, Self::Qux); + check_pat!(x, <Self>::Qux); + x + } +} + +fn main() { + let bar = Foo::Bar(1); + assert_eq!(bar, FooAlias::Bar(1)); + assert_eq!(bar, <FooAlias>::Bar(1)); + check_pat!(bar, FooAlias::Bar(1)); + + let baz = FooAlias::Baz { i: 2 }; + assert_eq!(baz, Foo::Baz { i: 2 }); + check_pat!(baz, FooAlias::Baz { i: 2 }); + + let qux = Foo::Qux; + assert_eq!(qux, FooAlias::Qux); + assert_eq!(qux, <FooAlias>::Qux); + check_pat!(qux, FooAlias::Qux); + check_pat!(qux, <FooAlias>::Qux); + + assert_eq!(Foo::bar(), Foo::Bar(3)); + assert_eq!(Foo::baz(), Foo::Baz { i: 42 }); + assert_eq!(Foo::qux(), Foo::Qux); + + let some = Option::Some(4); + assert_eq!(some, OptionAlias::Some(4)); + check_pat!(some, OptionAlias::Some(4)); +} diff --git a/src/test/ui/type-alias-impl-trait/argument-types.rs b/src/test/ui/type-alias-impl-trait/argument-types.rs new file mode 100644 index 000000000..185207b98 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/argument-types.rs @@ -0,0 +1,26 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] +// check-pass +use std::fmt::Debug; + +type Foo = impl Debug; + +fn foo1(mut x: Foo) { + x = 22_u32; +} + +fn foo2(mut x: Foo) { + // no constraint on x +} + +fn foo3(x: Foo) { + println!("{:?}", x); +} + +fn foo_value() -> Foo { + 11_u32 +} + +fn main() { + foo3(foo_value()); +} diff --git a/src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs b/src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs new file mode 100644 index 000000000..703e3e869 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs @@ -0,0 +1,24 @@ +#![feature(type_alias_impl_trait)] + +// build-pass + +trait T { type Item; } + +type Alias<'a> = impl T<Item = &'a ()>; + +struct S; +impl<'a> T for &'a S { + type Item = &'a (); +} + +fn filter_positive<'a>() -> Alias<'a> { + &S +} + +fn with_positive(fun: impl Fn(Alias<'_>)) { + fun(filter_positive()); +} + +fn main() { + with_positive(|_| ()); +} diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-const.rs b/src/test/ui/type-alias-impl-trait/assoc-type-const.rs new file mode 100644 index 000000000..0ade36daf --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/assoc-type-const.rs @@ -0,0 +1,32 @@ +// Tests that we properly detect defining usages when using +// const generics in an associated opaque type +// check-pass + +#![feature(type_alias_impl_trait)] + +trait UnwrapItemsExt<'a, const C: usize> { + type Iter; + fn unwrap_items(self) -> Self::Iter; +} + +struct MyStruct<const C: usize> {} + +trait MyTrait<'a, const C: usize> { + type MyItem; + const MY_CONST: usize; +} + +impl<'a, const C: usize> MyTrait<'a, C> for MyStruct<C> { + type MyItem = u8; + const MY_CONST: usize = C; +} + +impl<'a, I, const C: usize> UnwrapItemsExt<'a, C> for I { + type Iter = impl MyTrait<'a, C>; + + fn unwrap_items(self) -> Self::Iter { + MyStruct::<C> {} + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs new file mode 100644 index 000000000..3f34b00ec --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs @@ -0,0 +1,26 @@ +// Tests that we don't allow unconstrained lifetime parameters in impls when +// the lifetime is used in an associated opaque type. + +#![feature(type_alias_impl_trait)] + +trait UnwrapItemsExt { + type Iter; + fn unwrap_items(self) -> Self::Iter; +} + +struct MyStruct {} + +trait MyTrait<'a> {} + +impl<'a> MyTrait<'a> for MyStruct {} + +impl<'a, I> UnwrapItemsExt for I { + //~^ ERROR the lifetime parameter `'a` is not constrained + type Iter = impl MyTrait<'a>; + + fn unwrap_items(self) -> Self::Iter { + MyStruct {} + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr new file mode 100644 index 000000000..e594dc577 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr @@ -0,0 +1,9 @@ +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/assoc-type-lifetime-unconstrained.rs:17:6 + | +LL | impl<'a, I> UnwrapItemsExt for I { + | ^^ unconstrained lifetime parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs new file mode 100644 index 000000000..39f785d8c --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs @@ -0,0 +1,26 @@ +// Tests that we still detect defining usages when +// lifetimes are used in an associated opaque type +// check-pass + +#![feature(type_alias_impl_trait)] + +trait UnwrapItemsExt<'a> { + type Iter; + fn unwrap_items(self) -> Self::Iter; +} + +struct MyStruct {} + +trait MyTrait<'a> {} + +impl<'a> MyTrait<'a> for MyStruct {} + +impl<'a, I> UnwrapItemsExt<'a> for I { + type Iter = impl MyTrait<'a>; + + fn unwrap_items(self) -> Self::Iter { + MyStruct {} + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs b/src/test/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs new file mode 100644 index 000000000..42f07d49f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs @@ -0,0 +1,26 @@ +#![feature(type_alias_impl_trait)] +// build-pass (FIXME(62277): could be check-pass?) + +trait Bar {} +struct Dummy; +impl Bar for Dummy {} + +trait Foo { + type Assoc: Bar; + fn foo() -> Self::Assoc; + fn bar() -> Self::Assoc; +} + +type Helper = impl Bar; + +impl Foo for i32 { + type Assoc = Helper; + fn foo() -> Helper { + Dummy + } + fn bar() -> Helper { + Dummy + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage.rs b/src/test/ui/type-alias-impl-trait/auto-trait-leakage.rs new file mode 100644 index 000000000..a1584581e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +mod m { + type Foo = impl std::fmt::Debug; + + pub fn foo() -> Foo { + 22_u32 + } +} + +fn is_send<T: Send>(_: T) {} + +fn main() { + is_send(m::foo()); +} diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs new file mode 100644 index 000000000..fc89b0e87 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs @@ -0,0 +1,25 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +mod m { + use std::rc::Rc; + + type Foo = impl std::fmt::Debug; //~ NOTE appears within the type + //~^ within this `Foo` + //~| expansion of desugaring + + pub fn foo() -> Foo { + Rc::new(22_u32) + } +} + +fn is_send<T: Send>(_: T) {} +//~^ required by this bound +//~| required by a bound + +fn main() { + is_send(m::foo()); + //~^ ERROR: `Rc<u32>` cannot be sent between threads safely [E0277] + //~| NOTE cannot be sent + //~| NOTE required by a bound +} diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr new file mode 100644 index 000000000..d7247302d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr @@ -0,0 +1,26 @@ +error[E0277]: `Rc<u32>` cannot be sent between threads safely + --> $DIR/auto-trait-leakage2.rs:21:13 + | +LL | type Foo = impl std::fmt::Debug; + | -------------------- within this `Foo` +... +LL | is_send(m::foo()); + | ------- ^^^^^^^^ `Rc<u32>` cannot be sent between threads safely + | | + | required by a bound introduced by this call + | + = help: within `Foo`, the trait `Send` is not implemented for `Rc<u32>` +note: required because it appears within the type `Foo` + --> $DIR/auto-trait-leakage2.rs:7:16 + | +LL | type Foo = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `is_send` + --> $DIR/auto-trait-leakage2.rs:16:15 + | +LL | fn is_send<T: Send>(_: T) {} + | ^^^^ required by this bound in `is_send` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs new file mode 100644 index 000000000..5fb7a9473 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs @@ -0,0 +1,21 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +// FIXME This should compile, but it currently doesn't + +mod m { + type Foo = impl std::fmt::Debug; + //~^ ERROR: cycle detected when computing type of `m::Foo::{opaque#0}` [E0391] + + pub fn foo() -> Foo { + 22_u32 + } + + pub fn bar() { + is_send(foo()); + } + + fn is_send<T: Send>(_: T) {} +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr new file mode 100644 index 000000000..1e9a45aac --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr @@ -0,0 +1,22 @@ +error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}` + --> $DIR/auto-trait-leakage3.rs:7:16 + | +LL | type Foo = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `m::bar`... + --> $DIR/auto-trait-leakage3.rs:15:9 + | +LL | is_send(foo()); + | ^^^^^^^ + = note: ...which requires evaluating trait selection obligation `m::Foo: core::marker::Send`... + = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle +note: cycle used when checking item types in module `m` + --> $DIR/auto-trait-leakage3.rs:6:1 + | +LL | mod m { + | ^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/type-alias-impl-trait/auxiliary/collect_hidden_types.rs b/src/test/ui/type-alias-impl-trait/auxiliary/collect_hidden_types.rs new file mode 100644 index 000000000..75d20a6fe --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auxiliary/collect_hidden_types.rs @@ -0,0 +1,21 @@ +#![feature(type_alias_impl_trait)] + +// edition:2018 + +use std::future::Future; + +pub trait Service<Request> { + type Future: Future<Output = ()>; + fn call(&mut self, req: Request) -> Self::Future; +} + +// NOTE: the pub(crate) here is critical +pub(crate) fn new() -> () {} + +pub struct A; +impl Service<()> for A { + type Future = impl Future<Output = ()>; + fn call(&mut self, _: ()) -> Self::Future { + async { new() } + } +} diff --git a/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs b/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs new file mode 100644 index 000000000..e7bca2231 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs @@ -0,0 +1,10 @@ +// Crate that exports an opaque `impl Trait` type. Used for testing cross-crate. + +#![crate_type = "rlib"] +#![feature(type_alias_impl_trait)] + +pub type Foo = impl std::fmt::Debug; + +pub fn foo() -> Foo { + 5 +} diff --git a/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs b/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs new file mode 100644 index 000000000..119f7df1f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs @@ -0,0 +1,20 @@ +// Crate that exports an opaque `impl Trait` type. Used for testing cross-crate. + +#![crate_type = "rlib"] +#![feature(type_alias_impl_trait)] + +pub trait View { + type Tmp: Iterator<Item = u32>; + + fn test(&self) -> Self::Tmp; +} + +pub struct X; + +impl View for X { + type Tmp = impl Iterator<Item = u32>; + + fn test(&self) -> Self::Tmp { + vec![1, 2, 3].into_iter() + } +} diff --git a/src/test/ui/type-alias-impl-trait/auxiliary/foreign-crate.rs b/src/test/ui/type-alias-impl-trait/auxiliary/foreign-crate.rs new file mode 100644 index 000000000..52802dd8f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auxiliary/foreign-crate.rs @@ -0,0 +1,2 @@ +pub trait ForeignTrait {} +pub struct ForeignType<T>(pub T); diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction.rs b/src/test/ui/type-alias-impl-trait/bound_reduction.rs new file mode 100644 index 000000000..b9b50f0b7 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/bound_reduction.rs @@ -0,0 +1,19 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![allow(warnings)] +#![feature(type_alias_impl_trait)] + +fn main() { +} + +type Foo<V> = impl std::fmt::Debug; + +trait Trait<U> {} + +fn foo_desugared<T: Trait<[u32; { + #[no_mangle] + static FOO: usize = 42; + 3 +}]>>(_: T) -> Foo<T> { + (42, std::marker::PhantomData::<T>) +} diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs new file mode 100644 index 000000000..4d2890b5d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs @@ -0,0 +1,18 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +trait TraitWithAssoc { + type Assoc; +} + +type Foo<V> = impl Trait<V>; + +trait Trait<U> {} + +impl<W> Trait<W> for () {} + +fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> { + () + //~^ ERROR non-defining opaque type use +} diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr new file mode 100644 index 000000000..c405b1f6a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr @@ -0,0 +1,14 @@ +error: non-defining opaque type use in defining scope + --> $DIR/bound_reduction2.rs:16:5 + | +LL | () + | ^^ + | +note: used non-generic type `<T as TraitWithAssoc>::Assoc` for generic parameter + --> $DIR/bound_reduction2.rs:9:10 + | +LL | type Foo<V> = impl Trait<V>; + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.rs b/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.rs new file mode 100644 index 000000000..55b4dc8dc --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.rs @@ -0,0 +1,19 @@ +// Make sure that we check that impl trait types implement the traits that they +// claim to. + +#![feature(type_alias_impl_trait)] + +type X<T> = impl Clone; + +fn f<T: Clone>(t: T) -> X<T> { + t + //~^ ERROR the trait bound `T: Clone` is not satisfied +} + +fn g<T>(o: Option<X<T>>) -> Option<X<T>> { + o.clone() +} + +fn main() { + g(None::<X<&mut ()>>); +} diff --git a/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.stderr b/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.stderr new file mode 100644 index 000000000..8678e9b33 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.stderr @@ -0,0 +1,14 @@ +error[E0277]: the trait bound `T: Clone` is not satisfied + --> $DIR/bounds-are-checked-2.rs:9:5 + | +LL | t + | ^ the trait `Clone` is not implemented for `T` + | +help: consider restricting type parameter `T` + | +LL | type X<T: std::clone::Clone> = impl Clone; + | +++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/bounds-are-checked.rs b/src/test/ui/type-alias-impl-trait/bounds-are-checked.rs new file mode 100644 index 000000000..83d22161e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/bounds-are-checked.rs @@ -0,0 +1,24 @@ +// Make sure that we check that impl trait types implement the traits that they +// claim to. + +#![feature(type_alias_impl_trait)] + +type X<'a> = impl Into<&'static str> + From<&'a str>; + +fn f<'a: 'static>(t: &'a str) -> X<'a> { + //~^ WARNING unnecessary lifetime parameter + t + //~^ ERROR non-defining opaque type use +} + +fn extend_lt<'a>(o: &'a str) -> &'static str { + X::<'_>::from(o).into() +} + +fn main() { + let r = { + let s = "abcdef".to_string(); + extend_lt(&s) + }; + println!("{}", r); +} diff --git a/src/test/ui/type-alias-impl-trait/bounds-are-checked.stderr b/src/test/ui/type-alias-impl-trait/bounds-are-checked.stderr new file mode 100644 index 000000000..920eef11d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/bounds-are-checked.stderr @@ -0,0 +1,19 @@ +warning: unnecessary lifetime parameter `'a` + --> $DIR/bounds-are-checked.rs:8:6 + | +LL | fn f<'a: 'static>(t: &'a str) -> X<'a> { + | ^^ + | + = help: you can use the `'static` lifetime directly, in place of `'a` + +error: non-defining opaque type use in defining scope + --> $DIR/bounds-are-checked.rs:10:5 + | +LL | type X<'a> = impl Into<&'static str> + From<&'a str>; + | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type +... +LL | t + | ^ + +error: aborting due to previous error; 1 warning emitted + diff --git a/src/test/ui/type-alias-impl-trait/closures_in_branches.rs b/src/test/ui/type-alias-impl-trait/closures_in_branches.rs new file mode 100644 index 000000000..7bb490bbe --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/closures_in_branches.rs @@ -0,0 +1,31 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl std::ops::FnOnce(String) -> usize; + +fn foo(b: bool) -> Foo { + if b { + |x| x.len() //~ ERROR type annotations needed + } else { + panic!() + } +} + + +type Foo1 = impl std::ops::FnOnce(String) -> usize; +fn foo1(b: bool) -> Foo1 { + |x| x.len() +} + +fn bar(b: bool) -> impl std::ops::FnOnce(String) -> usize { + if b { + |x| x.len() //~ ERROR type annotations needed + } else { + panic!() + } +} + +fn bar1(b: bool) -> impl std::ops::FnOnce(String) -> usize { + |x| x.len() +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr b/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr new file mode 100644 index 000000000..48b7946ea --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr @@ -0,0 +1,25 @@ +error[E0282]: type annotations needed + --> $DIR/closures_in_branches.rs:7:10 + | +LL | |x| x.len() + | ^ - type must be known at this point + | +help: consider giving this closure parameter an explicit type + | +LL | |x: _| x.len() + | +++ + +error[E0282]: type annotations needed + --> $DIR/closures_in_branches.rs:21:10 + | +LL | |x| x.len() + | ^ - type must be known at this point + | +help: consider giving this closure parameter an explicit type + | +LL | |x: _| x.len() + | +++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-alias-impl-trait/coherence.rs b/src/test/ui/type-alias-impl-trait/coherence.rs new file mode 100644 index 000000000..98ac215ad --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/coherence.rs @@ -0,0 +1,17 @@ +// aux-build:foreign-crate.rs +#![feature(type_alias_impl_trait)] + +extern crate foreign_crate; + +trait LocalTrait {} +impl<T> LocalTrait for foreign_crate::ForeignType<T> {} + +type AliasOfForeignType<T> = impl LocalTrait; +fn use_alias<T>(val: T) -> AliasOfForeignType<T> { + foreign_crate::ForeignType(val) +} + +impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {} +//~^ ERROR cannot implement trait on type alias impl trait + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/coherence.stderr b/src/test/ui/type-alias-impl-trait/coherence.stderr new file mode 100644 index 000000000..3ce25d94f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/coherence.stderr @@ -0,0 +1,14 @@ +error: cannot implement trait on type alias impl trait + --> $DIR/coherence.rs:14:41 + | +LL | impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {} + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: type alias impl trait defined here + --> $DIR/coherence.rs:9:30 + | +LL | type AliasOfForeignType<T> = impl LocalTrait; + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/collect_hidden_types.rs b/src/test/ui/type-alias-impl-trait/collect_hidden_types.rs new file mode 100644 index 000000000..e78f178e4 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/collect_hidden_types.rs @@ -0,0 +1,22 @@ +// aux-build:collect_hidden_types.rs +use collect_hidden_types::Service; +use std::future::Future; +use std::pin::Pin; +use std::task::Context; + +// build-pass + +// edition:2018 + +extern crate collect_hidden_types; + +fn broken(mut a: collect_hidden_types::A, cx: &mut Context<'_>) { + let mut fut = a.call(()); + let _ = unsafe { Pin::new_unchecked(&mut fut) }.poll(cx); +} + +pub async fn meeb(cx: &mut Context<'_>) { + broken(collect_hidden_types::A, cx); +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/constrain_inputs.rs b/src/test/ui/type-alias-impl-trait/constrain_inputs.rs new file mode 100644 index 000000000..c32174288 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/constrain_inputs.rs @@ -0,0 +1,17 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +mod foo { + type Ty<'a> = impl Sized; + fn defining(s: &str) -> Ty<'_> { s } + fn execute(ty: Ty<'_>) -> &str { todo!() } +} + +mod bar { + type Ty<'a> = impl FnOnce() -> &'a str; + fn defining(s: &str) -> Ty<'_> { move || s } + fn execute(ty: Ty<'_>) -> &str { ty() } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/cross_crate_ice.rs b/src/test/ui/type-alias-impl-trait/cross_crate_ice.rs new file mode 100644 index 000000000..c30608176 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/cross_crate_ice.rs @@ -0,0 +1,16 @@ +// aux-build:cross_crate_ice.rs +// build-pass (FIXME(62277): could be check-pass?) + +extern crate cross_crate_ice; + +struct Bar(cross_crate_ice::Foo); + +impl Bar { + fn zero(&self) -> &cross_crate_ice::Foo { + &self.0 + } +} + +fn main() { + let _ = cross_crate_ice::foo(); +} diff --git a/src/test/ui/type-alias-impl-trait/cross_crate_ice2.rs b/src/test/ui/type-alias-impl-trait/cross_crate_ice2.rs new file mode 100644 index 000000000..3a7e49026 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/cross_crate_ice2.rs @@ -0,0 +1,11 @@ +// aux-build:cross_crate_ice2.rs +// build-pass (FIXME(62277): could be check-pass?) + +extern crate cross_crate_ice2; + +use cross_crate_ice2::View; + +fn main() { + let v = cross_crate_ice2::X; + v.test(); +} diff --git a/src/test/ui/type-alias-impl-trait/cross_inference.rs b/src/test/ui/type-alias-impl-trait/cross_inference.rs new file mode 100644 index 000000000..dafaf40a6 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/cross_inference.rs @@ -0,0 +1,10 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +fn main() { + type T = impl Copy; + let foo: T = (1u32, 2u32); + let x: (_, _) = foo; + println!("{:?}", x); +} 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 new file mode 100644 index 000000000..811832848 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs @@ -0,0 +1,8 @@ +// compile-flags: --edition=2021 +#![feature(type_alias_impl_trait)] + +fn main() { + type T = impl Copy; //~ ERROR unconstrained opaque type + 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 new file mode 100644 index 000000000..03b172e6d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.stderr @@ -0,0 +1,10 @@ +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 new file mode 100644 index 000000000..328096d44 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs @@ -0,0 +1,13 @@ +// known-bug: #96572 +// compile-flags: --edition=2021 --crate-type=lib +// rustc-env:RUST_BACKTRACE=0 + +// 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 + let foo: T = (1u32, 2u32); + let (a, b) = foo; // removing this line makes the code compile +} 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 new file mode 100644 index 000000000..8aa1f4956 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.stderr @@ -0,0 +1,10 @@ +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/cross_inference_rpit.rs b/src/test/ui/type-alias-impl-trait/cross_inference_rpit.rs new file mode 100644 index 000000000..f6affbf17 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/cross_inference_rpit.rs @@ -0,0 +1,14 @@ +// check-pass + +fn foo(b: bool) -> impl Copy { + if b { + return (5,6) + } + let x: (_, _) = foo(true); + println!("{:?}", x); + (1u32, 2u32) +} + +fn main() { + foo(false); +} diff --git a/src/test/ui/type-alias-impl-trait/declared_but_never_defined.rs b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.rs new file mode 100644 index 000000000..6febd0715 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.rs @@ -0,0 +1,6 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +// declared but never defined +type Bar = impl std::fmt::Debug; //~ ERROR unconstrained opaque type diff --git a/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr new file mode 100644 index 000000000..60bc24320 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr @@ -0,0 +1,10 @@ +error: unconstrained opaque type + --> $DIR/declared_but_never_defined.rs:6:12 + | +LL | type Bar = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `Bar` 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/declared_but_not_defined_in_scope.rs b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs new file mode 100644 index 000000000..5bda5f0fc --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs @@ -0,0 +1,13 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +mod boo { + // declared in module but not defined inside of it + pub type Boo = impl ::std::fmt::Debug; //~ ERROR unconstrained opaque type +} + +fn bomp() -> boo::Boo { + "" + //~^ mismatched types +} diff --git a/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr new file mode 100644 index 000000000..fbfa0ccf1 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr @@ -0,0 +1,25 @@ +error: unconstrained opaque type + --> $DIR/declared_but_not_defined_in_scope.rs:7:20 + | +LL | pub type Boo = impl ::std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Boo` must be used in combination with a concrete type within the same module + +error[E0308]: mismatched types + --> $DIR/declared_but_not_defined_in_scope.rs:11:5 + | +LL | pub type Boo = impl ::std::fmt::Debug; + | ---------------------- the expected opaque type +... +LL | fn bomp() -> boo::Boo { + | -------- expected `Boo` because of return type +LL | "" + | ^^ expected opaque type, found `&str` + | + = note: expected opaque type `Boo` + found reference `&'static str` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/defining-use-submodule.rs b/src/test/ui/type-alias-impl-trait/defining-use-submodule.rs new file mode 100644 index 000000000..8b51f5571 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/defining-use-submodule.rs @@ -0,0 +1,23 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +// test that the type alias impl trait defining use is in a submodule + +fn main() {} + +type Foo = impl std::fmt::Display; +type Bar = impl std::fmt::Display; + +mod foo { + pub fn foo() -> super::Foo { + "foo" + } + + pub mod bar { + pub fn bar() -> crate::Bar { + 1 + } + } +} diff --git a/src/test/ui/type-alias-impl-trait/different_defining_uses.rs b/src/test/ui/type-alias-impl-trait/different_defining_uses.rs new file mode 100644 index 000000000..4505c4d95 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses.rs @@ -0,0 +1,15 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +// two definitions with different types +type Foo = impl std::fmt::Debug; + +fn foo() -> Foo { + "" +} + +fn bar() -> Foo { + 42i32 + //~^ ERROR concrete type differs from previous +} diff --git a/src/test/ui/type-alias-impl-trait/different_defining_uses.stderr b/src/test/ui/type-alias-impl-trait/different_defining_uses.stderr new file mode 100644 index 000000000..a8b4cd7af --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses.stderr @@ -0,0 +1,14 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/different_defining_uses.rs:13:5 + | +LL | 42i32 + | ^^^^^ expected `&'static str`, got `i32` + | +note: previous use here + --> $DIR/different_defining_uses.rs:9:5 + | +LL | "" + | ^^ + +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 new file mode 100644 index 000000000..7740f774e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs @@ -0,0 +1,18 @@ +#![feature(type_alias_impl_trait)] +// check-pass +fn main() {} + +// two definitions with different types +type Foo = impl std::fmt::Debug; + +fn foo() -> Foo { + "" +} + +fn bar() -> Foo { + panic!() +} + +fn boo() -> Foo { + loop {} +} diff --git a/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs new file mode 100644 index 000000000..8549687ea --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs @@ -0,0 +1,44 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(type_alias_impl_trait)] + +fn main() {} + +// two definitions with different types +type Foo = impl std::fmt::Debug; + +fn foo() -> Foo { + "" +} + +fn bar(arg: bool) -> Foo { + if arg { + panic!() + } else { + "bar" + } +} + +fn boo(arg: bool) -> Foo { + if arg { + loop {} + } else { + "boo" + } +} + +fn bar2(arg: bool) -> Foo { + if arg { + "bar2" + } else { + panic!() + } +} + +fn boo2(arg: bool) -> Foo { + if arg { + "boo2" + } else { + loop {} + } +} 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 new file mode 100644 index 000000000..4f424b8c6 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs @@ -0,0 +1,15 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +type OneLifetime<'a, 'b> = impl std::fmt::Debug; + +fn foo<'a, 'b>(a: &'a u32, b: &'b u32) -> OneLifetime<'a, 'b> { + a +} + +fn bar<'a, 'b>(a: &'a u32, b: &'b u32) -> OneLifetime<'a, 'b> { + b + //~^ ERROR: concrete type differs from previous defining opaque type use +} + +fn main() {} 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 new file mode 100644 index 000000000..0c50a84e8 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr @@ -0,0 +1,14 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/different_lifetimes_defining_uses.rs:11:5 + | +LL | b + | ^ expected `&'a u32`, got `&'b u32` + | +note: previous use here + --> $DIR/different_lifetimes_defining_uses.rs:7:5 + | +LL | a + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/fallback.rs b/src/test/ui/type-alias-impl-trait/fallback.rs new file mode 100644 index 000000000..d8cf7d71f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/fallback.rs @@ -0,0 +1,28 @@ +// Tests that we correctly handle opaque types being used opaquely, +// even within their defining scope. +// +#![feature(type_alias_impl_trait)] + +type Foo = impl Copy; + +enum Wrapper<T> { + First(T), + Second +} + +// This method constrains `Foo` to be `bool` +fn constrained_foo() -> Foo { + true +} + + +// This method does not constrain `Foo`. +// Per RFC 2071, function bodies may either +// fully constrain an opaque type, or place no +// constraints on it. +fn unconstrained_foo() -> Wrapper<Foo> { + Wrapper::Second + //~^ ERROR: type annotations needed +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/fallback.stderr b/src/test/ui/type-alias-impl-trait/fallback.stderr new file mode 100644 index 000000000..e767bfdb0 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/fallback.stderr @@ -0,0 +1,17 @@ +error[E0283]: type annotations needed + --> $DIR/fallback.rs:24:5 + | +LL | fn unconstrained_foo() -> Wrapper<Foo> { + | ------------ type must be known at this point +LL | Wrapper::Second + | ^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the enum `Wrapper` + | + = note: cannot satisfy `_: Copy` +help: consider specifying the generic argument + | +LL | Wrapper::<T>::Second + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/type-alias-impl-trait/field-types.rs b/src/test/ui/type-alias-impl-trait/field-types.rs new file mode 100644 index 000000000..d99ed5812 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/field-types.rs @@ -0,0 +1,18 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +// check-pass + +use std::fmt::Debug; + +type Foo = impl Debug; + +struct Bar { + foo: Foo, +} + +fn bar() -> Bar { + Bar { foo: "foo" } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/future.rs b/src/test/ui/type-alias-impl-trait/future.rs new file mode 100644 index 000000000..56323216e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/future.rs @@ -0,0 +1,22 @@ +#![feature(type_alias_impl_trait)] + +// edition:2021 +// compile-flags: --crate-type=lib + +use std::future::Future; + +trait Bar { + fn bar(&self); +} + +type FooFuture<B> = impl Future<Output = ()>; + +fn foo<B: Bar>(bar: B) -> FooFuture<B> { + async move { bar.bar() } + //~^ ERROR: the trait bound `B: Bar` is not satisfied +} + +pub fn mainish(ctx: &mut std::task::Context) { + let boom: FooFuture<u32> = unsafe { core::mem::zeroed() }; + Box::pin(boom).as_mut().poll(ctx); +} diff --git a/src/test/ui/type-alias-impl-trait/future.stderr b/src/test/ui/type-alias-impl-trait/future.stderr new file mode 100644 index 000000000..7e76c120a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/future.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `B: Bar` is not satisfied + --> $DIR/future.rs:15:5 + | +LL | async move { bar.bar() } + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `B` + | +note: required by a bound in `foo` + --> $DIR/future.rs:14:11 + | +LL | fn foo<B: Bar>(bar: B) -> FooFuture<B> { + | ^^^ required by this bound in `foo` +help: consider restricting type parameter `B` + | +LL | type FooFuture<B: Bar> = impl Future<Output = ()>; + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.rs b/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.rs new file mode 100644 index 000000000..8b683ad28 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.rs @@ -0,0 +1,14 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +type MyIter<T> = impl Iterator<Item = T>; + +fn my_iter<T>(t: T) -> MyIter<T> { + std::iter::once(t) +} + +fn my_iter2<T>(t: T) -> MyIter<T> { + Some(t).into_iter() + //~^ ERROR concrete type differs from previous +} diff --git a/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.stderr b/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.stderr new file mode 100644 index 000000000..47ac33462 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.stderr @@ -0,0 +1,14 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/generic_different_defining_uses.rs:12:5 + | +LL | Some(t).into_iter() + | ^^^^^^^^^^^^^^^^^^^ expected `std::iter::Once<T>`, got `std::option::IntoIter<T>` + | +note: previous use here + --> $DIR/generic_different_defining_uses.rs:8:5 + | +LL | std::iter::once(t) + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + 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 new file mode 100644 index 000000000..c9b9e128f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs @@ -0,0 +1,11 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +type Two<'a, 'b> = impl std::fmt::Debug; + + +fn one<'a>(t: &'a ()) -> Two<'a, 'a> { + t + //~^ ERROR non-defining opaque type use +} 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 new file mode 100644 index 000000000..222aaea78 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr @@ -0,0 +1,14 @@ +error: non-defining opaque type use in defining scope + --> $DIR/generic_duplicate_lifetime_param.rs:9:5 + | +LL | t + | ^ + | +note: lifetime used multiple times + --> $DIR/generic_duplicate_lifetime_param.rs:5:10 + | +LL | type Two<'a, 'b> = impl std::fmt::Debug; + | ^^ ^^ + +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 new file mode 100644 index 000000000..093c1c231 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs @@ -0,0 +1,28 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +// test that unused generic parameters are ok +type TwoTys<T, U> = impl Debug; + +type TwoLifetimes<'a, 'b> = impl Debug; + +type TwoConsts<const X: usize, const Y: usize> = impl Debug; + + +fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> { + t + //~^ ERROR non-defining opaque type use in defining scope +} + +fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> { + t + //~^ ERROR non-defining opaque type use in defining scope +} + +fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> { + t + //~^ ERROR non-defining opaque type use in defining scope +} 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 new file mode 100644 index 000000000..b2edcc552 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr @@ -0,0 +1,38 @@ +error: non-defining opaque type use in defining scope + --> $DIR/generic_duplicate_param_use.rs:16:5 + | +LL | t + | ^ + | +note: type used multiple times + --> $DIR/generic_duplicate_param_use.rs:8:13 + | +LL | type TwoTys<T, U> = impl Debug; + | ^ ^ + +error: non-defining opaque type use in defining scope + --> $DIR/generic_duplicate_param_use.rs:21:5 + | +LL | t + | ^ + | +note: lifetime used multiple times + --> $DIR/generic_duplicate_param_use.rs:10:19 + | +LL | type TwoLifetimes<'a, 'b> = impl Debug; + | ^^ ^^ + +error: non-defining opaque type use in defining scope + --> $DIR/generic_duplicate_param_use.rs:26:5 + | +LL | t + | ^ + | +note: constant used multiple times + --> $DIR/generic_duplicate_param_use.rs:12:16 + | +LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug; + | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs new file mode 100644 index 000000000..c17d595db --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs @@ -0,0 +1,12 @@ +// check-pass +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +type Two<T: Debug, U> = impl Debug; + +fn two<T: Debug, U: Debug>(t: T, _: U) -> Two<T, U> { + (t, 4u32) +} diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs new file mode 100644 index 000000000..201535efe --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs @@ -0,0 +1,13 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +// test that unused generic parameters are ok +type Two<T, U> = impl Debug; + +fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> { + t + //~^ ERROR `T` doesn't implement `Debug` +} diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr new file mode 100644 index 000000000..3dbfff745 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr @@ -0,0 +1,14 @@ +error[E0277]: `T` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use2.rs:11:5 + | +LL | t + | ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | +help: consider restricting type parameter `T` + | +LL | type Two<T: std::fmt::Debug, U> = impl Debug; + | +++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs new file mode 100644 index 000000000..e7a25fc72 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs @@ -0,0 +1,18 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +// test that unused generic parameters are ok +type Two<T, U> = impl Debug; + +fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> { + t + //~^ ERROR `T` doesn't implement `Debug` +} + +fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> { + u + //~^ ERROR `U` doesn't implement `Debug` +} diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr new file mode 100644 index 000000000..7bec38220 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr @@ -0,0 +1,25 @@ +error[E0277]: `T` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use3.rs:11:5 + | +LL | t + | ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | +help: consider restricting type parameter `T` + | +LL | type Two<T: std::fmt::Debug, U> = impl Debug; + | +++++++++++++++++ + +error[E0277]: `U` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use3.rs:16:5 + | +LL | u + | ^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | +help: consider restricting type parameter `U` + | +LL | type Two<T, U: std::fmt::Debug> = impl Debug; + | +++++++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs new file mode 100644 index 000000000..d1e5a0f01 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs @@ -0,0 +1,13 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +// test that unused generic parameters are ok +type Two<T, U> = impl Debug; + +fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> { + u + //~^ ERROR `U` doesn't implement `Debug` +} diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr new file mode 100644 index 000000000..21a5369d9 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr @@ -0,0 +1,14 @@ +error[E0277]: `U` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use4.rs:11:5 + | +LL | u + | ^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | +help: consider restricting type parameter `U` + | +LL | type Two<T, U: std::fmt::Debug> = impl Debug; + | +++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs new file mode 100644 index 000000000..3bd1dda63 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs @@ -0,0 +1,20 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +// test that unused generic parameters are ok +type Two<T, U> = impl Debug; + +fn two<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> { + (t, u) + //~^ ERROR `T` doesn't implement `Debug` + //~| ERROR `U` doesn't implement `Debug` +} + +fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> { + (u, t) + //~^ ERROR `T` doesn't implement `Debug` + //~| ERROR `U` doesn't implement `Debug` +} diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr new file mode 100644 index 000000000..2768f0c3a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr @@ -0,0 +1,51 @@ +error[E0277]: `T` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use5.rs:11:5 + | +LL | (t, u) + | ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(T, U)` +help: consider restricting type parameter `T` + | +LL | type Two<T: std::fmt::Debug, U> = impl Debug; + | +++++++++++++++++ + +error[E0277]: `U` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use5.rs:11:5 + | +LL | (t, u) + | ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(T, U)` +help: consider restricting type parameter `U` + | +LL | type Two<T, U: std::fmt::Debug> = impl Debug; + | +++++++++++++++++ + +error[E0277]: `U` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use5.rs:17:5 + | +LL | (u, t) + | ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(U, T)` +help: consider restricting type parameter `U` + | +LL | type Two<T, U: std::fmt::Debug> = impl Debug; + | +++++++++++++++++ + +error[E0277]: `T` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use5.rs:17:5 + | +LL | (u, t) + | ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(U, T)` +help: consider restricting type parameter `T` + | +LL | type Two<T: std::fmt::Debug, U> = impl Debug; + | +++++++++++++++++ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs new file mode 100644 index 000000000..5120925e5 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs @@ -0,0 +1,19 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +// test that unused generic parameters are ok +type Two<T, U> = impl Debug; + +fn two<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> { + (t, t) + //~^ ERROR `T` doesn't implement `Debug` +} + +fn three<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> { + (u, t) + //~^ ERROR `T` doesn't implement `Debug` + //~| ERROR `U` doesn't implement `Debug` +} diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr new file mode 100644 index 000000000..c1712ca2e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr @@ -0,0 +1,39 @@ +error[E0277]: `T` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use6.rs:11:5 + | +LL | (t, t) + | ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(T, T)` +help: consider restricting type parameter `T` + | +LL | type Two<T: std::fmt::Debug, U> = impl Debug; + | +++++++++++++++++ + +error[E0277]: `U` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use6.rs:16:5 + | +LL | (u, t) + | ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(U, T)` +help: consider restricting type parameter `U` + | +LL | type Two<T, U: std::fmt::Debug> = impl Debug; + | +++++++++++++++++ + +error[E0277]: `T` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use6.rs:16:5 + | +LL | (u, t) + | ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(U, T)` +help: consider restricting type parameter `T` + | +LL | type Two<T: std::fmt::Debug, U> = impl Debug; + | +++++++++++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs new file mode 100644 index 000000000..feebf81ee --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs @@ -0,0 +1,24 @@ +// check-pass +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +type Two<A: Debug, B> = impl Debug; + +fn two<T: Debug + Copy, U>(t: T, u: U) -> Two<T, U> { + (t, t) +} + +fn three<T: Debug, U>(t: T, t2: T, u: U) -> Two<T, U> { + (t, t2) +} + +fn four<T: Debug, U, V>(t: T, t2: T, u: U, v: V) -> Two<T, U> { + (t, t2) +} + +fn five<X, Y: Debug>(x: X, y: Y, y2: Y) -> Two<Y, X> { + (y, y2) +} diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs new file mode 100644 index 000000000..3a4b5047b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs @@ -0,0 +1,17 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +type Two<T, U> = impl Debug; + +fn two<T: Debug, U: Debug>(t: T, _: U) -> Two<T, U> { + (t, 4u32) + //~^ ERROR `T` doesn't implement `Debug` +} + +fn three<T: Debug, U: Debug>(_: T, u: U) -> Two<T, U> { + (u, 4u32) + //~^ ERROR `U` doesn't implement `Debug` +} diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr new file mode 100644 index 000000000..b83105c45 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr @@ -0,0 +1,27 @@ +error[E0277]: `T` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use8.rs:10:5 + | +LL | (t, 4u32) + | ^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(T, u32)` +help: consider restricting type parameter `T` + | +LL | type Two<T: std::fmt::Debug, U> = impl Debug; + | +++++++++++++++++ + +error[E0277]: `U` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use8.rs:15:5 + | +LL | (u, 4u32) + | ^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(U, u32)` +help: consider restricting type parameter `U` + | +LL | type Two<T, U: std::fmt::Debug> = impl Debug; + | +++++++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs new file mode 100644 index 000000000..6afcdfe4d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs @@ -0,0 +1,25 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +type Two<A, B> = impl Debug; + +trait Foo { + type Bar: Debug; + const BAR: Self::Bar; +} + +fn two<T: Debug + Foo, U: Debug>(t: T, u: U) -> Two<T, U> { + (t, u, T::BAR) + //~^ ERROR the trait bound `A: Foo` is not satisfied + //~| ERROR `A` doesn't implement `Debug` + //~| ERROR `B` doesn't implement `Debug` +} + +fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> { + (t, u, 42) + //~^ ERROR `A` doesn't implement `Debug` + //~| ERROR `B` doesn't implement `Debug` +} diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr new file mode 100644 index 000000000..50cf98273 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr @@ -0,0 +1,62 @@ +error[E0277]: the trait bound `A: Foo` is not satisfied + --> $DIR/generic_duplicate_param_use9.rs:15:5 + | +LL | (t, u, T::BAR) + | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A` + | +help: consider restricting type parameter `A` + | +LL | type Two<A: Foo, B> = impl Debug; + | +++++ + +error[E0277]: `A` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use9.rs:15:5 + | +LL | (t, u, T::BAR) + | ^^^^^^^^^^^^^^ `A` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(A, B, _)` +help: consider restricting type parameter `A` + | +LL | type Two<A: std::fmt::Debug, B> = impl Debug; + | +++++++++++++++++ + +error[E0277]: `B` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use9.rs:15:5 + | +LL | (t, u, T::BAR) + | ^^^^^^^^^^^^^^ `B` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(A, B, _)` +help: consider restricting type parameter `B` + | +LL | type Two<A, B: std::fmt::Debug> = impl Debug; + | +++++++++++++++++ + +error[E0277]: `A` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use9.rs:22:5 + | +LL | (t, u, 42) + | ^^^^^^^^^^ `A` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(A, B, i32)` +help: consider restricting type parameter `A` + | +LL | type Two<A: std::fmt::Debug, B> = impl Debug; + | +++++++++++++++++ + +error[E0277]: `B` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use9.rs:22:5 + | +LL | (t, u, 42) + | ^^^^^^^^^^ `B` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(A, B, i32)` +help: consider restricting type parameter `B` + | +LL | type Two<A, B: std::fmt::Debug> = impl Debug; + | +++++++++++++++++ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. 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 new file mode 100644 index 000000000..e109c38c9 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_lifetime_param.rs @@ -0,0 +1,11 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(type_alias_impl_trait)] + +fn main() {} + +type Region<'a> = impl std::fmt::Debug; + +fn region<'b>(a: &'b ()) -> Region<'b> { + a +} diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs new file mode 100644 index 000000000..f39741a6a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs @@ -0,0 +1,29 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +type OneTy<T> = impl Debug; + +type OneLifetime<'a> = impl Debug; + +type OneConst<const X: usize> = impl Debug; + + +// Not defining uses, because they doesn't define *all* possible generics. + +fn concrete_ty() -> OneTy<u32> { + 5u32 + //~^ ERROR non-defining opaque type use in defining scope +} + +fn concrete_lifetime() -> OneLifetime<'static> { + 6u32 + //~^ ERROR non-defining opaque type use in defining scope +} + +fn concrete_const() -> OneConst<{ 123 }> { + 7u32 + //~^ ERROR non-defining opaque type use in defining scope +} diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr new file mode 100644 index 000000000..e7565525a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr @@ -0,0 +1,35 @@ +error: non-defining opaque type use in defining scope + --> $DIR/generic_nondefining_use.rs:17:5 + | +LL | 5u32 + | ^^^^ + | +note: used non-generic type `u32` for generic parameter + --> $DIR/generic_nondefining_use.rs:7:12 + | +LL | type OneTy<T> = impl Debug; + | ^ + +error: non-defining opaque type use in defining scope + --> $DIR/generic_nondefining_use.rs:22:5 + | +LL | type OneLifetime<'a> = impl Debug; + | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type +... +LL | 6u32 + | ^^^^ + +error: non-defining opaque type use in defining scope + --> $DIR/generic_nondefining_use.rs:27:5 + | +LL | 7u32 + | ^^^^ + | +note: used non-generic constant `123` for generic parameter + --> $DIR/generic_nondefining_use.rs:11:15 + | +LL | type OneConst<const X: usize> = impl Debug; + | ^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/type-alias-impl-trait/generic_not_used.rs b/src/test/ui/type-alias-impl-trait/generic_not_used.rs new file mode 100644 index 000000000..c70f473cf --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_not_used.rs @@ -0,0 +1,11 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +type WrongGeneric<T: 'static> = impl 'static; +//~^ ERROR: at least one trait must be specified + +fn wrong_generic<U: 'static, V: 'static>(_: U, v: V) -> WrongGeneric<U> { + v + //~^ ERROR type parameter `V` is part of concrete type but not used in parameter list +} diff --git a/src/test/ui/type-alias-impl-trait/generic_not_used.stderr b/src/test/ui/type-alias-impl-trait/generic_not_used.stderr new file mode 100644 index 000000000..fd720239a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_not_used.stderr @@ -0,0 +1,14 @@ +error: at least one trait must be specified + --> $DIR/generic_not_used.rs:5:33 + | +LL | type WrongGeneric<T: 'static> = impl 'static; + | ^^^^^^^^^^^^ + +error: type parameter `V` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/generic_not_used.rs:9:5 + | +LL | v + | ^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs new file mode 100644 index 000000000..cb9077647 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs @@ -0,0 +1,16 @@ +#![feature(type_alias_impl_trait)] + +fn main() { + let y = 42; + let x = wrong_generic(&y); + let z: i32 = x; + //~^ ERROR non-defining opaque type use +} + +type WrongGeneric<T> = impl 'static; +//~^ ERROR: at least one trait must be specified + +fn wrong_generic<T>(t: T) -> WrongGeneric<T> { + t + //~^ ERROR the parameter type `T` may not live long enough +} diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr new file mode 100644 index 000000000..ba583241a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr @@ -0,0 +1,32 @@ +error: at least one trait must be specified + --> $DIR/generic_type_does_not_live_long_enough.rs:10:24 + | +LL | type WrongGeneric<T> = impl 'static; + | ^^^^^^^^^^^^ + +error: non-defining opaque type use in defining scope + --> $DIR/generic_type_does_not_live_long_enough.rs:6:18 + | +LL | let z: i32 = x; + | ^ + | +note: used non-generic type `&'static i32` for generic parameter + --> $DIR/generic_type_does_not_live_long_enough.rs:10:19 + | +LL | type WrongGeneric<T> = impl 'static; + | ^ + +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/generic_type_does_not_live_long_enough.rs:14:5 + | +LL | t + | ^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn wrong_generic<T: 'static>(t: T) -> WrongGeneric<T> { + | +++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0310`. diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained.rs b/src/test/ui/type-alias-impl-trait/generic_underconstrained.rs new file mode 100644 index 000000000..d87a25aad --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained.rs @@ -0,0 +1,12 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +trait Trait {} +type Underconstrained<T: Trait> = impl Send; + +// no `Trait` bound +fn underconstrain<T>(_: T) -> Underconstrained<T> { + //~^ ERROR the trait bound `T: Trait` + unimplemented!() +} diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr new file mode 100644 index 000000000..c73288329 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `T: Trait` is not satisfied + --> $DIR/generic_underconstrained.rs:9:31 + | +LL | fn underconstrain<T>(_: T) -> Underconstrained<T> { + | ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` + | +note: required by a bound in `Underconstrained` + --> $DIR/generic_underconstrained.rs:6:26 + | +LL | type Underconstrained<T: Trait> = impl Send; + | ^^^^^ required by this bound in `Underconstrained` +help: consider restricting type parameter `T` + | +LL | fn underconstrain<T: Trait>(_: T) -> Underconstrained<T> { + | +++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.rs b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.rs new file mode 100644 index 000000000..8adc0bf32 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.rs @@ -0,0 +1,19 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +type Underconstrained<T: std::fmt::Debug> = impl Send; + +// not a defining use, because it doesn't define *all* possible generics +fn underconstrained<U>(_: U) -> Underconstrained<U> { + //~^ ERROR `U` doesn't implement `Debug` + 5u32 +} + +type Underconstrained2<T: std::fmt::Debug> = impl Send; + +// not a defining use, because it doesn't define *all* possible generics +fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> { + //~^ ERROR `V` doesn't implement `Debug` + 5u32 +} diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr new file mode 100644 index 000000000..d77d978aa --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr @@ -0,0 +1,35 @@ +error[E0277]: `U` doesn't implement `Debug` + --> $DIR/generic_underconstrained2.rs:8:33 + | +LL | fn underconstrained<U>(_: U) -> Underconstrained<U> { + | ^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | +note: required by a bound in `Underconstrained` + --> $DIR/generic_underconstrained2.rs:5:26 + | +LL | type Underconstrained<T: std::fmt::Debug> = impl Send; + | ^^^^^^^^^^^^^^^ required by this bound in `Underconstrained` +help: consider restricting type parameter `U` + | +LL | fn underconstrained<U: std::fmt::Debug>(_: U) -> Underconstrained<U> { + | +++++++++++++++++ + +error[E0277]: `V` doesn't implement `Debug` + --> $DIR/generic_underconstrained2.rs:16:43 + | +LL | fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> { + | ^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | +note: required by a bound in `Underconstrained2` + --> $DIR/generic_underconstrained2.rs:13:27 + | +LL | type Underconstrained2<T: std::fmt::Debug> = impl Send; + | ^^^^^^^^^^^^^^^ required by this bound in `Underconstrained2` +help: consider restricting type parameter `V` + | +LL | fn underconstrained2<U, V: std::fmt::Debug>(_: U, _: V) -> Underconstrained2<V> { + | +++++++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs new file mode 100644 index 000000000..851c2f66c --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs @@ -0,0 +1,17 @@ +// Ensure that we don't ICE if associated type impl trait is used in an impl +// with an unconstrained type parameter. + +#![feature(type_alias_impl_trait)] + +trait X { + type I; + fn f() -> Self::I; +} + +impl<T> X for () { + //~^ ERROR the type parameter `T` is not constrained + type I = impl Sized; + fn f() -> Self::I {} +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr new file mode 100644 index 000000000..8cf8fb1d1 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/impl-with-unconstrained-param.rs:11:6 + | +LL | impl<T> X for () { + | ^ unconstrained type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs new file mode 100644 index 000000000..685d76ee3 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs @@ -0,0 +1,15 @@ +// Regression test for issue 67856 + +#![feature(unboxed_closures)] +#![feature(type_alias_impl_trait)] +#![feature(fn_traits)] + +trait MyTrait {} +impl MyTrait for () {} + +impl<F> FnOnce<()> for &F { + //~^ ERROR type parameter `F` must be used + type Output = impl MyTrait; + extern "rust-call" fn call_once(self, _: ()) -> Self::Output {} +} +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr new file mode 100644 index 000000000..b93ea955c --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr @@ -0,0 +1,12 @@ +error[E0210]: type parameter `F` must be used as the type parameter for some local type (e.g., `MyStruct<F>`) + --> $DIR/incoherent-assoc-imp-trait.rs:10:6 + | +LL | impl<F> FnOnce<()> for &F { + | ^ type parameter `F` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/type-alias-impl-trait/incomplete-inference.rs b/src/test/ui/type-alias-impl-trait/incomplete-inference.rs new file mode 100644 index 000000000..4c8bf2cfc --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/incomplete-inference.rs @@ -0,0 +1,14 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl Sized; + +fn bar() -> Foo { + None + //~^ ERROR: type annotations needed [E0282] +} + +fn baz() -> Foo { + Some(()) +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/incomplete-inference.stderr b/src/test/ui/type-alias-impl-trait/incomplete-inference.stderr new file mode 100644 index 000000000..9a0e71b4e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/incomplete-inference.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/incomplete-inference.rs:6:5 + | +LL | None + | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option` + | +help: consider specifying the generic argument + | +LL | None::<T> + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-alias-impl-trait/inference-cycle.rs b/src/test/ui/type-alias-impl-trait/inference-cycle.rs new file mode 100644 index 000000000..79caddf79 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/inference-cycle.rs @@ -0,0 +1,25 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +mod m { + type Foo = impl std::fmt::Debug; + //~^ ERROR cycle detected + + // Cycle: error today, but it'd be nice if it eventually worked + + pub fn foo() -> Foo { + is_send(bar()) + } + + pub fn bar() { + is_send(foo()); // Today: error + } + + fn baz() { + let f: Foo = 22_u32; + } + + fn is_send<T: Send>(_: T) {} +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/inference-cycle.stderr b/src/test/ui/type-alias-impl-trait/inference-cycle.stderr new file mode 100644 index 000000000..b9d646b92 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/inference-cycle.stderr @@ -0,0 +1,22 @@ +error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}` + --> $DIR/inference-cycle.rs:5:16 + | +LL | type Foo = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `m::bar`... + --> $DIR/inference-cycle.rs:15:9 + | +LL | is_send(foo()); // Today: error + | ^^^^^^^ + = note: ...which requires evaluating trait selection obligation `m::Foo: core::marker::Send`... + = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle +note: cycle used when checking item types in module `m` + --> $DIR/inference-cycle.rs:4:1 + | +LL | mod m { + | ^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs new file mode 100644 index 000000000..50eeff0b1 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs @@ -0,0 +1,13 @@ +// Checks to ensure that we properly detect when a closure constrains an opaque type + +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() { + type Opaque = impl Debug; + fn _unused() -> Opaque { String::new() } + let null = || -> Opaque { 0 }; + //~^ ERROR: concrete type differs from previous defining opaque type use + println!("{:?}", null()); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr new file mode 100644 index 000000000..4c5fd2255 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr @@ -0,0 +1,14 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/issue-52843-closure-constrain.rs:10:31 + | +LL | let null = || -> Opaque { 0 }; + | ^ expected `String`, got `i32` + | +note: previous use here + --> $DIR/issue-52843-closure-constrain.rs:9:30 + | +LL | fn _unused() -> Opaque { String::new() } + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-52843.rs b/src/test/ui/type-alias-impl-trait/issue-52843.rs new file mode 100644 index 000000000..159d3ccd2 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-52843.rs @@ -0,0 +1,15 @@ +#![feature(type_alias_impl_trait)] + +type Foo<T> = impl Default; + +#[allow(unused)] +fn foo<T: Default>(t: T) -> Foo<T> { + t + //~^ ERROR: the trait bound `T: Default` is not satisfied +} + +struct NotDefault; + +fn main() { + let _ = Foo::<NotDefault>::default(); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-52843.stderr b/src/test/ui/type-alias-impl-trait/issue-52843.stderr new file mode 100644 index 000000000..acd40f980 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-52843.stderr @@ -0,0 +1,14 @@ +error[E0277]: the trait bound `T: Default` is not satisfied + --> $DIR/issue-52843.rs:7:5 + | +LL | t + | ^ the trait `Default` is not implemented for `T` + | +help: consider restricting type parameter `T` + | +LL | type Foo<T: std::default::Default> = impl Default; + | +++++++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/issue-53092-2.rs b/src/test/ui/type-alias-impl-trait/issue-53092-2.rs new file mode 100644 index 000000000..438ac35fd --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53092-2.rs @@ -0,0 +1,15 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +type Bug<T, U> = impl Fn(T) -> U + Copy; //~ ERROR cycle detected + +const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) }; +//~^ ERROR: cannot transmute + +fn make_bug<T, U: From<T>>() -> Bug<T, U> { + |x| x.into() //~ ERROR the trait bound `U: From<T>` is not satisfied +} + +fn main() { + CONST_BUG(0); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr b/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr new file mode 100644 index 000000000..1b89d5571 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr @@ -0,0 +1,55 @@ +error[E0391]: cycle detected when computing type of `Bug::{opaque#0}` + --> $DIR/issue-53092-2.rs:4:18 + | +LL | type Bug<T, U> = impl Fn(T) -> U + Copy; + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `CONST_BUG`... + --> $DIR/issue-53092-2.rs:6:1 + | +LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires computing layout of `Bug<u8, ()>`... + = note: ...which requires normalizing `Bug<u8, ()>`... + = note: ...which again requires computing type of `Bug::{opaque#0}`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/issue-53092-2.rs:1:1 + | +LL | / #![feature(type_alias_impl_trait)] +LL | | #![allow(dead_code)] +LL | | +LL | | type Bug<T, U> = impl Fn(T) -> U + Copy; +... | +LL | | CONST_BUG(0); +LL | | } + | |_^ + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/issue-53092-2.rs:6:41 + | +LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `[closure@$DIR/issue-53092-2.rs:6:61: 6:68]` (0 bits) + = note: target type: `Bug<u8, ()>` (size can vary because of [type error]) + +error[E0277]: the trait bound `U: From<T>` is not satisfied + --> $DIR/issue-53092-2.rs:10:5 + | +LL | |x| x.into() + | ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U` + | +note: required by a bound in `make_bug` + --> $DIR/issue-53092-2.rs:9:19 + | +LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> { + | ^^^^^^^ required by this bound in `make_bug` +help: consider restricting type parameter `U` + | +LL | type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy; + | +++++++++++++++++++++++ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0391, E0512. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/issue-53092.rs b/src/test/ui/type-alias-impl-trait/issue-53092.rs new file mode 100644 index 000000000..1be5b46d6 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53092.rs @@ -0,0 +1,19 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +type Bug<T, U> = impl Fn(T) -> U + Copy; + +union Moo { + x: Bug<u8, ()>, + y: (), +} + +const CONST_BUG: Bug<u8, ()> = unsafe { Moo { y: () }.x }; + +fn make_bug<T, U: From<T>>() -> Bug<T, U> { + |x| x.into() //~ ERROR the trait bound `U: From<T>` is not satisfied +} + +fn main() { + CONST_BUG(0); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-53092.stderr b/src/test/ui/type-alias-impl-trait/issue-53092.stderr new file mode 100644 index 000000000..2109cf8a7 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53092.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `U: From<T>` is not satisfied + --> $DIR/issue-53092.rs:14:5 + | +LL | |x| x.into() + | ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U` + | +note: required by a bound in `make_bug` + --> $DIR/issue-53092.rs:13:19 + | +LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> { + | ^^^^^^^ required by this bound in `make_bug` +help: consider restricting type parameter `U` + | +LL | type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy; + | +++++++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/issue-53096.rs b/src/test/ui/type-alias-impl-trait/issue-53096.rs new file mode 100644 index 000000000..007dcf3bc --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53096.rs @@ -0,0 +1,11 @@ +#![feature(rustc_attrs)] +#![feature(type_alias_impl_trait)] + +type Foo = impl Fn() -> usize; +const fn bar() -> Foo { + || 0usize +} +const BAZR: Foo = bar(); + +#[rustc_error] +fn main() {} //~ ERROR diff --git a/src/test/ui/type-alias-impl-trait/issue-53096.stderr b/src/test/ui/type-alias-impl-trait/issue-53096.stderr new file mode 100644 index 000000000..0af3a75f8 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53096.stderr @@ -0,0 +1,8 @@ +error: fatal error triggered by #[rustc_error] + --> $DIR/issue-53096.rs:11:1 + | +LL | fn main() {} + | ^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs new file mode 100644 index 000000000..4a11bb502 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs @@ -0,0 +1,10 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl Fn() -> Foo; + +fn foo() -> Foo { +//~^ ERROR: overflow evaluating the requirement + foo +} + +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 new file mode 100644 index 000000000..d20b1cc6d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr @@ -0,0 +1,11 @@ +error[E0275]: overflow evaluating the requirement `fn() -> Foo {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`) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/type-alias-impl-trait/issue-53598.rs b/src/test/ui/type-alias-impl-trait/issue-53598.rs new file mode 100644 index 000000000..9c1cbf926 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53598.rs @@ -0,0 +1,27 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +pub trait Foo { + type Item: Debug; + + fn foo<T: Debug>(_: T) -> Self::Item; +} + +#[derive(Debug)] +pub struct S<T>(std::marker::PhantomData<T>); + +pub struct S2; + +impl Foo for S2 { + type Item = impl Debug; + + fn foo<T: Debug>(_: T) -> Self::Item { + S::<T>(Default::default()) + //~^ Error type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + } +} + +fn main() { + S2::foo(123); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-53598.stderr b/src/test/ui/type-alias-impl-trait/issue-53598.stderr new file mode 100644 index 000000000..f8b8201e2 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53598.stderr @@ -0,0 +1,8 @@ +error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/issue-53598.rs:20:9 + | +LL | S::<T>(Default::default()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs b/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs new file mode 100644 index 000000000..a3f126d56 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs @@ -0,0 +1,19 @@ +#![feature(generators, generator_trait, rustc_attrs)] +#![feature(type_alias_impl_trait)] + +use std::ops::Generator; + +type GenOnce<Y, R> = impl Generator<Yield = Y, Return = R>; + +const fn const_generator<Y, R>(yielding: Y, returning: R) -> GenOnce<Y, R> { + move || { + yield yielding; + + return returning; + } +} + +const FOO: GenOnce<usize, usize> = const_generator(10, 100); + +#[rustc_error] +fn main() {} //~ ERROR diff --git a/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.stderr b/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.stderr new file mode 100644 index 000000000..eb1c9603a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.stderr @@ -0,0 +1,8 @@ +error: fatal error triggered by #[rustc_error] + --> $DIR/issue-53678-generator-and-const-fn.rs:19:1 + | +LL | fn main() {} + | ^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs b/src/test/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs new file mode 100644 index 000000000..af0780ab0 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs @@ -0,0 +1,26 @@ +// check-pass +// Regression test for issue #55099 +// Tests that we don't incorrectly consider a lifetime to part +// of the concrete type + +#![feature(type_alias_impl_trait)] + +trait Future {} + +struct AndThen<F>(F); + +impl<F> Future for AndThen<F> {} + +struct Foo<'a> { + x: &'a mut (), +} + +type F = impl Future; + +impl<'a> Foo<'a> { + fn reply(&mut self) -> F { + AndThen(|| ()) + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs b/src/test/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs new file mode 100644 index 000000000..3a7a5da07 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs @@ -0,0 +1,24 @@ +// Regression test for #57188 + +// check-pass + +#![feature(type_alias_impl_trait)] + +struct Baz<'a> { + source: &'a str, +} + +trait Foo<'a> { + type T: Iterator<Item = Baz<'a>> + 'a; + fn foo(source: &'a str) -> Self::T; +} + +struct Bar; +impl<'a> Foo<'a> for Bar { + type T = impl Iterator<Item = Baz<'a>> + 'a; + fn foo(source: &'a str) -> Self::T { + std::iter::once(Baz { source }) + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs new file mode 100644 index 000000000..067ed7ea1 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs @@ -0,0 +1,27 @@ +// Regression test for issue #57611 +// Ensures that we don't ICE +// FIXME: This should compile, but it currently doesn't +// known-bug: unknown + +#![feature(trait_alias)] +#![feature(type_alias_impl_trait)] + +trait Foo { + type Bar: Baz<Self, Self>; + + fn bar(&self) -> Self::Bar; +} + +struct X; + +impl Foo for X { + type Bar = impl Baz<Self, Self>; + + fn bar(&self) -> Self::Bar { + |x| x + } +} + +trait Baz<A: ?Sized, B: ?Sized> = Fn(&A) -> &B; + +fn main() {} 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 new file mode 100644 index 000000000..f14bf6b0f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr @@ -0,0 +1,26 @@ +error[E0308]: mismatched types + --> $DIR/issue-57611-trait-alias.rs:21:9 + | +LL | |x| x + | ^^^^^ one type is more general than the other + | + = note: expected trait `for<'r> Fn<(&'r X,)>` + found trait `Fn<(&X,)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-57611-trait-alias.rs:21:9 + | +LL | |x| x + | ^^^ + +error: implementation of `FnOnce` is not general enough + --> $DIR/issue-57611-trait-alias.rs:21:9 + | +LL | |x| x + | ^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/issue-57700.rs b/src/test/ui/type-alias-impl-trait/issue-57700.rs new file mode 100644 index 000000000..484589387 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57700.rs @@ -0,0 +1,21 @@ +#![feature(arbitrary_self_types)] +#![feature(type_alias_impl_trait)] + +use std::ops::Deref; + +trait Foo { + type Bar: Foo; + + fn foo(self: impl Deref<Target = Self>) -> Self::Bar; +} + +impl<C> Foo for C { + type Bar = impl Foo; + + fn foo(self: impl Deref<Target = Self>) -> Self::Bar { + self + //~^ Error type parameter `impl Deref<Target = Self>` is part of concrete type but not used in parameter list for the `impl Trait` type alias + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-57700.stderr b/src/test/ui/type-alias-impl-trait/issue-57700.stderr new file mode 100644 index 000000000..31b6df5d4 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57700.stderr @@ -0,0 +1,8 @@ +error: type parameter `impl Deref<Target = Self>` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/issue-57700.rs:16:9 + | +LL | self + | ^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-57807-associated-type.rs b/src/test/ui/type-alias-impl-trait/issue-57807-associated-type.rs new file mode 100644 index 000000000..fcab2c7db --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57807-associated-type.rs @@ -0,0 +1,31 @@ +// Regression test for issue #57807 - ensure +// that we properly unify associated types within +// a type alias impl trait +// check-pass +#![feature(type_alias_impl_trait)] + +trait Bar { + type A; +} + +impl Bar for () { + type A = (); +} + +trait Foo { + type A; + type B: Bar<A = Self::A>; + + fn foo() -> Self::B; +} + +impl Foo for () { + type A = (); + type B = impl Bar<A = Self::A>; + + fn foo() -> Self::B { + () + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-57961.rs b/src/test/ui/type-alias-impl-trait/issue-57961.rs new file mode 100644 index 000000000..472886c9c --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57961.rs @@ -0,0 +1,18 @@ +#![feature(type_alias_impl_trait)] + +type X = impl Sized; + +trait Foo { + type Bar: Iterator<Item = X>; +} + +impl Foo for () { + type Bar = std::vec::IntoIter<u32>; + //~^ ERROR type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::Item == X +} + +fn incoherent() { + let f: X = 22_i32; +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-57961.stderr b/src/test/ui/type-alias-impl-trait/issue-57961.stderr new file mode 100644 index 000000000..ed4caf6ce --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57961.stderr @@ -0,0 +1,20 @@ +error[E0271]: type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::Item == X` + --> $DIR/issue-57961.rs:10:16 + | +LL | type X = impl Sized; + | ---------- the expected opaque type +... +LL | type Bar = std::vec::IntoIter<u32>; + | ^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found `u32` + | + = note: expected opaque type `X` + found type `u32` +note: required by a bound in `Foo::Bar` + --> $DIR/issue-57961.rs:6:24 + | +LL | type Bar: Iterator<Item = X>; + | ^^^^^^^^ required by this bound in `Foo::Bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. 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 new file mode 100644 index 000000000..f20ddf020 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-58662-generator-with-lifetime.rs @@ -0,0 +1,39 @@ +// check-pass + +#![feature(generators, generator_trait)] +#![feature(type_alias_impl_trait)] + +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; + +type RandGenerator<'a> = impl Generator<Return = (), Yield = u64> + 'a; +fn rand_generator<'a>(rng: &'a ()) -> RandGenerator<'a> { + move || { + let _rng = rng; + loop { + yield 0; + } + } +} + +pub type RandGeneratorWithIndirection<'a> = impl Generator<Return = (), Yield = u64> + 'a; +pub fn rand_generator_with_indirection<'a>(rng: &'a ()) -> RandGeneratorWithIndirection<'a> { + fn helper<'b>(rng: &'b ()) -> impl 'b + Generator<Return = (), Yield = u64> { + move || { + let _rng = rng; + loop { + yield 0; + } + } + } + + helper(rng) +} + +fn main() { + let mut gen = rand_generator(&()); + match unsafe { Pin::new_unchecked(&mut gen) }.resume(()) { + GeneratorState::Yielded(_) => {} + GeneratorState::Complete(_) => {} + }; +} diff --git a/src/test/ui/type-alias-impl-trait/issue-58887.rs b/src/test/ui/type-alias-impl-trait/issue-58887.rs new file mode 100644 index 000000000..96ac78602 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-58887.rs @@ -0,0 +1,22 @@ +// run-pass + +#![feature(type_alias_impl_trait)] + +trait UnwrapItemsExt { + type Iter; + fn unwrap_items(self) -> Self::Iter; +} + +impl<I, T, E> UnwrapItemsExt for I +where + I: Iterator<Item = Result<T, E>>, + E: std::fmt::Debug, +{ + type Iter = impl Iterator<Item = T>; + + fn unwrap_items(self) -> Self::Iter { + self.map(|x| x.unwrap()) + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-58951-2.rs b/src/test/ui/type-alias-impl-trait/issue-58951-2.rs new file mode 100644 index 000000000..e4ba7f8e2 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-58951-2.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +mod defining_use_scope { + pub type A = impl Iterator; + + pub fn def_a() -> A { + 0..1 + } +} +use defining_use_scope::*; + +pub fn use_a() { + def_a().map(|x| x); +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-58951.rs b/src/test/ui/type-alias-impl-trait/issue-58951.rs new file mode 100644 index 000000000..7303cbab4 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-58951.rs @@ -0,0 +1,15 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +type A = impl Iterator; + +fn def_a() -> A { + 0..1 +} + +pub fn use_a() { + def_a().map(|x| x); +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.rs b/src/test/ui/type-alias-impl-trait/issue-60371.rs new file mode 100644 index 000000000..9a40f3d9b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-60371.rs @@ -0,0 +1,14 @@ +trait Bug { + type Item: Bug; + + const FUN: fn() -> Self::Item; +} + +impl Bug for &() { + type Item = impl Bug; //~ ERROR `impl Trait` in type aliases is unstable + + const FUN: fn() -> Self::Item = || (); + //~^ ERROR the trait bound `(): Bug` is not satisfied +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.stderr b/src/test/ui/type-alias-impl-trait/issue-60371.stderr new file mode 100644 index 000000000..082b0f0c3 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-60371.stderr @@ -0,0 +1,21 @@ +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/issue-60371.rs:8:17 + | +LL | type Item = impl Bug; + | ^^^^^^^^ + | + = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information + = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable + +error[E0277]: the trait bound `(): Bug` is not satisfied + --> $DIR/issue-60371.rs:10:40 + | +LL | const FUN: fn() -> Self::Item = || (); + | ^ the trait `Bug` is not implemented for `()` + | + = help: the trait `Bug` is implemented for `&()` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0658. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/issue-60407.rs b/src/test/ui/type-alias-impl-trait/issue-60407.rs new file mode 100644 index 000000000..b833429c7 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-60407.rs @@ -0,0 +1,15 @@ +#![feature(type_alias_impl_trait, rustc_attrs)] + +type Debuggable = impl core::fmt::Debug; + +static mut TEST: Option<Debuggable> = None; + +#[rustc_error] +fn main() { + //~^ ERROR + unsafe { TEST = Some(foo()) } +} + +fn foo() -> Debuggable { + 0u32 +} diff --git a/src/test/ui/type-alias-impl-trait/issue-60407.stderr b/src/test/ui/type-alias-impl-trait/issue-60407.stderr new file mode 100644 index 000000000..fecee2779 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-60407.stderr @@ -0,0 +1,8 @@ +error: fatal error triggered by #[rustc_error] + --> $DIR/issue-60407.rs:8:1 + | +LL | fn main() { + | ^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-60564-working.rs b/src/test/ui/type-alias-impl-trait/issue-60564-working.rs new file mode 100644 index 000000000..38accc824 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-60564-working.rs @@ -0,0 +1,24 @@ +#![feature(type_alias_impl_trait)] + +// check-pass + +trait IterBits { + type BitsIter: Iterator<Item = u8>; + fn iter_bits(self, n: u8) -> Self::BitsIter; +} + +impl<T: Copy, E> IterBits for T +where + T: std::ops::Shr<Output = T> + + std::ops::BitAnd<T, Output = T> + + std::convert::From<u8> + + std::convert::TryInto<u8, Error = E>, + E: std::fmt::Debug, +{ + type BitsIter = impl std::iter::Iterator<Item = u8>; + fn iter_bits(self, n: u8) -> Self::BitsIter { + (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.rs b/src/test/ui/type-alias-impl-trait/issue-60564.rs new file mode 100644 index 000000000..4fc767931 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs @@ -0,0 +1,25 @@ +#![feature(type_alias_impl_trait)] + +trait IterBits { + type BitsIter: Iterator<Item = u8>; + fn iter_bits(self, n: u8) -> Self::BitsIter; +} + +type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>; + +impl<T: Copy, E> IterBits for T +where + T: std::ops::Shr<Output = T> + + std::ops::BitAnd<T, Output = T> + + std::convert::From<u8> + + std::convert::TryInto<u8, Error = E>, + E: std::fmt::Debug, +{ + type BitsIter = IterBitsIter<T, E, u8>; + fn iter_bits(self, n: u8) -> Self::BitsIter { + (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) + //~^ ERROR non-defining opaque type use in defining scope + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.stderr b/src/test/ui/type-alias-impl-trait/issue-60564.stderr new file mode 100644 index 000000000..bbc93657b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-60564.stderr @@ -0,0 +1,14 @@ +error: non-defining opaque type use in defining scope + --> $DIR/issue-60564.rs:20:9 + | +LL | (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: used non-generic type `u8` for generic parameter + --> $DIR/issue-60564.rs:8:25 + | +LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>; + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-60662.rs b/src/test/ui/type-alias-impl-trait/issue-60662.rs new file mode 100644 index 000000000..b9faa668b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-60662.rs @@ -0,0 +1,10 @@ +// check-pass +// compile-flags: -Z unpretty=hir + +#![feature(type_alias_impl_trait)] + +trait Animal {} + +fn main() { + pub type ServeFut = impl Animal; +} diff --git a/src/test/ui/type-alias-impl-trait/issue-60662.stdout b/src/test/ui/type-alias-impl-trait/issue-60662.stdout new file mode 100644 index 000000000..5b3d7375d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-60662.stdout @@ -0,0 +1,14 @@ +// check-pass +// compile-flags: -Z unpretty=hir + +#![feature(type_alias_impl_trait)] +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; + +trait Animal { } + +fn main() { + type ServeFut = /*impl Trait*/; + } diff --git a/src/test/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs b/src/test/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs new file mode 100644 index 000000000..36779a0ce --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs @@ -0,0 +1,38 @@ +// Regression test for #62988 + +// check-pass + +#![feature(type_alias_impl_trait)] + +trait MyTrait { + type AssocType: Send; + fn ret(&self) -> Self::AssocType; +} + +impl MyTrait for () { + type AssocType = impl Send; + fn ret(&self) -> Self::AssocType { + () + } +} + +impl<'a> MyTrait for &'a () { + type AssocType = impl Send; + fn ret(&self) -> Self::AssocType { + () + } +} + +trait MyLifetimeTrait<'a> { + type AssocType: Send + 'a; + fn ret(&self) -> Self::AssocType; +} + +impl<'a> MyLifetimeTrait<'a> for &'a () { + type AssocType = impl Send + 'a; + fn ret(&self) -> Self::AssocType { + *self + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-63263-closure-return.rs b/src/test/ui/type-alias-impl-trait/issue-63263-closure-return.rs new file mode 100644 index 000000000..7414611a7 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-63263-closure-return.rs @@ -0,0 +1,13 @@ +// Regression test for issue #63263. +// Tests that we properly handle closures with an explicit return type +// that return an opaque type. + +// check-pass + +#![feature(type_alias_impl_trait)] + +pub type Closure = impl FnOnce(); + +fn main() { + || -> Closure { || () }; +} diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.rs b/src/test/ui/type-alias-impl-trait/issue-63279.rs new file mode 100644 index 000000000..97332e16d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-63279.rs @@ -0,0 +1,15 @@ +// compile-flags: -Zsave-analysis + +#![feature(type_alias_impl_trait)] + +type Closure = impl FnOnce(); + +fn c() -> Closure { + //~^ ERROR: expected a `FnOnce<()>` closure, found `()` + || -> Closure { || () } + //~^ ERROR: mismatched types + //~| ERROR: mismatched types + //~| ERROR: expected a `FnOnce<()>` closure, found `()` +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.stderr b/src/test/ui/type-alias-impl-trait/issue-63279.stderr new file mode 100644 index 000000000..110b8d1ee --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-63279.stderr @@ -0,0 +1,48 @@ +error[E0277]: expected a `FnOnce<()>` closure, found `()` + --> $DIR/issue-63279.rs:7:11 + | +LL | fn c() -> Closure { + | ^^^^^^^ expected an `FnOnce<()>` closure, found `()` + | + = help: the trait `FnOnce<()>` is not implemented for `()` + = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` + +error[E0277]: expected a `FnOnce<()>` closure, found `()` + --> $DIR/issue-63279.rs:9:11 + | +LL | || -> Closure { || () } + | ^^^^^^^ expected an `FnOnce<()>` closure, found `()` + | + = help: the trait `FnOnce<()>` is not implemented for `()` + = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` + +error[E0308]: mismatched types + --> $DIR/issue-63279.rs:9:21 + | +LL | || -> Closure { || () } + | ^^^^^ expected `()`, found closure + | + = note: expected unit type `()` + found closure `[closure@$DIR/issue-63279.rs:9:21: 9:23]` +help: use parentheses to call this closure + | +LL | || -> Closure { (|| ())() } + | + +++ + +error[E0308]: mismatched types + --> $DIR/issue-63279.rs:9:5 + | +LL | || -> Closure { || () } + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found closure + | + = note: expected unit type `()` + found closure `[closure@$DIR/issue-63279.rs:9:5: 9:18]` +help: use parentheses to call this closure + | +LL | (|| -> Closure { || () })() + | + +++ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/issue-63355.rs b/src/test/ui/type-alias-impl-trait/issue-63355.rs new file mode 100644 index 000000000..7066a0535 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-63355.rs @@ -0,0 +1,46 @@ +#![feature(type_alias_impl_trait)] +// check-pass + +pub trait Foo {} + +pub trait Bar { + type Foo: Foo; + + fn foo() -> Self::Foo; +} + +pub trait Baz { + type Foo: Foo; + type Bar: Bar<Foo = Self::Foo>; + + fn foo() -> Self::Foo; + fn bar() -> Self::Bar; +} + +impl Foo for () {} + +impl Bar for () { + type Foo = FooImpl; + + fn foo() -> Self::Foo { + () + } +} + +pub type FooImpl = impl Foo; +pub type BarImpl = impl Bar<Foo = FooImpl>; + +impl Baz for () { + type Foo = FooImpl; + type Bar = BarImpl; + + fn foo() -> Self::Foo { + () + } + + fn bar() -> Self::Bar { + () + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs b/src/test/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs new file mode 100644 index 000000000..28f4a85c9 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs @@ -0,0 +1,21 @@ +// check-pass +// Regression test for issue #63677 - ensure that +// coherence checking can properly handle 'impl trait' +// in type aliases +#![feature(type_alias_impl_trait)] + +pub trait Trait {} +pub struct S1<T>(T); +pub struct S2<T>(T); + +pub type T1 = impl Trait; +pub type T2 = S1<T1>; +pub type T3 = S2<T2>; + +impl<T> Trait for S1<T> {} +impl<T: Trait> S2<T> {} +impl T3 {} + +pub fn use_t1() -> T1 { S1(()) } + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-65384.rs b/src/test/ui/type-alias-impl-trait/issue-65384.rs new file mode 100644 index 000000000..9a119c4d2 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-65384.rs @@ -0,0 +1,15 @@ +#![feature(type_alias_impl_trait)] +#![allow(incomplete_features)] + +trait MyTrait {} + +impl MyTrait for () {} + +type Bar = impl MyTrait; + +impl MyTrait for Bar {} +//~^ ERROR: cannot implement trait on type alias impl trait + +fn bazr() -> Bar { } + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-65384.stderr b/src/test/ui/type-alias-impl-trait/issue-65384.stderr new file mode 100644 index 000000000..41bcea27e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-65384.stderr @@ -0,0 +1,14 @@ +error: cannot implement trait on type alias impl trait + --> $DIR/issue-65384.rs:10:18 + | +LL | impl MyTrait for Bar {} + | ^^^ + | +note: type alias impl trait defined here + --> $DIR/issue-65384.rs:8:12 + | +LL | type Bar = impl MyTrait; + | ^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs b/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs new file mode 100644 index 000000000..72c22827f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs @@ -0,0 +1,18 @@ +// compile-flags: -Zsave-analysis +// check-pass + +#![feature(type_alias_impl_trait, rustc_attrs)] + +type T = impl Sized; +// The concrete type referred by impl-trait-type-alias(`T`) is guaranteed +// to be the same as where it occurs, whereas `impl Trait`'s instance is location sensitive; +// so difference assertion should not be declared on impl-trait-type-alias's instances. +// for details, check RFC-2515: +// https://github.com/rust-lang/rfcs/blob/master/text/2515-type_alias_impl_trait.md + +fn take(_: fn() -> T) {} + +fn main() { + take(|| {}); + take(|| {}); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-65918.rs b/src/test/ui/type-alias-impl-trait/issue-65918.rs new file mode 100644 index 000000000..af6d50109 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-65918.rs @@ -0,0 +1,51 @@ +// ignore-test: This now ICEs again. + +// build-pass + +#![feature(type_alias_impl_trait)] + +use std::marker::PhantomData; + +/* copied Index and TryFrom for convenience (and simplicity) */ +trait MyIndex<T> { + type O; + fn my_index(self) -> Self::O; +} +trait MyFrom<T>: Sized { + type Error; + fn my_from(value: T) -> Result<Self, Self::Error>; +} + +/* MCVE starts here */ +trait F {} +impl F for () {} +type DummyT<T> = impl F; +fn _dummy_t<T>() -> DummyT<T> {} + +struct Phantom1<T>(PhantomData<T>); +struct Phantom2<T>(PhantomData<T>); +struct Scope<T>(Phantom2<DummyT<T>>); + +impl<T> Scope<T> { + fn new() -> Self { + unimplemented!() + } +} + +impl<T> MyFrom<Phantom2<T>> for Phantom1<T> { + type Error = (); + fn my_from(_: Phantom2<T>) -> Result<Self, Self::Error> { + unimplemented!() + } +} + +impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<Phantom1<T>> for Scope<U> { + type O = T; + fn my_index(self) -> Self::O { + MyFrom::my_from(self.0).ok().unwrap() + } +} + +fn main() { + let _pos: Phantom1<DummyT<()>> = Scope::new().my_index(); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs b/src/test/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs new file mode 100644 index 000000000..d97270c31 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs @@ -0,0 +1,21 @@ +// Regression test for issue #66580 +// Ensures that we don't try to determine whether a closure +// is foreign when it's the underlying type of an opaque type +// check-pass +#![feature(type_alias_impl_trait)] + +type Closure = impl FnOnce(); + +fn closure() -> Closure { + || {} +} + +struct Wrap<T> { + f: T, +} + +impl Wrap<Closure> {} + +impl<T> Wrap<T> {} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs b/src/test/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs new file mode 100644 index 000000000..cd219328a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs @@ -0,0 +1,33 @@ +// check-pass +// Regression test for issue #67844 +// Ensures that we properly handle nested TAIT occurrences +// with generic parameters + +#![feature(type_alias_impl_trait)] + +trait WithAssoc { + type AssocType; +} + +trait WithParam<A> {} + +type Return<A> = impl WithAssoc<AssocType = impl WithParam<A>>; + +struct MyParam; +impl<A> WithParam<A> for MyParam {} + +struct MyStruct; + +impl WithAssoc for MyStruct { + type AssocType = MyParam; +} + +fn my_fun<A>() -> Return<A> { + MyStruct +} + +fn my_other_fn<A>() -> impl WithAssoc<AssocType = impl WithParam<A>> { + MyStruct +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs new file mode 100644 index 000000000..5223fb1c7 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs @@ -0,0 +1,14 @@ +// Regression test for issue #68368 +// Ensures that we don't ICE when emitting an error +// for a non-defining use when lifetimes are involved + +#![feature(type_alias_impl_trait)] +trait Trait<T> {} +type Alias<'a, U> = impl Trait<U>; + +fn f<'a>() -> Alias<'a, ()> {} +//~^ ERROR non-defining opaque type use in defining scope + +fn main() {} + +impl<X> Trait<X> for () {} diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr new file mode 100644 index 000000000..7fb9a0c41 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr @@ -0,0 +1,14 @@ +error: non-defining opaque type use in defining scope + --> $DIR/issue-68368-non-defining-use-2.rs:9:29 + | +LL | fn f<'a>() -> Alias<'a, ()> {} + | ^^ + | +note: used non-generic type `()` for generic parameter + --> $DIR/issue-68368-non-defining-use-2.rs:7:16 + | +LL | type Alias<'a, U> = impl Trait<U>; + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs new file mode 100644 index 000000000..b50462bf2 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs @@ -0,0 +1,14 @@ +// Regression test for issue #68368 +// Ensures that we don't ICE when emitting an error +// for a non-defining use when lifetimes are involved + +#![feature(type_alias_impl_trait)] +trait Trait<T> {} +type Alias<'a, U> = impl Trait<U>; + +fn f<'a>() -> Alias<'a, ()> {} +//~^ ERROR non-defining opaque type use in defining scope + +fn main() {} + +impl Trait<()> for () {} diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr new file mode 100644 index 000000000..8059621b6 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr @@ -0,0 +1,14 @@ +error: non-defining opaque type use in defining scope + --> $DIR/issue-68368-non-defining-use.rs:9:29 + | +LL | fn f<'a>() -> Alias<'a, ()> {} + | ^^ + | +note: used non-generic type `()` for generic parameter + --> $DIR/issue-68368-non-defining-use.rs:7:16 + | +LL | type Alias<'a, U> = impl Trait<U>; + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs new file mode 100644 index 000000000..428454bc0 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs @@ -0,0 +1,23 @@ +// Regression test for #69136 + +#![feature(type_alias_impl_trait)] + +trait SomeTrait {} + +impl SomeTrait for () {} + +trait WithAssoc<A> { + type AssocType; +} + +impl<T> WithAssoc<T> for () { + type AssocType = (); +} + +type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>; +//~^ ERROR use of undeclared lifetime name `'a` + +fn my_fun() -> Return<()> {} +//~^ ERROR non-defining opaque type use in defining scope + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr new file mode 100644 index 000000000..7b50c8af2 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr @@ -0,0 +1,31 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/issue-69136-inner-lifetime-resolve-error.rs:17:65 + | +LL | type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>; + | ^^ undeclared lifetime + | + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider making the bound lifetime-generic with a new `'a` lifetime + | +LL | type Return<A> = impl for<'a> WithAssoc<A, AssocType = impl SomeTrait + 'a>; + | +++++++ +help: consider introducing lifetime `'a` here + | +LL | type Return<'a, A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>; + | +++ + +error: non-defining opaque type use in defining scope + --> $DIR/issue-69136-inner-lifetime-resolve-error.rs:20:27 + | +LL | fn my_fun() -> Return<()> {} + | ^^ + | +note: used non-generic type `()` for generic parameter + --> $DIR/issue-69136-inner-lifetime-resolve-error.rs:17:13 + | +LL | type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>; + | ^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0261`. diff --git a/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs new file mode 100644 index 000000000..a6916eda8 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs @@ -0,0 +1,23 @@ +// Test-pass variant of #69136 + +// check-pass + +#![feature(type_alias_impl_trait)] + +trait SomeTrait {} + +impl SomeTrait for () {} + +trait WithAssoc { + type AssocType; +} + +impl WithAssoc for () { + type AssocType = (); +} + +type Return<'a> = impl WithAssoc<AssocType = impl Sized + 'a>; + +fn my_fun<'a>() -> Return<'a> {} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-69323.rs b/src/test/ui/type-alias-impl-trait/issue-69323.rs new file mode 100644 index 000000000..a9bd6daf2 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-69323.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +use std::iter::{once, Chain}; + +fn test1<A: Iterator<Item = &'static str>>(x: A) -> Chain<A, impl Iterator<Item = &'static str>> { + x.chain(once(",")) +} + +type I<A> = Chain<A, impl Iterator<Item = &'static str>>; +fn test2<A: Iterator<Item = &'static str>>(x: A) -> I<A> { + x.chain(once(",")) +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-70121.rs b/src/test/ui/type-alias-impl-trait/issue-70121.rs new file mode 100644 index 000000000..dff0d89d4 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-70121.rs @@ -0,0 +1,23 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +pub type Successors<'a> = impl Iterator<Item = &'a ()>; + +pub fn f<'a>() -> Successors<'a> { + None.into_iter() +} + +pub trait Tr { + type Item; +} + +impl<'a> Tr for &'a () { + type Item = Successors<'a>; +} + +pub fn kazusa<'a>() -> <&'a () as Tr>::Item { + None.into_iter() +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-72793.rs b/src/test/ui/type-alias-impl-trait/issue-72793.rs new file mode 100644 index 000000000..828c87114 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-72793.rs @@ -0,0 +1,25 @@ +// check-pass +// compile-flags: -Zmir-opt-level=3 + +#![feature(type_alias_impl_trait)] + +trait T { type Item; } + +type Alias<'a> = impl T<Item = &'a ()>; + +struct S; +impl<'a> T for &'a S { + type Item = &'a (); +} + +fn filter_positive<'a>() -> Alias<'a> { + &S +} + +fn with_positive(fun: impl Fn(Alias<'_>)) { + fun(filter_positive()); +} + +fn main() { + with_positive(|_| ()); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-74244.rs b/src/test/ui/type-alias-impl-trait/issue-74244.rs new file mode 100644 index 000000000..bb4104b3d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74244.rs @@ -0,0 +1,20 @@ +#![feature(type_alias_impl_trait)] + +trait Allocator { + type Buffer; +} + +struct DefaultAllocator; + +impl<T> Allocator for DefaultAllocator { + //~^ ERROR: the type parameter `T` is not constrained + type Buffer = (); +} + +type A = impl Fn(<DefaultAllocator as Allocator>::Buffer); + +fn foo() -> A { + |_| () +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-74244.stderr b/src/test/ui/type-alias-impl-trait/issue-74244.stderr new file mode 100644 index 000000000..ff6bacd27 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74244.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-74244.rs:9:6 + | +LL | impl<T> Allocator for DefaultAllocator { + | ^ unconstrained type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/type-alias-impl-trait/issue-74280.rs b/src/test/ui/type-alias-impl-trait/issue-74280.rs new file mode 100644 index 000000000..ad641eaa0 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74280.rs @@ -0,0 +1,12 @@ +// Regression test for #74280. + +#![feature(type_alias_impl_trait)] + +type Test = impl Copy; + +fn test() -> Test { + let y = || -> Test { () }; + 7 //~ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-74280.stderr b/src/test/ui/type-alias-impl-trait/issue-74280.stderr new file mode 100644 index 000000000..5ed29e0ac --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74280.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/issue-74280.rs:9:5 + | +LL | fn test() -> Test { + | ---- expected `_` because of return type +LL | let y = || -> Test { () }; +LL | 7 + | ^ expected `()`, found integer + +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-74761-2.rs b/src/test/ui/type-alias-impl-trait/issue-74761-2.rs new file mode 100644 index 000000000..d26ca5c3e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74761-2.rs @@ -0,0 +1,15 @@ +#![feature(type_alias_impl_trait)] + +pub trait A { + type B; + fn f(&self) -> Self::B; +} +impl<'a, 'b> A for () { + //~^ ERROR the lifetime parameter `'a` is not constrained + //~| ERROR the lifetime parameter `'b` is not constrained + type B = impl core::fmt::Debug; + + fn f(&self) -> Self::B {} +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr b/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr new file mode 100644 index 000000000..f15d0a069 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr @@ -0,0 +1,15 @@ +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-74761-2.rs:7:6 + | +LL | impl<'a, 'b> A for () { + | ^^ unconstrained lifetime parameter + +error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-74761-2.rs:7:10 + | +LL | impl<'a, 'b> A for () { + | ^^ unconstrained lifetime parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/type-alias-impl-trait/issue-74761.rs b/src/test/ui/type-alias-impl-trait/issue-74761.rs new file mode 100644 index 000000000..d26ca5c3e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74761.rs @@ -0,0 +1,15 @@ +#![feature(type_alias_impl_trait)] + +pub trait A { + type B; + fn f(&self) -> Self::B; +} +impl<'a, 'b> A for () { + //~^ ERROR the lifetime parameter `'a` is not constrained + //~| ERROR the lifetime parameter `'b` is not constrained + type B = impl core::fmt::Debug; + + fn f(&self) -> Self::B {} +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-74761.stderr b/src/test/ui/type-alias-impl-trait/issue-74761.stderr new file mode 100644 index 000000000..1d016fe07 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74761.stderr @@ -0,0 +1,15 @@ +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-74761.rs:7:6 + | +LL | impl<'a, 'b> A for () { + | ^^ unconstrained lifetime parameter + +error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-74761.rs:7:10 + | +LL | impl<'a, 'b> A for () { + | ^^ unconstrained lifetime parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs b/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs new file mode 100644 index 000000000..fb56cc54d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs @@ -0,0 +1,24 @@ +// Regression test for issue #76202 +// Tests that we don't ICE when we have a trait impl on a TAIT. + +#![feature(type_alias_impl_trait)] + +trait Dummy {} +impl Dummy for () {} + +type F = impl Dummy; +fn f() -> F {} + +trait Test { + fn test(self); +} + +impl Test for F { + //~^ ERROR cannot implement trait + fn test(self) {} +} + +fn main() { + let x: F = f(); + x.test(); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr b/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr new file mode 100644 index 000000000..2d4a6854a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr @@ -0,0 +1,14 @@ +error: cannot implement trait on type alias impl trait + --> $DIR/issue-76202-trait-impl-for-tait.rs:16:15 + | +LL | impl Test for F { + | ^ + | +note: type alias impl trait defined here + --> $DIR/issue-76202-trait-impl-for-tait.rs:9:10 + | +LL | type F = impl Dummy; + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-77179.rs b/src/test/ui/type-alias-impl-trait/issue-77179.rs new file mode 100644 index 000000000..8d818d4a3 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-77179.rs @@ -0,0 +1,14 @@ +// Regression test for #77179. + +#![feature(type_alias_impl_trait)] + +type Pointer<T> = impl std::ops::Deref<Target=T>; + +fn test() -> Pointer<_> { + //~^ ERROR: the placeholder `_` is not allowed within types + Box::new(1) +} + +fn main() { + test(); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-77179.stderr b/src/test/ui/type-alias-impl-trait/issue-77179.stderr new file mode 100644 index 000000000..053546e4b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-77179.stderr @@ -0,0 +1,12 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/issue-77179.rs:7:22 + | +LL | fn test() -> Pointer<_> { + | --------^- + | | | + | | not allowed in type signatures + | help: replace with the correct return type: `Pointer<i32>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/type-alias-impl-trait/issue-78450.rs b/src/test/ui/type-alias-impl-trait/issue-78450.rs new file mode 100644 index 000000000..fccbfb74f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-78450.rs @@ -0,0 +1,25 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +pub trait AssociatedImpl { + type ImplTrait; + + fn f() -> Self::ImplTrait; +} + +struct S<T>(T); + +trait Associated { + type A; +} + +impl<'a, T: Associated<A = &'a ()>> AssociatedImpl for S<T> { + type ImplTrait = impl core::fmt::Debug; + + fn f() -> Self::ImplTrait { + () + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs b/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs new file mode 100644 index 000000000..fa25d8f76 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs @@ -0,0 +1,23 @@ +// Regression test for issues #84660 and #86411: both are variations on #76202. +// Tests that we don't ICE when we have an opaque type appearing anywhere in an impl header. + +#![feature(type_alias_impl_trait)] + +trait Foo {} +impl Foo for () {} +type Bar = impl Foo; +fn _defining_use() -> Bar {} + +trait TraitArg<T> { + fn f(); +} + +impl TraitArg<Bar> for () { //~ ERROR cannot implement trait + fn f() { + println!("ho"); + } +} + +fn main() { + <() as TraitArg<Bar>>::f(); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.stderr b/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.stderr new file mode 100644 index 000000000..bb70d07be --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.stderr @@ -0,0 +1,14 @@ +error: cannot implement trait on type alias impl trait + --> $DIR/issue-84660-trait-impl-for-tait.rs:15:15 + | +LL | impl TraitArg<Bar> for () { + | ^^^ + | +note: type alias impl trait defined here + --> $DIR/issue-84660-trait-impl-for-tait.rs:8:12 + | +LL | type Bar = impl Foo; + | ^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs new file mode 100644 index 000000000..f12d1b6d9 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs @@ -0,0 +1,41 @@ +// Another example from issue #84660, this time weaponized as a safe transmute: an opaque type in an +// impl header being accepted was used to create unsoundness. + +#![feature(type_alias_impl_trait)] + +trait Foo {} +impl Foo for () {} +type Bar = impl Foo; +fn _defining_use() -> Bar {} + +trait Trait<T, In> { + type Out; + fn convert(i: In) -> Self::Out; +} + +impl<In, Out> Trait<Bar, In> for Out { //~ ERROR cannot implement trait + type Out = Out; + fn convert(_i: In) -> Self::Out { + unreachable!(); + } +} + +impl<In, Out> Trait<(), In> for Out { + type Out = In; + fn convert(i: In) -> Self::Out { + i + } +} + +fn transmute<In, Out>(i: In) -> Out { + <Out as Trait<Bar, In>>::convert(i) +} + +fn main() { + let d; + { + let x = "Hello World".to_string(); + d = transmute::<&String, &String>(&x); + } + println!("{}", d); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr new file mode 100644 index 000000000..f2d600fb4 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr @@ -0,0 +1,14 @@ +error: cannot implement trait on type alias impl trait + --> $DIR/issue-84660-unsoundness.rs:16:21 + | +LL | impl<In, Out> Trait<Bar, In> for Out { + | ^^^ + | +note: type alias impl trait defined here + --> $DIR/issue-84660-unsoundness.rs:8:12 + | +LL | type Bar = impl Foo; + | ^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-87455-static-lifetime-ice.rs b/src/test/ui/type-alias-impl-trait/issue-87455-static-lifetime-ice.rs new file mode 100644 index 000000000..80a74eb63 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-87455-static-lifetime-ice.rs @@ -0,0 +1,73 @@ +// check-pass + +use std::error::Error as StdError; +use std::pin::Pin; +use std::task::{Context, Poll}; + +pub trait Stream { + type Item; + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>; + fn size_hint(&self) -> (usize, Option<usize>) { + (0, None) + } +} + +pub trait TryStream: Stream { + type Ok; + type Error; + + fn try_poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll<Option<Result<Self::Ok, Self::Error>>>; +} + +impl<S, T, E> TryStream for S +where + S: ?Sized + Stream<Item = Result<T, E>>, +{ + type Ok = T; + type Error = E; + + fn try_poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll<Option<Result<Self::Ok, Self::Error>>> { + self.poll_next(cx) + } +} + +pub trait ServerSentEvent: Sized + Send + Sync + 'static {} + +impl<T: Send + Sync + 'static> ServerSentEvent for T {} + +struct SseKeepAlive<S> { + event_stream: S, +} + +struct SseComment<T>(T); + +impl<S> Stream for SseKeepAlive<S> +where + S: TryStream + Send + 'static, + S::Ok: ServerSentEvent, + S::Error: StdError + Send + Sync + 'static, +{ + type Item = Result<SseComment<&'static str>, ()>; + fn poll_next(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Option<Self::Item>> { + unimplemented!() + } +} + +pub fn keep<S>( + event_stream: S, +) -> impl TryStream<Ok = impl ServerSentEvent + Send + 'static, Error = ()> + Send + 'static +where + S: TryStream + Send + 'static, + S::Ok: ServerSentEvent + Send, + S::Error: StdError + Send + Sync + 'static, +{ + SseKeepAlive { event_stream } +} + +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 new file mode 100644 index 000000000..de070fc9d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-89686.rs @@ -0,0 +1,23 @@ +// edition:2018 + +#![feature(type_alias_impl_trait)] + +use std::future::Future; + +type G<'a, T> = impl Future<Output = ()>; + +trait Trait { + type F: Future<Output = ()>; + + fn f(&self) -> Self::F; + + fn g<'a>(&'a self) -> G<'a, Self> + where + Self: Sized, + { + async move { self.f().await } + //~^ ERROR: the trait bound `T: Trait` is not satisfied + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-89686.stderr b/src/test/ui/type-alias-impl-trait/issue-89686.stderr new file mode 100644 index 000000000..b636ada8b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-89686.stderr @@ -0,0 +1,14 @@ +error[E0277]: the trait bound `T: Trait` is not satisfied + --> $DIR/issue-89686.rs:18:9 + | +LL | async move { self.f().await } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` + | +help: consider restricting type parameter `T` + | +LL | type G<'a, T: Trait> = impl Future<Output = ()>; + | +++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/issue-89952.rs b/src/test/ui/type-alias-impl-trait/issue-89952.rs new file mode 100644 index 000000000..dc0f19c04 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-89952.rs @@ -0,0 +1,31 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +trait SomeTrait {} +impl SomeTrait for () {} + +trait MyFuture { + type Output; +} +impl<T> MyFuture for T { + type Output = T; +} + +trait ReturnsFuture { + type Output: SomeTrait; + type Future: MyFuture<Output = Result<Self::Output, ()>>; + fn func() -> Self::Future; +} + +struct Foo; + +impl ReturnsFuture for Foo { + type Output = impl SomeTrait; + type Future = impl MyFuture<Output = Result<Self::Output, ()>>; + fn func() -> Self::Future { + Result::<(), ()>::Err(()) + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-90400-1.rs b/src/test/ui/type-alias-impl-trait/issue-90400-1.rs new file mode 100644 index 000000000..8550a3e86 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-90400-1.rs @@ -0,0 +1,30 @@ +// Regression test for #90400, +// taken from https://github.com/rust-lang/rust/issues/90400#issuecomment-954927836 + +#![feature(generic_associated_types)] +#![feature(type_alias_impl_trait)] + +trait Bar { + fn bar(&self); +} + +trait Foo { + type FooFn<B>: FnOnce(); + + fn foo<B: Bar>(&self, bar: B) -> Self::FooFn<B>; +} + +struct MyFoo; + +impl Foo for MyFoo { + type FooFn<B> = impl FnOnce(); + + fn foo<B: Bar>(&self, bar: B) -> Self::FooFn<B> { + move || bar.bar() //~ ERROR: the trait bound `B: Bar` is not satisfied + } +} + +fn main() { + let boom: <MyFoo as Foo>::FooFn<u32> = unsafe { core::mem::zeroed() }; + boom(); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-90400-1.stderr b/src/test/ui/type-alias-impl-trait/issue-90400-1.stderr new file mode 100644 index 000000000..428a10740 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-90400-1.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `B: Bar` is not satisfied + --> $DIR/issue-90400-1.rs:23:9 + | +LL | move || bar.bar() + | ^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `B` + | +note: required by a bound in `<MyFoo as Foo>::foo` + --> $DIR/issue-90400-1.rs:22:15 + | +LL | fn foo<B: Bar>(&self, bar: B) -> Self::FooFn<B> { + | ^^^ required by this bound in `<MyFoo as Foo>::foo` +help: consider restricting type parameter `B` + | +LL | type FooFn<B: Bar> = impl FnOnce(); + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/issue-90400-2.rs b/src/test/ui/type-alias-impl-trait/issue-90400-2.rs new file mode 100644 index 000000000..2b369bb8a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-90400-2.rs @@ -0,0 +1,38 @@ +// Regression test for #90400, +// taken from https://github.com/rust-lang/rust/issues/90400#issuecomment-954927836 + +#![feature(generic_associated_types)] +#![feature(type_alias_impl_trait)] + +trait Bar { + fn bar(&self); +} + +trait Baz { + fn baz(&self); +} + +trait Foo { + type FooFn<B>: Baz; + + fn foo<B: Bar>(&self, bar: B) -> Self::FooFn<B>; +} + +struct MyFoo; +impl Foo for MyFoo { + type FooFn<B> = impl Baz; + + fn foo<B: Bar>(&self, bar: B) -> Self::FooFn<B> { + MyBaz(bar) //~ ERROR: the trait bound `B: Bar` is not satisfied + } +} + +struct MyBaz<B: Bar>(B); +impl<B: Bar> Baz for MyBaz<B> { + fn baz(&self) {} +} + +fn main() { + let boom: <MyFoo as Foo>::FooFn<u32> = unsafe { core::mem::zeroed() }; + boom.baz(); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-90400-2.stderr b/src/test/ui/type-alias-impl-trait/issue-90400-2.stderr new file mode 100644 index 000000000..5da05a439 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-90400-2.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `B: Bar` is not satisfied + --> $DIR/issue-90400-2.rs:26:9 + | +LL | MyBaz(bar) + | ^^^^^^^^^^ the trait `Bar` is not implemented for `B` + | +note: required because of the requirements on the impl of `Baz` for `MyBaz<B>` + --> $DIR/issue-90400-2.rs:31:14 + | +LL | impl<B: Bar> Baz for MyBaz<B> { + | ^^^ ^^^^^^^^ +help: consider restricting type parameter `B` + | +LL | type FooFn<B: Bar> = impl Baz; + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/issue-93411.rs b/src/test/ui/type-alias-impl-trait/issue-93411.rs new file mode 100644 index 000000000..1f8c78926 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-93411.rs @@ -0,0 +1,19 @@ +#![feature(type_alias_impl_trait)] + +// this test used to stack overflow due to infinite recursion. +// check-pass +// compile-flags: --edition=2018 + +use std::future::Future; + +fn main() { + let _ = move || async move { + let value = 0u8; + blah(&value).await; + }; +} + +type BlahFut<'a> = impl Future<Output = ()> + Send + 'a; +fn blah<'a>(_value: &'a u8) -> BlahFut<'a> { + async {} +} diff --git a/src/test/ui/type-alias-impl-trait/issue-94429.rs b/src/test/ui/type-alias-impl-trait/issue-94429.rs new file mode 100644 index 000000000..2c965b875 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-94429.rs @@ -0,0 +1,23 @@ +#![feature(type_alias_impl_trait, generator_trait, generators)] +use std::ops::Generator; + +trait Runnable { + type Gen: Generator<Yield = (), Return = ()>; + + fn run(&mut self) -> Self::Gen; +} + +struct Implementor {} + +impl Runnable for Implementor { + type Gen = impl Generator<Yield = (), Return = ()>; + + fn run(&mut self) -> Self::Gen { + //~^ ERROR: type mismatch resolving + move || { + yield 1; + } + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-94429.stderr b/src/test/ui/type-alias-impl-trait/issue-94429.stderr new file mode 100644 index 000000000..8d7f7a07b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-94429.stderr @@ -0,0 +1,9 @@ +error[E0271]: type mismatch resolving `<[generator@$DIR/issue-94429.rs:17:9: 17:16] as Generator>::Yield == ()` + --> $DIR/issue-94429.rs:15:26 + | +LL | fn run(&mut self) -> Self::Gen { + | ^^^^^^^^^ expected integer, found `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/type-alias-impl-trait/issue-98604.rs b/src/test/ui/type-alias-impl-trait/issue-98604.rs new file mode 100644 index 000000000..a4fd8a82a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-98604.rs @@ -0,0 +1,13 @@ +// edition:2018 + +type AsyncFnPtr = Box< + dyn Fn() -> std::pin::Pin<Box<dyn std::future::Future<Output = ()>>>, +>; + +async fn test() {} + +#[allow(unused_must_use)] +fn main() { + Box::new(test) as AsyncFnPtr; + //~^ ERROR type mismatch +} diff --git a/src/test/ui/type-alias-impl-trait/issue-98604.stderr b/src/test/ui/type-alias-impl-trait/issue-98604.stderr new file mode 100644 index 000000000..f04d1b4d7 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-98604.stderr @@ -0,0 +1,18 @@ +error[E0271]: type mismatch resolving `<fn() -> impl Future<Output = ()> {test} as FnOnce<()>>::Output == Pin<Box<(dyn Future<Output = ()> + 'static)>>` + --> $DIR/issue-98604.rs:11:5 + | +LL | Box::new(test) as AsyncFnPtr; + | ^^^^^^^^^^^^^^ expected struct `Pin`, found opaque type + | +note: while checking the return type of the `async fn` + --> $DIR/issue-98604.rs:7:17 + | +LL | async fn test() {} + | ^ checked the `Output` of this `async fn`, found opaque type + = note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>` + found opaque type `impl Future<Output = ()>` + = note: required for the cast from `fn() -> impl Future<Output = ()> {test}` to the object type `dyn Fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/type-alias-impl-trait/issue-98608.rs b/src/test/ui/type-alias-impl-trait/issue-98608.rs new file mode 100644 index 000000000..d75762a8b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-98608.rs @@ -0,0 +1,9 @@ +fn hi() -> impl Sized { std::ptr::null::<u8>() } + +fn main() { + let b: Box<dyn Fn() -> Box<u8>> = Box::new(hi); + //~^ ERROR type mismatch resolving `<fn() -> impl Sized {hi} as FnOnce<()>>::Output == Box<u8>` + let boxed = b(); + let null = *boxed; + println!("{null:?}"); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-98608.stderr b/src/test/ui/type-alias-impl-trait/issue-98608.stderr new file mode 100644 index 000000000..8f3ec7d9d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-98608.stderr @@ -0,0 +1,16 @@ +error[E0271]: type mismatch resolving `<fn() -> impl Sized {hi} as FnOnce<()>>::Output == Box<u8>` + --> $DIR/issue-98608.rs:4:39 + | +LL | fn hi() -> impl Sized { std::ptr::null::<u8>() } + | ---------- the found opaque type +... +LL | let b: Box<dyn Fn() -> Box<u8>> = Box::new(hi); + | ^^^^^^^^^^^^ expected struct `Box`, found opaque type + | + = note: expected struct `Box<u8>` + found opaque type `impl Sized` + = note: required for the cast from `fn() -> impl Sized {hi}` to the object type `dyn Fn() -> Box<u8>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs new file mode 100644 index 000000000..b887fcf30 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs @@ -0,0 +1,13 @@ +// https://github.com/rust-lang/rust/issues/73481 +// This test used to cause unsoundness, since one of the two possible +// resolutions was chosen at random instead of erroring due to conflicts. + +#![feature(type_alias_impl_trait)] + +type Y<A, B> = impl std::fmt::Debug; + +fn g<A, B>() -> (Y<A, B>, Y<B, A>) { + (42_i64, 60) //~ ERROR concrete type differs from previous defining opaque type use +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr new file mode 100644 index 000000000..278117009 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr @@ -0,0 +1,11 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/multiple-def-uses-in-one-fn-infer.rs:10:5 + | +LL | (42_i64, 60) + | ^^^^^^^^^^^^ + | | + | expected `i64`, got `i32` + | this expression supplies two conflicting concrete types for the same opaque type + +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 new file mode 100644 index 000000000..3f122f106 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs @@ -0,0 +1,9 @@ +#![feature(type_alias_impl_trait)] + +type Foo<'a, 'b> = impl std::fmt::Debug; + +fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) { + (i, i) //~ ERROR concrete type differs from previous +} + +fn main() {} 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 new file mode 100644 index 000000000..81e603e23 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr @@ -0,0 +1,11 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5 + | +LL | (i, i) + | ^^^^^^ + | | + | expected `&'a i32`, got `&'b i32` + | this expression supplies two conflicting concrete types for the same opaque type + +error: aborting due to previous error + 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 new file mode 100644 index 000000000..83fd9a1da --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs @@ -0,0 +1,21 @@ +// check-pass +#![feature(type_alias_impl_trait)] + +type X<A: ToString + Clone, B: ToString + Clone> = impl ToString; + +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; + +fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) { + (i, j) +} + +fn main() { + println!("{}", <X<_, _> as ToString>::to_string(&f(42_i32, String::new()).1)); + let meh = 42; + let muh = 69; + println!("{:?}", foo(&meh, &muh)); +} diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs new file mode 100644 index 000000000..da845e861 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs @@ -0,0 +1,16 @@ +// https://github.com/rust-lang/rust/issues/73481 +// This test used to cause unsoundness, since one of the two possible +// resolutions was chosen at random instead of erroring due to conflicts. + +#![feature(type_alias_impl_trait)] + +type X<A, B> = impl Into<&'static A>; + +fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) { + //~^ ERROR the trait bound `&'static B: From<&A>` is not satisfied + (a, a) +} + +fn main() { + println!("{}", <X<_, _> as Into<&String>>::into(f(&[1isize, 2, 3], String::new()).1)); +} diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr new file mode 100644 index 000000000..cdaae99e2 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `&'static B: From<&A>` is not satisfied + --> $DIR/multiple-def-uses-in-one-fn.rs:9:45 + | +LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) { + | ^^^^^^^^^^^^^^^^^^ the trait `From<&A>` is not implemented for `&'static B` + | + = note: required because of the requirements on the impl of `Into<&'static B>` for `&A` +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) where &'static B: From<&A> { + | ++++++++++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs new file mode 100644 index 000000000..14510a529 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs @@ -0,0 +1,16 @@ +// https://github.com/rust-lang/rust/issues/73481 +// This test used to cause unsoundness, since one of the two possible +// resolutions was chosen at random instead of erroring due to conflicts. + +#![feature(type_alias_impl_trait)] + +type X<A: ToString + Clone, B: ToString + Clone> = impl ToString; + +fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) { + (a.clone(), a) + //~^ ERROR concrete type differs from previous defining opaque type +} + +fn main() { + println!("{}", <X<_, _> as ToString>::to_string(&f(42_i32, String::new()).1)); +} diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr new file mode 100644 index 000000000..0f752212a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr @@ -0,0 +1,11 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/multiple-def-uses-in-one-fn2.rs:10:5 + | +LL | (a.clone(), a) + | ^^^^^^^^^^^^^^ + | | + | expected `A`, got `B` + | this expression supplies two conflicting concrete types for the same opaque type + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs new file mode 100644 index 000000000..11a922443 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs @@ -0,0 +1,18 @@ +// https://github.com/rust-lang/rust/issues/73481 +// This test used to cause unsoundness, since one of the two possible +// resolutions was chosen at random instead of erroring due to conflicts. + +#![feature(type_alias_impl_trait)] + +type X<A: ToString + Clone, B: ToString + Clone> = impl ToString; + +fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) { + (a, b) +} + +fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) { + (a, b) + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr new file mode 100644 index 000000000..bbe709dcc --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/multiple-def-uses-in-one-fn3.rs:14:9 + | +LL | fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) { + | - - found type parameter + | | + | expected type parameter +LL | (a, b) + | ^ expected type parameter `A`, found type parameter `B` + | + = note: expected type parameter `A` + found type parameter `B` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +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/multiple_definitions.rs b/src/test/ui/type-alias-impl-trait/multiple_definitions.rs new file mode 100644 index 000000000..9e6268e63 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/multiple_definitions.rs @@ -0,0 +1,30 @@ +// check-pass + +use std::marker::PhantomData; + +pub struct ConcreteError {} +pub trait IoBase {} +struct X {} +impl IoBase for X {} + +pub struct ClusterIterator<B, E, S = B> { + pub fat: B, + phantom_s: PhantomData<S>, + phantom_e: PhantomData<E>, +} + +pub struct FileSystem<IO: IoBase> { + pub disk: IO, +} + +impl<IO: IoBase> FileSystem<IO> { + pub fn cluster_iter(&self) -> ClusterIterator<impl IoBase + '_, ConcreteError> { + ClusterIterator { + fat: X {}, + phantom_s: PhantomData::default(), + phantom_e: PhantomData::default(), + } + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs new file mode 100644 index 000000000..822489716 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs @@ -0,0 +1,18 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +use std::fmt::Debug; + +type FooX = impl Debug; + +trait Foo<A> { } + +impl Foo<()> for () { } + +fn foo() -> impl Foo<FooX> { + //~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied + // FIXME(type-alias-impl-trait): We could probably make this work. + () +} + +fn main() { } diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr new file mode 100644 index 000000000..62db019ed --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr @@ -0,0 +1,14 @@ +error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied + --> $DIR/nested-tait-inference.rs:12:13 + | +LL | fn foo() -> impl Foo<FooX> { + | ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()` +... +LL | () + | -- return type was inferred to be `()` here + | + = help: the trait `Foo<()>` is implemented for `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs new file mode 100644 index 000000000..0d7f5bad2 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs @@ -0,0 +1,18 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +use std::fmt::Debug; + +type FooX = impl Debug; + +trait Foo<A> {} + +impl Foo<()> for () {} +impl Foo<u32> for () {} + +fn foo() -> impl Foo<FooX> { + //~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied + () +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr new file mode 100644 index 000000000..f4d96038d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr @@ -0,0 +1,16 @@ +error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied + --> $DIR/nested-tait-inference2.rs:13:13 + | +LL | fn foo() -> impl Foo<FooX> { + | ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()` +LL | +LL | () + | -- return type was inferred to be `()` here + | + = help: the following other types implement trait `Foo<A>`: + <() as Foo<()>> + <() as Foo<u32>> + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs new file mode 100644 index 000000000..ebf3a99bb --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs @@ -0,0 +1,17 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +use std::fmt::Debug; + +type FooX = impl Debug; + +trait Foo<A> { } + +impl Foo<FooX> for () { } +//~^ cannot implement trait on type alias impl trait + +fn foo() -> impl Foo<FooX> { + () +} + +fn main() { } diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr new file mode 100644 index 000000000..4a3fb1673 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr @@ -0,0 +1,14 @@ +error: cannot implement trait on type alias impl trait + --> $DIR/nested-tait-inference3.rs:10:10 + | +LL | impl Foo<FooX> for () { } + | ^^^^ + | +note: type alias impl trait defined here + --> $DIR/nested-tait-inference3.rs:6:13 + | +LL | type FooX = impl Debug; + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/nested.rs b/src/test/ui/type-alias-impl-trait/nested.rs new file mode 100644 index 000000000..6b866be7d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/nested.rs @@ -0,0 +1,17 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl std::fmt::Debug; +type Bar = impl Trait<Foo>; + +trait Trait<T> {} + +impl<T, U> Trait<T> for U {} + +fn bar() -> Bar { + 42 +} + +fn main() { + println!("{:?}", bar()); + //~^ ERROR `Bar` doesn't implement `Debug` +} diff --git a/src/test/ui/type-alias-impl-trait/nested.stderr b/src/test/ui/type-alias-impl-trait/nested.stderr new file mode 100644 index 000000000..732af5c0b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/nested.stderr @@ -0,0 +1,12 @@ +error[E0277]: `Bar` doesn't implement `Debug` + --> $DIR/nested.rs:15:22 + | +LL | println!("{:?}", bar()); + | ^^^^^ `Bar` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = help: the trait `Debug` is not implemented for `Bar` + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs b/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs new file mode 100644 index 000000000..60b6e1aac --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs @@ -0,0 +1,20 @@ +#![feature(type_alias_impl_trait)] + +mod my_mod { + use std::fmt::Debug; + + pub type Foo = impl Debug; + pub type Foot = impl Debug; + + pub fn get_foo() -> Foo { + 5i32 + } + + pub fn get_foot() -> Foot { + get_foo() //~ ERROR opaque type's hidden type cannot be another opaque type + } +} + +fn main() { + let _: my_mod::Foot = my_mod::get_foot(); +} diff --git a/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr b/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr new file mode 100644 index 000000000..fa6ecf68d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr @@ -0,0 +1,19 @@ +error: opaque type's hidden type cannot be another opaque type from the same scope + --> $DIR/nested_type_alias_impl_trait.rs:14:9 + | +LL | get_foo() + | ^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope + | +note: opaque type whose hidden type is being assigned + --> $DIR/nested_type_alias_impl_trait.rs:7:21 + | +LL | pub type Foot = impl Debug; + | ^^^^^^^^^^ +note: opaque type being used as hidden type + --> $DIR/nested_type_alias_impl_trait.rs:6:20 + | +LL | pub type Foo = impl Debug; + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.rs b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.rs new file mode 100644 index 000000000..fed5ac07c --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.rs @@ -0,0 +1,14 @@ +#![feature(type_alias_impl_trait)] +// check-pass +fn main() {} + +type NoReveal = impl std::fmt::Debug; + +fn define_no_reveal() -> NoReveal { + "" +} + +fn no_reveal(x: NoReveal) { + let _: &'static str = x; + let _ = x as &'static str; +} diff --git a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs new file mode 100644 index 000000000..46621362e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs @@ -0,0 +1,19 @@ +// Issue 52985: user code provides no use case that allows a type alias `impl Trait` +// We now emit a 'unconstrained opaque type' error + +#![feature(type_alias_impl_trait)] + +mod foo { + pub type Foo = impl Copy; + //~^ ERROR unconstrained opaque type + + // make compiler happy about using 'Foo' + pub fn bar(x: Foo) -> Foo { + x + } +} + +fn main() { + let _: foo::Foo = std::mem::transmute(0u8); + //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types +} diff --git a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr new file mode 100644 index 000000000..337708b87 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr @@ -0,0 +1,20 @@ +error: unconstrained opaque type + --> $DIR/no_inferrable_concrete_type.rs:7:20 + | +LL | pub type Foo = impl Copy; + | ^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same module + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/no_inferrable_concrete_type.rs:17:23 + | +LL | let _: foo::Foo = std::mem::transmute(0u8); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `u8` (8 bits) + = note: target type: `Foo` (size can vary because of [type error]) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs new file mode 100644 index 000000000..61153b1e1 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs @@ -0,0 +1,24 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +mod boo { + pub type Boo = impl ::std::fmt::Debug; + fn bomp() -> Boo { + "" + } +} + +// We don't actually know the type here. + +fn bomp2() { + let _: &str = bomp(); //~ ERROR mismatched types +} + +fn bomp() -> boo::Boo { + "" //~ ERROR mismatched types +} + +fn bomp_loop() -> boo::Boo { + loop {} +} diff --git a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr new file mode 100644 index 000000000..ae03a5b3e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr @@ -0,0 +1,31 @@ +error[E0308]: mismatched types + --> $DIR/no_revealing_outside_defining_module.rs:15:19 + | +LL | pub type Boo = impl ::std::fmt::Debug; + | ---------------------- the found opaque type +... +LL | let _: &str = bomp(); + | ---- ^^^^^^ expected `&str`, found opaque type + | | + | expected due to this + | + = note: expected reference `&str` + found opaque type `Boo` + +error[E0308]: mismatched types + --> $DIR/no_revealing_outside_defining_module.rs:19:5 + | +LL | pub type Boo = impl ::std::fmt::Debug; + | ---------------------- the expected opaque type +... +LL | fn bomp() -> boo::Boo { + | -------- expected `Boo` because of return type +LL | "" + | ^^ expected opaque type, found `&str` + | + = note: expected opaque type `Boo` + found reference `&'static str` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs new file mode 100644 index 000000000..fa47d13f5 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs @@ -0,0 +1,36 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +type Two<T, U> = impl Debug; + +fn three<T: Debug, U>(t: T) -> Two<T, U> { + (t, 5i8) + //~^ ERROR `T` doesn't implement `Debug` +} + +trait Bar { + type Blub: Debug; + const FOO: Self::Blub; +} + +impl Bar for u32 { + type Blub = i32; + const FOO: i32 = 42; +} + +fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> { + (t, <U as Bar>::FOO) + //~^ ERROR `U: Bar` is not satisfied + //~| ERROR `T` doesn't implement `Debug` +} + +fn is_sync<T: Sync>() {} + +fn asdfl() { + //FIXME(oli-obk): these currently cause cycle errors + //is_sync::<Two<i32, u32>>(); + //is_sync::<Two<i32, *const i32>>(); +} diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr new file mode 100644 index 000000000..a5ac38c38 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr @@ -0,0 +1,38 @@ +error[E0277]: `T` doesn't implement `Debug` + --> $DIR/not_a_defining_use.rs:10:5 + | +LL | (t, 5i8) + | ^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(T, i8)` +help: consider restricting type parameter `T` + | +LL | type Two<T: std::fmt::Debug, U> = impl Debug; + | +++++++++++++++++ + +error[E0277]: the trait bound `U: Bar` is not satisfied + --> $DIR/not_a_defining_use.rs:25:5 + | +LL | (t, <U as Bar>::FOO) + | ^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `U` + | +help: consider restricting type parameter `U` + | +LL | type Two<T, U: Bar> = impl Debug; + | +++++ + +error[E0277]: `T` doesn't implement `Debug` + --> $DIR/not_a_defining_use.rs:25:5 + | +LL | (t, <U as Bar>::FOO) + | ^^^^^^^^^^^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(T, _)` +help: consider restricting type parameter `T` + | +LL | type Two<T: std::fmt::Debug, U> = impl Debug; + | +++++++++++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/not_well_formed.rs b/src/test/ui/type-alias-impl-trait/not_well_formed.rs new file mode 100644 index 000000000..fbb7a4d58 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/not_well_formed.rs @@ -0,0 +1,17 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +trait TraitWithAssoc { + type Assoc; +} + +type Foo<V> = impl Trait<V::Assoc>; //~ associated type `Assoc` not found for `V` + +trait Trait<U> {} + +impl<W> Trait<W> for () {} + +fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T> { + () +} diff --git a/src/test/ui/type-alias-impl-trait/not_well_formed.stderr b/src/test/ui/type-alias-impl-trait/not_well_formed.stderr new file mode 100644 index 000000000..c36b95f47 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/not_well_formed.stderr @@ -0,0 +1,9 @@ +error[E0220]: associated type `Assoc` not found for `V` + --> $DIR/not_well_formed.rs:9:29 + | +LL | type Foo<V> = impl Trait<V::Assoc>; + | ^^^^^ there is a similarly named associated type `Assoc` in the trait `TraitWithAssoc` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0220`. diff --git a/src/test/ui/type-alias-impl-trait/reveal_local.rs b/src/test/ui/type-alias-impl-trait/reveal_local.rs new file mode 100644 index 000000000..7ecb55353 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/reveal_local.rs @@ -0,0 +1,25 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +type Foo = impl Debug; +//~^ ERROR cycle detected + +fn is_send<T: Send>() { } + +fn not_good() { + // Error: this function does not constrain `Foo` to any particular + // hidden type, so it cannot rely on `Send` being true. + is_send::<Foo>(); +} + +fn not_gooder() { + // Constrain `Foo = u32` + let x: Foo = 22_u32; + + // while we could know this from the hidden type, it would + // need extra roundabout logic to support it. + is_send::<Foo>(); +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/reveal_local.stderr b/src/test/ui/type-alias-impl-trait/reveal_local.stderr new file mode 100644 index 000000000..27fded333 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/reveal_local.stderr @@ -0,0 +1,28 @@ +error[E0391]: cycle detected when computing type of `Foo::{opaque#0}` + --> $DIR/reveal_local.rs:5:12 + | +LL | type Foo = impl Debug; + | ^^^^^^^^^^ + | +note: ...which requires type-checking `not_good`... + --> $DIR/reveal_local.rs:13:5 + | +LL | is_send::<Foo>(); + | ^^^^^^^^^^^^^^ + = note: ...which requires evaluating trait selection obligation `Foo: core::marker::Send`... + = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/reveal_local.rs:1:1 + | +LL | / #![feature(type_alias_impl_trait)] +LL | | +LL | | use std::fmt::Debug; +LL | | +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/type-alias-impl-trait/self-referential-2.rs b/src/test/ui/type-alias-impl-trait/self-referential-2.rs new file mode 100644 index 000000000..8781196c3 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/self-referential-2.rs @@ -0,0 +1,10 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl std::fmt::Debug; +type Bar = impl PartialEq<Foo>; + +fn bar() -> Bar { + 42_i32 //~^ ERROR can't compare `i32` with `Foo` +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/self-referential-2.stderr b/src/test/ui/type-alias-impl-trait/self-referential-2.stderr new file mode 100644 index 000000000..2b505d307 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/self-referential-2.stderr @@ -0,0 +1,23 @@ +error[E0277]: can't compare `i32` with `Foo` + --> $DIR/self-referential-2.rs:6:13 + | +LL | fn bar() -> Bar { + | ^^^ no implementation for `i32 == Foo` +LL | 42_i32 + | ------ return type was inferred to be `i32` here + | + = help: the trait `PartialEq<Foo>` is not implemented for `i32` + = help: the following other types implement trait `PartialEq<Rhs>`: + f32 + f64 + i128 + i16 + i32 + i64 + i8 + isize + and 6 others + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/self-referential-3.rs b/src/test/ui/type-alias-impl-trait/self-referential-3.rs new file mode 100644 index 000000000..d40715717 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/self-referential-3.rs @@ -0,0 +1,14 @@ +// run-pass +#![feature(type_alias_impl_trait)] + +type Bar<'a, 'b> = impl PartialEq<Bar<'a, 'b>> + std::fmt::Debug; + +fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { + i +} + +fn main() { + let meh = 42; + let muh = 42; + assert_eq!(bar(&meh), bar(&muh)); +} diff --git a/src/test/ui/type-alias-impl-trait/self-referential-4.rs b/src/test/ui/type-alias-impl-trait/self-referential-4.rs new file mode 100644 index 000000000..36742c8ad --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/self-referential-4.rs @@ -0,0 +1,25 @@ +#![feature(type_alias_impl_trait)] + +type Bar<'a, 'b> = impl PartialEq<Bar<'b, 'static>> + std::fmt::Debug; + +fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { + i //~^ ERROR can't compare `&i32` with `Bar<'b, 'static>` +} + +type Foo<'a, 'b> = impl PartialEq<Foo<'static, 'b>> + std::fmt::Debug; + +fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> { + i //~^ ERROR can't compare `&i32` with `Foo<'static, 'b>` +} + +type Moo<'a, 'b> = impl PartialEq<Moo<'static, 'a>> + std::fmt::Debug; + +fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> { + i //~^ ERROR can't compare `&i32` with `Moo<'static, 'a>` +} + +fn main() { + let meh = 42; + let muh = 69; + assert_eq!(bar(&meh), bar(&meh)); +} diff --git a/src/test/ui/type-alias-impl-trait/self-referential-4.stderr b/src/test/ui/type-alias-impl-trait/self-referential-4.stderr new file mode 100644 index 000000000..27880f792 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/self-referential-4.stderr @@ -0,0 +1,63 @@ +error[E0277]: can't compare `&i32` with `Bar<'b, 'static>` + --> $DIR/self-referential-4.rs:5:31 + | +LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { + | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'b, 'static>` +LL | i + | - return type was inferred to be `&i32` here + | + = help: the trait `PartialEq<Bar<'b, 'static>>` is not implemented for `&i32` + = help: the following other types implement trait `PartialEq<Rhs>`: + f32 + f64 + i128 + i16 + i32 + i64 + i8 + isize + and 6 others + +error[E0277]: can't compare `&i32` with `Foo<'static, 'b>` + --> $DIR/self-referential-4.rs:11:31 + | +LL | fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> { + | ^^^^^^^^^^^ no implementation for `&i32 == Foo<'static, 'b>` +LL | i + | - return type was inferred to be `&i32` here + | + = help: the trait `PartialEq<Foo<'static, 'b>>` is not implemented for `&i32` + = help: the following other types implement trait `PartialEq<Rhs>`: + f32 + f64 + i128 + i16 + i32 + i64 + i8 + isize + and 6 others + +error[E0277]: can't compare `&i32` with `Moo<'static, 'a>` + --> $DIR/self-referential-4.rs:17:31 + | +LL | fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> { + | ^^^^^^^^^^^ no implementation for `&i32 == Moo<'static, 'a>` +LL | i + | - return type was inferred to be `&i32` here + | + = help: the trait `PartialEq<Moo<'static, 'a>>` is not implemented for `&i32` + = help: the following other types implement trait `PartialEq<Rhs>`: + f32 + f64 + i128 + i16 + i32 + i64 + i8 + isize + and 6 others + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/self-referential.rs b/src/test/ui/type-alias-impl-trait/self-referential.rs new file mode 100644 index 000000000..3ff5406a3 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/self-referential.rs @@ -0,0 +1,28 @@ +#![feature(type_alias_impl_trait)] + +type Bar<'a, 'b> = impl PartialEq<Bar<'b, 'a>> + std::fmt::Debug; + +fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { + //~^ ERROR can't compare `&i32` with `Bar<'b, 'a>` + i +} + +type Foo<'a, 'b> = (i32, impl PartialEq<Foo<'a, 'b>> + std::fmt::Debug); + +fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> { + //~^ ERROR can't compare `&i32` with `(i32, &i32)` + (42, i) +} + +type Moo<'a, 'b> = (i32, impl PartialEq<Moo<'b, 'a>> + std::fmt::Debug); + +fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> { + //~^ ERROR can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0})` + (42, i) +} + +fn main() { + let meh = 42; + let muh = 69; + assert_eq!(bar(&meh), bar(&meh)); +} diff --git a/src/test/ui/type-alias-impl-trait/self-referential.stderr b/src/test/ui/type-alias-impl-trait/self-referential.stderr new file mode 100644 index 000000000..97d510f68 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/self-referential.stderr @@ -0,0 +1,66 @@ +error[E0277]: can't compare `&i32` with `Bar<'b, 'a>` + --> $DIR/self-referential.rs:5:31 + | +LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { + | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'b, 'a>` +LL | +LL | i + | - return type was inferred to be `&i32` here + | + = help: the trait `PartialEq<Bar<'b, 'a>>` is not implemented for `&i32` + = help: the following other types implement trait `PartialEq<Rhs>`: + f32 + f64 + i128 + i16 + i32 + i64 + i8 + isize + and 6 others + +error[E0277]: can't compare `&i32` with `(i32, &i32)` + --> $DIR/self-referential.rs:12:31 + | +LL | fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> { + | ^^^^^^^^^^^ no implementation for `&i32 == (i32, &i32)` +LL | +LL | (42, i) + | ------- return type was inferred to be `(i32, &i32)` here + | + = help: the trait `PartialEq<(i32, &i32)>` is not implemented for `&i32` + = help: the following other types implement trait `PartialEq<Rhs>`: + f32 + f64 + i128 + i16 + i32 + i64 + i8 + isize + and 6 others + +error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0})` + --> $DIR/self-referential.rs:19:31 + | +LL | fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> { + | ^^^^^^^^^^^ no implementation for `&i32 == (i32, Moo<'b, 'a>::{opaque#0})` +LL | +LL | (42, i) + | ------- return type was inferred to be `(i32, &i32)` here + | + = help: the trait `PartialEq<(i32, Moo<'b, 'a>::{opaque#0})>` is not implemented for `&i32` + = help: the following other types implement trait `PartialEq<Rhs>`: + f32 + f64 + i128 + i16 + i32 + i64 + i8 + isize + and 6 others + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/static-const-types.rs b/src/test/ui/type-alias-impl-trait/static-const-types.rs new file mode 100644 index 000000000..748a279e4 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/static-const-types.rs @@ -0,0 +1,13 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +// check-pass + +use std::fmt::Debug; + +type Foo = impl Debug; + +static FOO1: Foo = 22_u32; +const FOO2: Foo = 22_u32; + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs new file mode 100644 index 000000000..c2ab6a9d1 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs @@ -0,0 +1,20 @@ +#![feature(type_alias_impl_trait)] + +type Bar = impl Send; + +// While i32 is structural-match, we do not want to leak this information. +// (See https://github.com/rust-lang/rust/issues/72156) +const fn leak_free() -> Bar { + 7i32 +} +const LEAK_FREE: Bar = leak_free(); + +fn leak_free_test() { + match LEAK_FREE { + LEAK_FREE => (), + //~^ `Bar` cannot be used in patterns + _ => (), + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr new file mode 100644 index 000000000..dbc183f54 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr @@ -0,0 +1,8 @@ +error: `Bar` cannot be used in patterns + --> $DIR/structural-match-no-leak.rs:14:9 + | +LL | LEAK_FREE => (), + | ^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/structural-match.rs b/src/test/ui/type-alias-impl-trait/structural-match.rs new file mode 100644 index 000000000..7cc9ccaab --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/structural-match.rs @@ -0,0 +1,21 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl Send; + +// This is not structural-match +struct A; + +const fn value() -> Foo { + A +} +const VALUE: Foo = value(); + +fn test() { + match VALUE { + VALUE => (), + //~^ `Foo` cannot be used in patterns + _ => (), + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/structural-match.stderr b/src/test/ui/type-alias-impl-trait/structural-match.stderr new file mode 100644 index 000000000..61287f268 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/structural-match.stderr @@ -0,0 +1,8 @@ +error: `Foo` cannot be used in patterns + --> $DIR/structural-match.rs:15:9 + | +LL | VALUE => (), + | ^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs new file mode 100644 index 000000000..f6a830296 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs @@ -0,0 +1,12 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +type Foo = Box<dyn Iterator<Item = impl Send>>; + +fn make_foo() -> Foo { + Box::new(vec![1, 2, 3].into_iter()) +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs new file mode 100644 index 000000000..fddecfcac --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs @@ -0,0 +1,19 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +type Foo = impl Iterator<Item = impl Send>; + +fn make_foo() -> Foo { + vec![1, 2].into_iter() +} + +type Bar = impl Send; +type Baz = impl Iterator<Item = Bar>; + +fn make_baz() -> Baz { + vec!["1", "2"].into_iter() +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs new file mode 100644 index 000000000..5630e036b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs @@ -0,0 +1,11 @@ +#![feature(type_alias_impl_trait)] +// check-pass +// Ensures that `const` items can constrain an opaque `impl Trait`. + +use std::fmt::Debug; + +pub type Foo = impl Debug; + +const _FOO: Foo = 5; + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs new file mode 100644 index 000000000..857066c78 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs @@ -0,0 +1,13 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +// FIXME: this is ruled out for now but should work + +type Foo = fn() -> impl Send; +//~^ ERROR: `impl Trait` only allowed in function and inherent method return types + +fn make_foo() -> Foo { + || 15 +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr new file mode 100644 index 000000000..a31cf1a51 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr @@ -0,0 +1,9 @@ +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return + --> $DIR/type-alias-impl-trait-fn-type.rs:6:20 + | +LL | type Foo = fn() -> impl Send; + | ^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0562`. diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs new file mode 100644 index 000000000..07c891f06 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs @@ -0,0 +1,26 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +// Regression test for issue #61863 + +pub trait MyTrait {} + +#[derive(Debug)] +pub struct MyStruct { + v: u64, +} + +impl MyTrait for MyStruct {} + +pub fn bla() -> TE { + return MyStruct { v: 1 }; +} + +pub fn bla2() -> TE { + bla() +} + +type TE = impl MyTrait; + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs new file mode 100644 index 000000000..c5e8068e5 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs @@ -0,0 +1,25 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +type A = impl Sized; +fn f1() -> A { + 0 +} + +type B = impl ?Sized; +fn f2() -> &'static B { + &[0] +} + +type C = impl ?Sized + 'static; +fn f3() -> &'static C { + &[0] +} + +type D = impl ?Sized; +fn f4() -> &'static D { + &1 +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs new file mode 100644 index 000000000..1a4064055 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs @@ -0,0 +1,12 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +type Foo = Vec<impl Send>; + +fn make_foo() -> Foo { + vec![true, false] +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs new file mode 100644 index 000000000..1f2d0e47e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs @@ -0,0 +1,30 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +pub trait MyTrait {} + +impl MyTrait for bool {} + +type Foo = impl MyTrait; + +struct Blah { + my_foo: Foo, + my_u8: u8, +} + +impl Blah { + fn new() -> Blah { + Blah { my_foo: make_foo(), my_u8: 12 } + } + fn into_inner(self) -> (Foo, u8, Foo) { + (self.my_foo, self.my_u8, make_foo()) + } +} + +fn make_foo() -> Foo { + true +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs new file mode 100644 index 000000000..efbf4f1e3 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs @@ -0,0 +1,18 @@ +// regression test for #74018 + +#![feature(type_alias_impl_trait)] + +trait Trait { + type Associated; + fn into(self) -> Self::Associated; +} + +impl<'a, I: Iterator<Item = i32>> Trait for (i32, I) { + //~^ ERROR the lifetime parameter `'a` is not constrained + type Associated = (i32, impl Iterator<Item = i32>); + fn into(self) -> Self::Associated { + (0_i32, [0_i32].iter().copied()) + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr new file mode 100644 index 000000000..8cdce2f8e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr @@ -0,0 +1,9 @@ +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/type-alias-impl-trait-unconstrained-lifetime.rs:10:6 + | +LL | impl<'a, I: Iterator<Item = i32>> Trait for (i32, I) { + | ^^ unconstrained lifetime parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs new file mode 100644 index 000000000..e5e7fb677 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs @@ -0,0 +1,12 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl Fn() -> Foo; +//~^ ERROR: unconstrained opaque type + +fn crash(x: Foo) -> Foo { + x +} + +fn main() { + +} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr new file mode 100644 index 000000000..a770eeac3 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr @@ -0,0 +1,10 @@ +error: unconstrained opaque type + --> $DIR/type-alias-impl-trait-with-cycle-error.rs:3:12 + | +LL | type Foo = impl Fn() -> Foo; + | ^^^^^^^^^^^^^^^^ + | + = note: `Foo` 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/type-alias-impl-trait-with-cycle-error2.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs new file mode 100644 index 000000000..7c7a1b405 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs @@ -0,0 +1,14 @@ +#![feature(type_alias_impl_trait)] + +pub trait Bar<T> { + type Item; +} + +type Foo = impl Bar<Foo, Item = Foo>; +//~^ ERROR: unconstrained opaque type + +fn crash(x: Foo) -> Foo { + x +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr new file mode 100644 index 000000000..3f3699ce5 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr @@ -0,0 +1,10 @@ +error: unconstrained opaque type + --> $DIR/type-alias-impl-trait-with-cycle-error2.rs:7:12 + | +LL | type Foo = impl Bar<Foo, Item = Foo>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Foo` 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/type-alias-impl-trait-with-no-traits.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs new file mode 100644 index 000000000..8ca279eec --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs @@ -0,0 +1,14 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl 'static; +//~^ ERROR: at least one trait must be specified + +fn foo() -> Foo { + "foo" +} + +fn bar() -> impl 'static { //~ ERROR: at least one trait must be specified + "foo" +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr new file mode 100644 index 000000000..3f7acd338 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr @@ -0,0 +1,14 @@ +error: at least one trait must be specified + --> $DIR/type-alias-impl-trait-with-no-traits.rs:3:12 + | +LL | type Foo = impl 'static; + | ^^^^^^^^^^^^ + +error: at least one trait must be specified + --> $DIR/type-alias-impl-trait-with-no-traits.rs:10:13 + | +LL | fn bar() -> impl 'static { + | ^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs new file mode 100644 index 000000000..70c2ee427 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs @@ -0,0 +1,79 @@ +// check-pass + +#![allow(dead_code)] +#![allow(unused_assignments)] +#![allow(unused_variables)] +#![feature(type_alias_impl_trait)] + +fn main() { + assert_eq!(foo().to_string(), "foo"); + assert_eq!(bar1().to_string(), "bar1"); + assert_eq!(bar2().to_string(), "bar2"); + let mut x = bar1(); + x = bar2(); + assert_eq!(my_iter(42u8).collect::<Vec<u8>>(), vec![42u8]); +} + +// single definition +type Foo = impl std::fmt::Display; + +fn foo() -> Foo { + "foo" +} + +// two definitions +type Bar = impl std::fmt::Display; + +fn bar1() -> Bar { + "bar1" +} + +fn bar2() -> Bar { + "bar2" +} + +type MyIter<T> = impl Iterator<Item = T>; + +fn my_iter<T>(t: T) -> MyIter<T> { + std::iter::once(t) +} + +fn my_iter2<T>(t: T) -> MyIter<T> { + std::iter::once(t) +} + +// param names should not have an effect! +fn my_iter3<U>(u: U) -> MyIter<U> { + std::iter::once(u) +} + +// param position should not have an effect! +fn my_iter4<U, V>(_: U, v: V) -> MyIter<V> { + std::iter::once(v) +} + +// param names should not have an effect! +type MyOtherIter<T> = impl Iterator<Item = T>; + +fn my_other_iter<U>(u: U) -> MyOtherIter<U> { + std::iter::once(u) +} + +trait Trait {} +type GenericBound<'a, T: Trait + 'a> = impl Sized + 'a; + +fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> { + t +} + +mod pass_through { + pub type Passthrough<T: 'static> = impl Sized + 'static; + + fn define_passthrough<T: 'static>(t: T) -> Passthrough<T> { + t + } +} + +fn use_passthrough(x: pass_through::Passthrough<u32>) -> pass_through::Passthrough<u32> { + x +} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait2.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait2.rs new file mode 100644 index 000000000..67f56bcde --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait2.rs @@ -0,0 +1,84 @@ +// check-pass + +#![allow(dead_code)] +#![allow(unused_assignments)] +#![allow(unused_variables)] +#![feature(type_alias_impl_trait)] + +fn main() { + assert_eq!(foo().to_string(), "foo"); + assert_eq!(bar1().to_string(), "bar1"); + assert_eq!(bar2().to_string(), "bar2"); + let mut x = bar1(); + x = bar2(); + assert_eq!(my_iter(42u8).collect::<Vec<u8>>(), vec![42u8]); +} + +use defining_use_scope::*; + +mod defining_use_scope { + // single definition + pub type Foo = impl std::fmt::Display; + + pub fn foo() -> Foo { + "foo" + } + + // two definitions + pub type Bar = impl std::fmt::Display; + + pub fn bar1() -> Bar { + "bar1" + } + + pub fn bar2() -> Bar { + "bar2" + } + + pub type MyIter<T> = impl Iterator<Item = T>; + + pub fn my_iter<T>(t: T) -> MyIter<T> { + std::iter::once(t) + } + + fn my_iter2<T>(t: T) -> MyIter<T> { + std::iter::once(t) + } + + // param names should not have an effect! + fn my_iter3<U>(u: U) -> MyIter<U> { + std::iter::once(u) + } + + // param position should not have an effect! + fn my_iter4<U, V>(_: U, v: V) -> MyIter<V> { + std::iter::once(v) + } + + // param names should not have an effect! + type MyOtherIter<T> = impl Iterator<Item = T>; + + fn my_other_iter<U>(u: U) -> MyOtherIter<U> { + std::iter::once(u) + } + + trait Trait {} + type GenericBound<'a, T: Trait + 'a> = impl Sized + 'a; + + fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> { + t + } + + mod pass_through { + pub type Passthrough<T: 'static> = impl Sized + 'static; + + fn define_passthrough<T: 'static>(t: T) -> Passthrough<T> { + t + } + } + + fn use_passthrough(x: pass_through::Passthrough<u32>) -> pass_through::Passthrough<u32> { + x + } + +} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs b/src/test/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs new file mode 100644 index 000000000..fd954801d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs @@ -0,0 +1,14 @@ +// run-pass + +#![feature(type_alias_impl_trait)] + +use std::iter::{once, Chain}; + +type I<A> = Chain<A, impl Iterator<Item = &'static str>>; +fn test2<A: Iterator<Item = &'static str>>(x: A) -> I<A> { + x.chain(once("5")) +} + +fn main() { + assert_eq!(vec!["1", "3", "5"], test2(["1", "3"].iter().cloned()).collect::<Vec<_>>()); +} diff --git a/src/test/ui/type-alias-impl-trait/type_of_a_let.rs b/src/test/ui/type-alias-impl-trait/type_of_a_let.rs new file mode 100644 index 000000000..4e9d1788b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type_of_a_let.rs @@ -0,0 +1,22 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +use std::fmt::Debug; + +type Foo = impl Debug; + +fn foo1() -> u32 { + let x: Foo = 22_u32; + x +} + +fn foo2() -> u32 { + let x: Foo = 22_u32; + let y: Foo = x; + same_type((x, y)); //~ ERROR use of moved value + y //~ ERROR use of moved value +} + +fn same_type<T>(x: (T, T)) {} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type_of_a_let.stderr b/src/test/ui/type-alias-impl-trait/type_of_a_let.stderr new file mode 100644 index 000000000..1dabe4586 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type_of_a_let.stderr @@ -0,0 +1,23 @@ +error[E0382]: use of moved value: `x` + --> $DIR/type_of_a_let.rs:16:16 + | +LL | let x: Foo = 22_u32; + | - move occurs because `x` has type `Foo`, which does not implement the `Copy` trait +LL | let y: Foo = x; + | - value moved here +LL | same_type((x, y)); + | ^ value used here after move + +error[E0382]: use of moved value: `y` + --> $DIR/type_of_a_let.rs:17:5 + | +LL | let y: Foo = x; + | - move occurs because `y` has type `Foo`, which does not implement the `Copy` trait +LL | same_type((x, y)); + | - value moved here +LL | y + | ^ value used here after move + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/type-alias-impl-trait/underconstrained_generic.rs b/src/test/ui/type-alias-impl-trait/underconstrained_generic.rs new file mode 100644 index 000000000..aa537dfc9 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/underconstrained_generic.rs @@ -0,0 +1,28 @@ +#![feature(type_alias_impl_trait)] + +use std::marker::PhantomData; + +trait Trait { + fn foo<T, U>(t: T) -> U; +} + +trait ProofForConversion<X> { + fn convert<T, U>(_: PhantomData<Self>, r: T) -> U; +} + +impl<X: Trait> ProofForConversion<X> for () { + fn convert<T, U>(_: PhantomData<Self>, r: T) -> U { + X::foo(r) + } +} + +type Converter<T> = impl ProofForConversion<T>; + +fn _defining_use<T: Trait>() -> Converter<T> { + () + //~^ ERROR the trait bound `T: Trait` is not satisfied +} + + +fn main() { +} diff --git a/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr b/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr new file mode 100644 index 000000000..e70916573 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `T: Trait` is not satisfied + --> $DIR/underconstrained_generic.rs:22:5 + | +LL | () + | ^^ the trait `Trait` is not implemented for `T` + | +note: required because of the requirements on the impl of `ProofForConversion<T>` for `()` + --> $DIR/underconstrained_generic.rs:13:16 + | +LL | impl<X: Trait> ProofForConversion<X> for () { + | ^^^^^^^^^^^^^^^^^^^^^ ^^ +help: consider restricting type parameter `T` + | +LL | type Converter<T: Trait> = impl ProofForConversion<T>; + | +++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.rs b/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.rs new file mode 100644 index 000000000..c5b2e8a1c --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.rs @@ -0,0 +1,34 @@ +#![feature(type_alias_impl_trait)] + +use std::marker::PhantomData; + +trait ProofForConversion<'a, 'b> { + fn convert<T: ?Sized>(_: PhantomData<Self>, r: &'a T) -> &'b T; +} + +impl<'a, 'b> ProofForConversion<'a, 'b> for &'b &'a () { + fn convert<T: ?Sized>(_: PhantomData<Self>, r: &'a T) -> &'b T { + r + } +} + +type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>; +//~^ ERROR reference has a longer lifetime than the data it references + +// Even _defining_use with an explicit `'a: 'b` compiles fine, too. +fn _defining_use<'a, 'b>(x: &'b &'a ()) -> Converter<'a, 'b> { + x +} + +fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T { + Converter::<'a, 'b>::convert(PhantomData, x) +} + +fn main() { + let d; + { + let x = "Hello World".to_string(); + d = extend_lifetime(&x); + } + println!("{}", d); +} diff --git a/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.stderr b/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.stderr new file mode 100644 index 000000000..12d85a49d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.stderr @@ -0,0 +1,20 @@ +error[E0491]: in type `&'b &'a ()`, reference has a longer lifetime than the data it references + --> $DIR/underconstrained_lifetime.rs:15:26 + | +LL | type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the pointer is valid for the lifetime `'b` as defined here + --> $DIR/underconstrained_lifetime.rs:15:20 + | +LL | type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>; + | ^^ +note: but the referenced data is only valid for the lifetime `'a` as defined here + --> $DIR/underconstrained_lifetime.rs:15:16 + | +LL | type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>; + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0491`. diff --git a/src/test/ui/type-alias-impl-trait/unused_generic_param.rs b/src/test/ui/type-alias-impl-trait/unused_generic_param.rs new file mode 100644 index 000000000..ad5e4918c --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/unused_generic_param.rs @@ -0,0 +1,22 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +fn main() {} + +type PartiallyDefined<T> = impl Sized; + +fn partially_defined<T: std::fmt::Debug>(_: T) -> PartiallyDefined<T> { + 4u32 +} + +type PartiallyDefined2<T> = impl Sized; + +fn partially_defined2<T: std::fmt::Debug>(_: T) -> PartiallyDefined2<T> { + 4u32 +} + +fn partially_defined22<T>(_: T) -> PartiallyDefined2<T> { + 4u32 +} diff --git a/src/test/ui/type-alias-impl-trait/weird-return-types.rs b/src/test/ui/type-alias-impl-trait/weird-return-types.rs new file mode 100644 index 000000000..faad5ee95 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/weird-return-types.rs @@ -0,0 +1,16 @@ +// edition:2018 +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +use std::future::Future; +use std::fmt::Debug; + +type Foo = impl Debug; + +fn f() -> impl Future<Output = Foo> { + async move { 22_u32 } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/wf-check-fn-def.rs b/src/test/ui/type-alias-impl-trait/wf-check-fn-def.rs new file mode 100644 index 000000000..449e9fbd0 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/wf-check-fn-def.rs @@ -0,0 +1,18 @@ +#![feature(type_alias_impl_trait)] + +trait Bar { + fn bar(&self); +} + +type FooFn<B> = impl FnOnce(B); + +fn foo<B: Bar>() -> FooFn<B> { + fn mop<B: Bar>(bar: B) { bar.bar() } + mop // NOTE: no function pointer, but function zst item + //~^ ERROR the trait bound `B: Bar` is not satisfied +} + +fn main() { + let boom: FooFn<u32> = unsafe { core::mem::zeroed() }; + boom(42); +} diff --git a/src/test/ui/type-alias-impl-trait/wf-check-fn-def.stderr b/src/test/ui/type-alias-impl-trait/wf-check-fn-def.stderr new file mode 100644 index 000000000..e0005489d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/wf-check-fn-def.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `B: Bar` is not satisfied + --> $DIR/wf-check-fn-def.rs:11:5 + | +LL | mop // NOTE: no function pointer, but function zst item + | ^^^ the trait `Bar` is not implemented for `B` + | +note: required by a bound in `mop` + --> $DIR/wf-check-fn-def.rs:10:15 + | +LL | fn mop<B: Bar>(bar: B) { bar.bar() } + | ^^^ required by this bound in `mop` +help: consider restricting type parameter `B` + | +LL | type FooFn<B: Bar> = impl FnOnce(B); + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs b/src/test/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs new file mode 100644 index 000000000..3b8470e4a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs @@ -0,0 +1,23 @@ +#![feature(type_alias_impl_trait)] + +// build-pass + +trait Bar { + fn bar(&self); +} + +type FooFn<B> = impl FnOnce(B); + +fn foo<B: Bar>() -> FooFn<B> { + fn mop<B: Bar>(bar: B) { bar.bar() } + mop as fn(B) + // function pointers don't have any obligations on them, + // thus the above compiles. It's obviously unsound to just + // procure a `FooFn` from the ether without making sure that + // the pointer is actually legal for all `B` +} + +fn main() { + let boom: FooFn<u32> = unsafe { core::mem::zeroed() }; + boom(42); +} diff --git a/src/test/ui/type-alias-impl-trait/wf_check_closures.rs b/src/test/ui/type-alias-impl-trait/wf_check_closures.rs new file mode 100644 index 000000000..2c70696ff --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/wf_check_closures.rs @@ -0,0 +1,17 @@ +#![feature(type_alias_impl_trait)] + +trait Bar { + fn bar(&self); +} + +type FooFn<B> = impl FnOnce(); + +fn foo<B: Bar>(bar: B) -> FooFn<B> { + move || { bar.bar() } + //~^ ERROR the trait bound `B: Bar` is not satisfied +} + +fn main() { + let boom: FooFn<u32> = unsafe { core::mem::zeroed() }; + boom(); +} diff --git a/src/test/ui/type-alias-impl-trait/wf_check_closures.stderr b/src/test/ui/type-alias-impl-trait/wf_check_closures.stderr new file mode 100644 index 000000000..58ae8617b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/wf_check_closures.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `B: Bar` is not satisfied + --> $DIR/wf_check_closures.rs:10:5 + | +LL | move || { bar.bar() } + | ^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `B` + | +note: required by a bound in `foo` + --> $DIR/wf_check_closures.rs:9:11 + | +LL | fn foo<B: Bar>(bar: B) -> FooFn<B> { + | ^^^ required by this bound in `foo` +help: consider restricting type parameter `B` + | +LL | type FooFn<B: Bar> = impl FnOnce(); + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias/issue-14933.rs b/src/test/ui/type-alias/issue-14933.rs new file mode 100644 index 000000000..bd95332ca --- /dev/null +++ b/src/test/ui/type-alias/issue-14933.rs @@ -0,0 +1,6 @@ +// check-pass +// pretty-expanded FIXME #23616 + +pub type BigRat<T = isize> = T; + +fn main() {} diff --git a/src/test/ui/type-alias/issue-62263-self-in-atb.rs b/src/test/ui/type-alias/issue-62263-self-in-atb.rs new file mode 100644 index 000000000..91522d891 --- /dev/null +++ b/src/test/ui/type-alias/issue-62263-self-in-atb.rs @@ -0,0 +1,8 @@ +pub trait Trait { + type A; +} + +pub type Alias = dyn Trait<A = Self::A>; +//~^ ERROR failed to resolve: `Self` + +fn main() {} diff --git a/src/test/ui/type-alias/issue-62263-self-in-atb.stderr b/src/test/ui/type-alias/issue-62263-self-in-atb.stderr new file mode 100644 index 000000000..c20074dc2 --- /dev/null +++ b/src/test/ui/type-alias/issue-62263-self-in-atb.stderr @@ -0,0 +1,9 @@ +error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions + --> $DIR/issue-62263-self-in-atb.rs:5:32 + | +LL | pub type Alias = dyn Trait<A = Self::A>; + | ^^^^ `Self` is only available in impls, traits, and type definitions + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/type-alias/issue-62305-self-assoc-ty.rs b/src/test/ui/type-alias/issue-62305-self-assoc-ty.rs new file mode 100644 index 000000000..a4d9a2854 --- /dev/null +++ b/src/test/ui/type-alias/issue-62305-self-assoc-ty.rs @@ -0,0 +1,4 @@ +type Alias = Self::Target; +//~^ ERROR failed to resolve: `Self` + +fn main() {} diff --git a/src/test/ui/type-alias/issue-62305-self-assoc-ty.stderr b/src/test/ui/type-alias/issue-62305-self-assoc-ty.stderr new file mode 100644 index 000000000..f3da50df9 --- /dev/null +++ b/src/test/ui/type-alias/issue-62305-self-assoc-ty.stderr @@ -0,0 +1,9 @@ +error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions + --> $DIR/issue-62305-self-assoc-ty.rs:1:14 + | +LL | type Alias = Self::Target; + | ^^^^ `Self` is only available in impls, traits, and type definitions + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/type-alias/issue-62364-self-ty-arg.rs b/src/test/ui/type-alias/issue-62364-self-ty-arg.rs new file mode 100644 index 000000000..bebb4a902 --- /dev/null +++ b/src/test/ui/type-alias/issue-62364-self-ty-arg.rs @@ -0,0 +1,8 @@ +struct Struct<P1> { + field: P1, +} + +type Alias<'a> = Struct<&'a Self>; +//~^ ERROR cannot find type `Self` in this scope [E0411] + +fn main() {} diff --git a/src/test/ui/type-alias/issue-62364-self-ty-arg.stderr b/src/test/ui/type-alias/issue-62364-self-ty-arg.stderr new file mode 100644 index 000000000..7e15e42e3 --- /dev/null +++ b/src/test/ui/type-alias/issue-62364-self-ty-arg.stderr @@ -0,0 +1,11 @@ +error[E0411]: cannot find type `Self` in this scope + --> $DIR/issue-62364-self-ty-arg.rs:5:29 + | +LL | type Alias<'a> = Struct<&'a Self>; + | ----- ^^^^ `Self` is only available in impls, traits, and type definitions + | | + | `Self` not allowed in a type alias + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0411`. diff --git a/src/test/ui/type-id-higher-rank-2.rs b/src/test/ui/type-id-higher-rank-2.rs new file mode 100644 index 000000000..5391c849d --- /dev/null +++ b/src/test/ui/type-id-higher-rank-2.rs @@ -0,0 +1,31 @@ +// run-pass +// Test that we can't ignore lifetimes by going through Any. + +use std::any::Any; + +struct Foo<'a>(&'a str); + +fn good(s: &String) -> Foo { Foo(s) } + +fn bad1(s: String) -> Option<&'static str> { + let a: Box<dyn Any> = Box::new(good as fn(&String) -> Foo); + a.downcast_ref::<fn(&String) -> Foo<'static>>().map(|f| f(&s).0) +} + +trait AsStr<'a, 'b> { + fn get(&'a self) -> &'b str; +} + +impl<'a> AsStr<'a, 'a> for String { + fn get(&'a self) -> &'a str { self } +} + +fn bad2(s: String) -> Option<&'static str> { + let a: Box<dyn Any> = Box::new(Box::new(s) as Box<dyn for<'a> AsStr<'a, 'a>>); + a.downcast_ref::<Box<dyn for<'a> AsStr<'a, 'static>>>().map(|x| x.get()) +} + +fn main() { + assert_eq!(bad1(String::from("foo")), None); + assert_eq!(bad2(String::from("bar")), None); +} diff --git a/src/test/ui/type-inference/issue-30225.rs b/src/test/ui/type-inference/issue-30225.rs new file mode 100644 index 000000000..42315332c --- /dev/null +++ b/src/test/ui/type-inference/issue-30225.rs @@ -0,0 +1,38 @@ +// Regression test for #30225, which was an ICE that would trigger as +// a result of a poor interaction between trait result caching and +// type inference. Specifically, at that time, unification could cause +// unrelated type variables to become instantiated, if subtyping +// relationships existed. These relationships are now propagated +// through obligations and hence everything works out fine. + +trait Foo<U,V> : Sized { + fn foo(self, u: Option<U>, v: Option<V>) {} +} + +struct A; +struct B; + +impl Foo<A, B> for () {} // impl A +impl Foo<u32, u32> for u32 {} // impl B, creating ambiguity + +fn toxic() { + // cache the resolution <() as Foo<$0,$1>> = impl A + let u = None; + let v = None; + Foo::foo((), u, v); +} + +fn bomb() { + let mut u = None; // type is Option<$0> + let mut v = None; // type is Option<$1> + let mut x = None; // type is Option<$2> + + Foo::foo(x.unwrap(),u,v); // register <$2 as Foo<$0, $1>> + u = v; // mark $0 and $1 in a subtype relationship + //~^ ERROR mismatched types + x = Some(()); // set $2 = (), allowing impl selection + // to proceed for <() as Foo<$0, $1>> = impl A. + // kaboom, this *used* to trigge an ICE +} + +fn main() {} diff --git a/src/test/ui/type-inference/issue-30225.stderr b/src/test/ui/type-inference/issue-30225.stderr new file mode 100644 index 000000000..ccd05fa6b --- /dev/null +++ b/src/test/ui/type-inference/issue-30225.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/issue-30225.rs:31:9 + | +LL | u = v; // mark $0 and $1 in a subtype relationship + | ^ expected struct `A`, found struct `B` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-inference/or_else-multiple-type-params.rs b/src/test/ui/type-inference/or_else-multiple-type-params.rs new file mode 100644 index 000000000..b15de2a45 --- /dev/null +++ b/src/test/ui/type-inference/or_else-multiple-type-params.rs @@ -0,0 +1,10 @@ +use std::process::{Command, Stdio}; + +fn main() { + let process = Command::new("wc") + .stdout(Stdio::piped()) + .spawn() + .or_else(|err| { //~ ERROR type annotations needed + panic!("oh no: {:?}", err); + }).unwrap(); +} diff --git a/src/test/ui/type-inference/or_else-multiple-type-params.stderr b/src/test/ui/type-inference/or_else-multiple-type-params.stderr new file mode 100644 index 000000000..6ac63a91e --- /dev/null +++ b/src/test/ui/type-inference/or_else-multiple-type-params.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed for `Result<Child, F>` + --> $DIR/or_else-multiple-type-params.rs:7:18 + | +LL | .or_else(|err| { + | ^^^^^ + | +help: try giving this closure an explicit return type + | +LL | .or_else(|err| -> Result<Child, F> { + | +++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-inference/sort_by_key.rs b/src/test/ui/type-inference/sort_by_key.rs new file mode 100644 index 000000000..afc4d90b8 --- /dev/null +++ b/src/test/ui/type-inference/sort_by_key.rs @@ -0,0 +1,5 @@ +fn main() { + let mut lst: [([i32; 10], bool); 10] = [([0; 10], false); 10]; + lst.sort_by_key(|&(v, _)| v.iter().sum()); //~ ERROR type annotations needed + println!("{:?}", lst); +} diff --git a/src/test/ui/type-inference/sort_by_key.stderr b/src/test/ui/type-inference/sort_by_key.stderr new file mode 100644 index 000000000..0a48d5756 --- /dev/null +++ b/src/test/ui/type-inference/sort_by_key.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/sort_by_key.rs:3:40 + | +LL | lst.sort_by_key(|&(v, _)| v.iter().sum()); + | ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` + | +help: consider specifying the generic argument + | +LL | lst.sort_by_key(|&(v, _)| v.iter().sum::<S>()); + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-inference/unbounded-associated-type.rs b/src/test/ui/type-inference/unbounded-associated-type.rs new file mode 100644 index 000000000..0167e9436 --- /dev/null +++ b/src/test/ui/type-inference/unbounded-associated-type.rs @@ -0,0 +1,16 @@ +trait T { + type A; + fn foo(&self) -> Self::A { + panic!() + } +} + +struct S<X>(std::marker::PhantomData<X>); + +impl<X> T for S<X> { + type A = X; +} + +fn main() { + S(std::marker::PhantomData).foo(); //~ ERROR type annotations needed +} diff --git a/src/test/ui/type-inference/unbounded-associated-type.stderr b/src/test/ui/type-inference/unbounded-associated-type.stderr new file mode 100644 index 000000000..e0fecc72f --- /dev/null +++ b/src/test/ui/type-inference/unbounded-associated-type.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/unbounded-associated-type.rs:15:7 + | +LL | S(std::marker::PhantomData).foo(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `PhantomData` + | +help: consider specifying the generic argument + | +LL | S(std::marker::PhantomData::<T>).foo(); + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.rs b/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.rs new file mode 100644 index 000000000..81d054b3a --- /dev/null +++ b/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.rs @@ -0,0 +1,9 @@ +#[allow(invalid_type_param_default)] + +fn foo<T, U = u64>() -> (T, U) { + panic!() +} + +fn main() { + foo(); //~ ERROR type annotations needed +} diff --git a/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr b/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr new file mode 100644 index 000000000..209abfe5c --- /dev/null +++ b/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/unbounded-type-param-in-fn-with-assoc-type.rs:8:5 + | +LL | foo(); + | ^^^ cannot infer type of the type parameter `T` declared on the function `foo` + | +help: consider specifying the generic arguments + | +LL | foo::<T, U>(); + | ++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-inference/unbounded-type-param-in-fn.rs b/src/test/ui/type-inference/unbounded-type-param-in-fn.rs new file mode 100644 index 000000000..1f336ed59 --- /dev/null +++ b/src/test/ui/type-inference/unbounded-type-param-in-fn.rs @@ -0,0 +1,7 @@ +fn foo<T>() -> T { + panic!() +} + +fn main() { + foo(); //~ ERROR type annotations needed +} diff --git a/src/test/ui/type-inference/unbounded-type-param-in-fn.stderr b/src/test/ui/type-inference/unbounded-type-param-in-fn.stderr new file mode 100644 index 000000000..d92892eeb --- /dev/null +++ b/src/test/ui/type-inference/unbounded-type-param-in-fn.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/unbounded-type-param-in-fn.rs:6:5 + | +LL | foo(); + | ^^^ cannot infer type of the type parameter `T` declared on the function `foo` + | +help: consider specifying the generic argument + | +LL | foo::<T>(); + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-namespace.rs b/src/test/ui/type-namespace.rs new file mode 100644 index 000000000..3cc0bc447 --- /dev/null +++ b/src/test/ui/type-namespace.rs @@ -0,0 +1,7 @@ +// run-pass + +struct A { a: isize } + +fn a(a: A) -> isize { return a.a; } + +pub fn main() { let x: A = A {a: 1}; assert_eq!(a(x), 1); } diff --git a/src/test/ui/type-param-constraints.rs b/src/test/ui/type-param-constraints.rs new file mode 100644 index 000000000..3d87a089f --- /dev/null +++ b/src/test/ui/type-param-constraints.rs @@ -0,0 +1,37 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn p_foo<T>(_pinned: T) { } +fn s_foo<T>(_shared: T) { } +fn u_foo<T:Send>(_unique: T) { } + +struct r { + i: isize, +} + +impl Drop for r { + fn drop(&mut self) {} +} + +fn r(i:isize) -> r { + r { + i: i + } +} + +pub fn main() { + p_foo(r(10)); + + p_foo::<Box<_>>(Box::new(r(10))); + p_foo::<Box<_>>(Box::new(10)); + p_foo(10); + + s_foo::<Box<_>>(Box::new(10)); + s_foo(10); + + u_foo::<Box<_>>(Box::new(10)); + u_foo(10); +} diff --git a/src/test/ui/type-param.rs b/src/test/ui/type-param.rs new file mode 100644 index 000000000..ca2f24d37 --- /dev/null +++ b/src/test/ui/type-param.rs @@ -0,0 +1,11 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] + + +// pretty-expanded FIXME #23616 + +type lteq<T> = extern "C" fn(T) -> bool; + +pub fn main() { } diff --git a/src/test/ui/type-ptr.rs b/src/test/ui/type-ptr.rs new file mode 100644 index 000000000..7c2438d38 --- /dev/null +++ b/src/test/ui/type-ptr.rs @@ -0,0 +1,10 @@ +// run-pass + +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn f(a: *const isize) -> *const isize { return a; } + +fn g(a: *const isize) -> *const isize { let b = f(a); return b; } + +pub fn main() { return; } diff --git a/src/test/ui/type-use-i1-versus-i8.rs b/src/test/ui/type-use-i1-versus-i8.rs new file mode 100644 index 000000000..7315cd2fe --- /dev/null +++ b/src/test/ui/type-use-i1-versus-i8.rs @@ -0,0 +1,12 @@ +// run-pass +// pretty-expanded FIXME #23616 + +use std::ptr; + +pub fn main() { + unsafe { + let mut x: bool = false; + // this line breaks it + ptr::write(&mut x, false); + } +} diff --git a/src/test/ui/type/ascription/issue-34255-1.rs b/src/test/ui/type/ascription/issue-34255-1.rs new file mode 100644 index 000000000..44b47cc4e --- /dev/null +++ b/src/test/ui/type/ascription/issue-34255-1.rs @@ -0,0 +1,15 @@ +struct Reactor { + input_cells: Vec<usize>, +} + +impl Reactor { + pub fn new() -> Self { + input_cells: Vec::new() + //~^ ERROR cannot find value `input_cells` in this scope + //~| ERROR parenthesized type parameters may only be used with a `Fn` trait + //~| ERROR missing generics for struct `Vec` + } +} + +// This case isn't currently being handled gracefully, including for completeness. +fn main() {} diff --git a/src/test/ui/type/ascription/issue-34255-1.stderr b/src/test/ui/type/ascription/issue-34255-1.stderr new file mode 100644 index 000000000..6819d14bb --- /dev/null +++ b/src/test/ui/type/ascription/issue-34255-1.stderr @@ -0,0 +1,41 @@ +error[E0425]: cannot find value `input_cells` in this scope + --> $DIR/issue-34255-1.rs:7:9 + | +LL | input_cells: Vec::new() + | ^^^^^^^^^^^ a field by this name exists in `Self` + | +help: you might have meant to write a `struct` literal + | +LL ~ pub fn new() -> Self { SomeStruct { +LL | input_cells: Vec::new() + ... +LL | +LL ~ }} + | + +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait + --> $DIR/issue-34255-1.rs:7:27 + | +LL | input_cells: Vec::new() + | ^^^^^ only `Fn` traits may use parentheses + +error[E0107]: missing generics for struct `Vec` + --> $DIR/issue-34255-1.rs:7:22 + | +LL | input_cells: Vec::new() + | ^^^ expected at least 1 generic argument + | +note: struct defined here, with at least 1 generic parameter: `T` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + | +LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> { + | ^^^ - +help: add missing generic argument + | +LL | input_cells: Vec<T>::new() + | ~~~~~~ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0214, E0425. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/type/ascription/issue-47666.fixed b/src/test/ui/type/ascription/issue-47666.fixed new file mode 100644 index 000000000..c4db74755 --- /dev/null +++ b/src/test/ui/type/ascription/issue-47666.fixed @@ -0,0 +1,4 @@ +// run-rustfix +fn main() { + let _ = Option::Some(vec![0, 1]); //~ ERROR expected type, found +} diff --git a/src/test/ui/type/ascription/issue-47666.rs b/src/test/ui/type/ascription/issue-47666.rs new file mode 100644 index 000000000..c67202e21 --- /dev/null +++ b/src/test/ui/type/ascription/issue-47666.rs @@ -0,0 +1,4 @@ +// run-rustfix +fn main() { + let _ = Option:Some(vec![0, 1]); //~ ERROR expected type, found +} diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr new file mode 100644 index 000000000..0f90fce3a --- /dev/null +++ b/src/test/ui/type/ascription/issue-47666.stderr @@ -0,0 +1,16 @@ +error: expected type, found `<[_]>::into_vec(#[rustc_box] ::alloc::boxed::Box::new([0, 1]))` + --> $DIR/issue-47666.rs:3:25 + | +LL | let _ = Option:Some(vec![0, 1]); + | - ^^^^^^^^^^ + | | | + | | expected type + | | in this macro invocation + | | this macro call doesn't expand to a type + | help: maybe write a path separator here: `::` + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + = note: this error originates in the macro `$crate::__rust_force_expr` which comes from the expansion of the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/ui/type/ascription/issue-54516.fixed b/src/test/ui/type/ascription/issue-54516.fixed new file mode 100644 index 000000000..f78268894 --- /dev/null +++ b/src/test/ui/type/ascription/issue-54516.fixed @@ -0,0 +1,7 @@ +// run-rustfix +use std::collections::BTreeMap; + +fn main() { + println!("{}", std::mem::size_of::<BTreeMap<u32, u32>>()); + //~^ ERROR type ascription cannot be followed by a function call +} diff --git a/src/test/ui/type/ascription/issue-54516.rs b/src/test/ui/type/ascription/issue-54516.rs new file mode 100644 index 000000000..1f34e6943 --- /dev/null +++ b/src/test/ui/type/ascription/issue-54516.rs @@ -0,0 +1,7 @@ +// run-rustfix +use std::collections::BTreeMap; + +fn main() { + println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); + //~^ ERROR type ascription cannot be followed by a function call +} diff --git a/src/test/ui/type/ascription/issue-54516.stderr b/src/test/ui/type/ascription/issue-54516.stderr new file mode 100644 index 000000000..1ab9093e5 --- /dev/null +++ b/src/test/ui/type/ascription/issue-54516.stderr @@ -0,0 +1,12 @@ +error: type ascription cannot be followed by a function call + --> $DIR/issue-54516.rs:5:20 + | +LL | println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>()); + | ^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | help: maybe write a path separator here: `::` + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + +error: aborting due to previous error + diff --git a/src/test/ui/type/ascription/issue-60933.fixed b/src/test/ui/type/ascription/issue-60933.fixed new file mode 100644 index 000000000..3e8be3875 --- /dev/null +++ b/src/test/ui/type/ascription/issue-60933.fixed @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let _: usize = std::mem::size_of::<u32>(); + //~^ ERROR type ascription cannot be followed by a function call +} diff --git a/src/test/ui/type/ascription/issue-60933.rs b/src/test/ui/type/ascription/issue-60933.rs new file mode 100644 index 000000000..2a4ad7bdc --- /dev/null +++ b/src/test/ui/type/ascription/issue-60933.rs @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let _: usize = std::mem:size_of::<u32>(); + //~^ ERROR type ascription cannot be followed by a function call +} diff --git a/src/test/ui/type/ascription/issue-60933.stderr b/src/test/ui/type/ascription/issue-60933.stderr new file mode 100644 index 000000000..0b7f8edf6 --- /dev/null +++ b/src/test/ui/type/ascription/issue-60933.stderr @@ -0,0 +1,12 @@ +error: type ascription cannot be followed by a function call + --> $DIR/issue-60933.rs:3:20 + | +LL | let _: usize = std::mem:size_of::<u32>(); + | ^^^^^^^^-^^^^^^^^^^^^^^ + | | + | help: maybe write a path separator here: `::` + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + +error: aborting due to previous error + diff --git a/src/test/ui/type/auxiliary/crate_a1.rs b/src/test/ui/type/auxiliary/crate_a1.rs new file mode 100644 index 000000000..e2e185005 --- /dev/null +++ b/src/test/ui/type/auxiliary/crate_a1.rs @@ -0,0 +1,11 @@ +pub struct Foo; + +pub trait Bar{} + +pub fn bar() -> Box<Bar> { + unimplemented!() +} + + +pub fn try_foo(x: Foo){} +pub fn try_bar(x: Box<Bar>){} diff --git a/src/test/ui/type/auxiliary/crate_a2.rs b/src/test/ui/type/auxiliary/crate_a2.rs new file mode 100644 index 000000000..d16a4ac10 --- /dev/null +++ b/src/test/ui/type/auxiliary/crate_a2.rs @@ -0,0 +1,7 @@ +pub struct Foo; + +pub trait Bar{} + +pub fn bar() -> Box<Bar> { + unimplemented!() +} diff --git a/src/test/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs b/src/test/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs new file mode 100644 index 000000000..68aadcf60 --- /dev/null +++ b/src/test/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs @@ -0,0 +1,8 @@ +// Regression test for issue #67690 +// Rustc endless loop out-of-memory and consequent SIGKILL in generic new type + +// check-pass +pub type T<P: Send + Send + Send> = P; +//~^ WARN bounds on generic parameters are not enforced in type aliases + +fn main() {} diff --git a/src/test/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr b/src/test/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr new file mode 100644 index 000000000..125ffbbb4 --- /dev/null +++ b/src/test/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr @@ -0,0 +1,15 @@ +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/issue-67690-type-alias-bound-diagnostic-crash.rs:5:15 + | +LL | pub type T<P: Send + Send + Send> = P; + | ^^^^ ^^^^ ^^^^ + | + = note: `#[warn(type_alias_bounds)]` on by default +help: the bound will not be checked when the type alias is used, and should be removed + | +LL - pub type T<P: Send + Send + Send> = P; +LL + pub type T<P> = P; + | + +warning: 1 warning emitted + diff --git a/src/test/ui/type/issue-91268.rs b/src/test/ui/type/issue-91268.rs new file mode 100644 index 000000000..f1e16bc7b --- /dev/null +++ b/src/test/ui/type/issue-91268.rs @@ -0,0 +1,9 @@ +// error-pattern: this file contains an unclosed delimiter +// error-pattern: cannot find type `Å£` in this scope +// error-pattern: parenthesized type parameters may only be used with a `Fn` trait +// error-pattern: type arguments are not allowed on builtin type `u8` +// error-pattern: mismatched types +// ignore-tidy-trailing-newlines +// `Å£` must be the last character in this file, it cannot be followed by a newline +fn main() { + 0: u8(Å£
\ No newline at end of file diff --git a/src/test/ui/type/issue-91268.stderr b/src/test/ui/type/issue-91268.stderr new file mode 100644 index 000000000..6c9ee9945 --- /dev/null +++ b/src/test/ui/type/issue-91268.stderr @@ -0,0 +1,63 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-91268.rs:9:12 + | +LL | fn main() { + | - unclosed delimiter +LL | 0: u8(ţ + | - ^ + | | + | unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-91268.rs:9:12 + | +LL | fn main() { + | - unclosed delimiter +LL | 0: u8(ţ + | - ^ + | | + | unclosed delimiter + +error[E0412]: cannot find type `ţ` in this scope + --> $DIR/issue-91268.rs:9:11 + | +LL | 0: u8(ţ + | ^ expecting a type here because of type ascription + +error[E0214]: parenthesized type parameters may only be used with a `Fn` trait + --> $DIR/issue-91268.rs:9:8 + | +LL | 0: u8(ţ + | ^^^^ only `Fn` traits may use parentheses + | +help: use angle brackets instead + | +LL | 0: u8<ţ> + | ~ + + +error[E0109]: type arguments are not allowed on builtin type `u8` + --> $DIR/issue-91268.rs:9:11 + | +LL | 0: u8(ţ + | -- ^ type argument not allowed + | | + | not allowed on builtin type `u8` + | +help: primitive type `u8` doesn't have generic parameters + | +LL - 0: u8(ţ +LL + 0: u8 + | + +error[E0308]: mismatched types + --> $DIR/issue-91268.rs:9:5 + | +LL | fn main() { + | - expected `()` because of default return type +LL | 0: u8(ţ + | ^^^^^^^ expected `()`, found `u8` + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0109, E0214, E0308, E0412. +For more information about an error, try `rustc --explain E0109`. diff --git a/src/test/ui/type/missing-let-in-binding.fixed b/src/test/ui/type/missing-let-in-binding.fixed new file mode 100644 index 000000000..d17876889 --- /dev/null +++ b/src/test/ui/type/missing-let-in-binding.fixed @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let mut _foo: i32 = 1; + let _foo: i32 = 4; //~ ERROR type ascription is experimental +} diff --git a/src/test/ui/type/missing-let-in-binding.rs b/src/test/ui/type/missing-let-in-binding.rs new file mode 100644 index 000000000..ca42f2e6e --- /dev/null +++ b/src/test/ui/type/missing-let-in-binding.rs @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let mut _foo: i32 = 1; + _foo: i32 = 4; //~ ERROR type ascription is experimental +} diff --git a/src/test/ui/type/missing-let-in-binding.stderr b/src/test/ui/type/missing-let-in-binding.stderr new file mode 100644 index 000000000..12759c509 --- /dev/null +++ b/src/test/ui/type/missing-let-in-binding.stderr @@ -0,0 +1,16 @@ +error[E0658]: type ascription is experimental + --> $DIR/missing-let-in-binding.rs:4:5 + | +LL | _foo: i32 = 4; + | ^^^^^^^^^ + | + = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information + = help: add `#![feature(type_ascription)]` to the crate attributes to enable +help: you might have meant to introduce a new binding + | +LL | let _foo: i32 = 4; + | +++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/type/type-alias-bounds.rs b/src/test/ui/type/type-alias-bounds.rs new file mode 100644 index 000000000..65b79650d --- /dev/null +++ b/src/test/ui/type/type-alias-bounds.rs @@ -0,0 +1,59 @@ +// Test `ignored_generic_bounds` lint warning about bounds in type aliases. + +// check-pass +#![allow(dead_code)] + +use std::rc::Rc; + +type SVec<T: Send + Send> = Vec<T>; +//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] +type S2Vec<T> where T: Send = Vec<T>; +//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] +type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); +//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] +type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>); +//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] +type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>); +//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] + +static STATIC: u32 = 0; + +fn foo<'a>(y: &'a i32) { + // If any of the bounds above would matter, the code below would be rejected. + // This can be seen when replacing the type aliases above by newtype structs. + // (The type aliases have no unused parameters to make that a valid transformation.) + let mut x: SVec<_> = Vec::new(); + x.push(Rc::new(42)); // is not send + + let mut x: S2Vec<_> = Vec::new(); + x.push(Rc::new(42)); // is not `Send` + + let mut x: VVec<'static, 'a> = (&STATIC, Vec::new()); + x.1.push(y); // `'a: 'static` does not hold + + let mut x: WVec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // `&'a i32: 'static` does not hold + + let mut x: W2Vec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // `&'a i32: 'static` does not hold +} + +// Bounds are not checked either; i.e., the definition is not necessarily well-formed. +struct Sendable<T: Send>(T); +type MySendable<T> = Sendable<T>; // no error here! + +// However, bounds *are* taken into account when accessing associated types +trait Bound { type Assoc; } +type T1<U: Bound> = U::Assoc; //~ WARN not enforced in type aliases +type T2<U> where U: Bound = U::Assoc; //~ WARN not enforced in type aliases + +// This errors: +// `type T3<U> = U::Assoc;` +// Do this instead: +type T4<U> = <U as Bound>::Assoc; + +// Make sure the help about associatd types is not shown incorrectly +type T5<U: Bound> = <U as Bound>::Assoc; //~ WARN not enforced in type aliases +type T6<U: Bound> = ::std::vec::Vec<U>; //~ WARN not enforced in type aliases + +fn main() {} diff --git a/src/test/ui/type/type-alias-bounds.stderr b/src/test/ui/type/type-alias-bounds.stderr new file mode 100644 index 000000000..92e573393 --- /dev/null +++ b/src/test/ui/type/type-alias-bounds.stderr @@ -0,0 +1,121 @@ +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:8:14 + | +LL | type SVec<T: Send + Send> = Vec<T>; + | ^^^^ ^^^^ + | + = note: `#[warn(type_alias_bounds)]` on by default +help: the bound will not be checked when the type alias is used, and should be removed + | +LL - type SVec<T: Send + Send> = Vec<T>; +LL + type SVec<T> = Vec<T>; + | + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:10:21 + | +LL | type S2Vec<T> where T: Send = Vec<T>; + | ^^^^^^^ + | +help: the clause will not be checked when the type alias is used, and should be removed + | +LL - type S2Vec<T> where T: Send = Vec<T>; +LL + type S2Vec<T> = Vec<T>; + | + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:12:19 + | +LL | type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); + | ^^ ^^ + | +help: the bound will not be checked when the type alias is used, and should be removed + | +LL - type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); +LL + type VVec<'b, 'a> = (&'b u32, Vec<&'a i32>); + | + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:14:18 + | +LL | type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>); + | ^^ ^^ + | +help: the bound will not be checked when the type alias is used, and should be removed + | +LL - type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>); +LL + type WVec<'b, T> = (&'b u32, Vec<T>); + | + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:16:25 + | +LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>); + | ^^^^^ ^^^^^ + | +help: the clause will not be checked when the type alias is used, and should be removed + | +LL - type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>); +LL + type W2Vec<'b, T> = (&'b u32, Vec<T>); + | + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:47:12 + | +LL | type T1<U: Bound> = U::Assoc; + | ^^^^^ + | +help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases + --> $DIR/type-alias-bounds.rs:47:21 + | +LL | type T1<U: Bound> = U::Assoc; + | ^^^^^^^^ +help: the bound will not be checked when the type alias is used, and should be removed + | +LL - type T1<U: Bound> = U::Assoc; +LL + type T1<U> = U::Assoc; + | + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:48:18 + | +LL | type T2<U> where U: Bound = U::Assoc; + | ^^^^^^^^ + | +help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases + --> $DIR/type-alias-bounds.rs:48:29 + | +LL | type T2<U> where U: Bound = U::Assoc; + | ^^^^^^^^ +help: the clause will not be checked when the type alias is used, and should be removed + | +LL - type T2<U> where U: Bound = U::Assoc; +LL + type T2<U> = U::Assoc; + | + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:56:12 + | +LL | type T5<U: Bound> = <U as Bound>::Assoc; + | ^^^^^ + | +help: the bound will not be checked when the type alias is used, and should be removed + | +LL - type T5<U: Bound> = <U as Bound>::Assoc; +LL + type T5<U> = <U as Bound>::Assoc; + | + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:57:12 + | +LL | type T6<U: Bound> = ::std::vec::Vec<U>; + | ^^^^^ + | +help: the bound will not be checked when the type alias is used, and should be removed + | +LL - type T6<U: Bound> = ::std::vec::Vec<U>; +LL + type T6<U> = ::std::vec::Vec<U>; + | + +warning: 9 warnings emitted + diff --git a/src/test/ui/type/type-annotation-needed.rs b/src/test/ui/type/type-annotation-needed.rs new file mode 100644 index 000000000..347887f4b --- /dev/null +++ b/src/test/ui/type/type-annotation-needed.rs @@ -0,0 +1,10 @@ +fn foo<T: Into<String>>(x: i32) {} +//~^ NOTE required by +//~| NOTE required by + +fn main() { + foo(42); + //~^ ERROR type annotations needed + //~| NOTE cannot infer type + //~| NOTE cannot satisfy +} diff --git a/src/test/ui/type/type-annotation-needed.stderr b/src/test/ui/type/type-annotation-needed.stderr new file mode 100644 index 000000000..4af4c22f7 --- /dev/null +++ b/src/test/ui/type/type-annotation-needed.stderr @@ -0,0 +1,20 @@ +error[E0283]: type annotations needed + --> $DIR/type-annotation-needed.rs:6:5 + | +LL | foo(42); + | ^^^ cannot infer type of the type parameter `T` declared on the function `foo` + | + = note: cannot satisfy `_: Into<String>` +note: required by a bound in `foo` + --> $DIR/type-annotation-needed.rs:1:11 + | +LL | fn foo<T: Into<String>>(x: i32) {} + | ^^^^^^^^^^^^ required by this bound in `foo` +help: consider specifying the type argument in the function call + | +LL | foo::<T>(42); + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/type/type-arg-out-of-scope.rs b/src/test/ui/type/type-arg-out-of-scope.rs new file mode 100644 index 000000000..02aad0077 --- /dev/null +++ b/src/test/ui/type/type-arg-out-of-scope.rs @@ -0,0 +1,5 @@ +// error-pattern:can't use generic parameters from outer function +fn foo<T>(x: T) { + fn bar(f: Box<dyn FnMut(T) -> T>) { } +} +fn main() { foo(1); } diff --git a/src/test/ui/type/type-arg-out-of-scope.stderr b/src/test/ui/type/type-arg-out-of-scope.stderr new file mode 100644 index 000000000..0b6283fbc --- /dev/null +++ b/src/test/ui/type/type-arg-out-of-scope.stderr @@ -0,0 +1,23 @@ +error[E0401]: can't use generic parameters from outer function + --> $DIR/type-arg-out-of-scope.rs:3:29 + | +LL | fn foo<T>(x: T) { + | - type parameter from outer function +LL | fn bar(f: Box<dyn FnMut(T) -> T>) { } + | --- ^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `bar<T>` + +error[E0401]: can't use generic parameters from outer function + --> $DIR/type-arg-out-of-scope.rs:3:35 + | +LL | fn foo<T>(x: T) { + | - type parameter from outer function +LL | fn bar(f: Box<dyn FnMut(T) -> T>) { } + | --- ^ use of generic parameter from outer function + | | + | help: try using a local generic parameter instead: `bar<T>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0401`. diff --git a/src/test/ui/type/type-ascription-instead-of-initializer.rs b/src/test/ui/type/type-ascription-instead-of-initializer.rs new file mode 100644 index 000000000..9f9b6f06b --- /dev/null +++ b/src/test/ui/type/type-ascription-instead-of-initializer.rs @@ -0,0 +1,4 @@ +fn main() { + let x: Vec::with_capacity(10, 20); //~ ERROR expected type, found `10` + //~^ ERROR this function takes 1 argument +} diff --git a/src/test/ui/type/type-ascription-instead-of-initializer.stderr b/src/test/ui/type/type-ascription-instead-of-initializer.stderr new file mode 100644 index 000000000..fcac6c495 --- /dev/null +++ b/src/test/ui/type/type-ascription-instead-of-initializer.stderr @@ -0,0 +1,28 @@ +error: expected type, found `10` + --> $DIR/type-ascription-instead-of-initializer.rs:2:31 + | +LL | let x: Vec::with_capacity(10, 20); + | -- ^^ expected type + | || + | |help: use `=` if you meant to assign + | while parsing the type for `x` + +error[E0061]: this function takes 1 argument but 2 arguments were supplied + --> $DIR/type-ascription-instead-of-initializer.rs:2:12 + | +LL | let x: Vec::with_capacity(10, 20); + | ^^^^^^^^^^^^^^^^^^ -- argument of type `{integer}` unexpected + | +note: associated function defined here + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + | +LL | pub fn with_capacity(capacity: usize) -> Self { + | ^^^^^^^^^^^^^ +help: remove the extra argument + | +LL | let x: Vec::with_capacity(10); + | ~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/type/type-ascription-instead-of-statement-end.rs b/src/test/ui/type/type-ascription-instead-of-statement-end.rs new file mode 100644 index 000000000..1d5565ab5 --- /dev/null +++ b/src/test/ui/type/type-ascription-instead-of-statement-end.rs @@ -0,0 +1,10 @@ +#![feature(type_ascription)] + +fn main() { + println!("test"): + 0; //~ ERROR expected type, found `0` +} + +fn foo() { + println!("test"): 0; //~ ERROR expected type, found `0` +} diff --git a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr new file mode 100644 index 000000000..521ebcdf1 --- /dev/null +++ b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr @@ -0,0 +1,24 @@ +error: expected type, found `0` + --> $DIR/type-ascription-instead-of-statement-end.rs:5:5 + | +LL | println!("test"): + | - help: try using a semicolon: `;` +LL | 0; + | ^ expected type + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information + +error: expected type, found `0` + --> $DIR/type-ascription-instead-of-statement-end.rs:9:23 + | +LL | println!("test"): 0; + | - ^ expected type + | | + | tried to parse a type due to this type ascription + | + = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>` + = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/type/type-ascription-precedence.rs b/src/test/ui/type/type-ascription-precedence.rs new file mode 100644 index 000000000..d3aef929b --- /dev/null +++ b/src/test/ui/type/type-ascription-precedence.rs @@ -0,0 +1,54 @@ +// Operator precedence of type ascription +// Type ascription has very high precedence, the same as operator `as` + +#![feature(type_ascription)] + +use std::ops::*; + +struct S; +struct Z; + +impl Add<Z> for S { + type Output = S; + fn add(self, _rhs: Z) -> S { panic!() } +} +impl Mul<Z> for S { + type Output = S; + fn mul(self, _rhs: Z) -> S { panic!() } +} +impl Neg for S { + type Output = Z; + fn neg(self) -> Z { panic!() } +} +impl Deref for S { + type Target = Z; + fn deref(&self) -> &Z { panic!() } +} + +fn main() { + &S: &S; // OK + (&S): &S; // OK + &(S: &S); //~ ERROR mismatched types + + *S: Z; // OK + (*S): Z; // OK + *(S: Z); //~ ERROR mismatched types + //~^ ERROR type `Z` cannot be dereferenced + + -S: Z; // OK + (-S): Z; // OK + -(S: Z); //~ ERROR mismatched types + //~^ ERROR cannot apply unary operator `-` to type `Z` + + S + Z: Z; // OK + S + (Z: Z); // OK + (S + Z): Z; //~ ERROR mismatched types + + S * Z: Z; // OK + S * (Z: Z); // OK + (S * Z): Z; //~ ERROR mismatched types + + S .. S: S; // OK + S .. (S: S); // OK + (S .. S): S; //~ ERROR mismatched types +} diff --git a/src/test/ui/type/type-ascription-precedence.stderr b/src/test/ui/type/type-ascription-precedence.stderr new file mode 100644 index 000000000..a8139063d --- /dev/null +++ b/src/test/ui/type/type-ascription-precedence.stderr @@ -0,0 +1,66 @@ +error[E0308]: mismatched types + --> $DIR/type-ascription-precedence.rs:31:7 + | +LL | &(S: &S); + | ^ expected `&S`, found struct `S` + +error[E0308]: mismatched types + --> $DIR/type-ascription-precedence.rs:35:7 + | +LL | *(S: Z); + | ^ expected struct `Z`, found struct `S` + +error[E0614]: type `Z` cannot be dereferenced + --> $DIR/type-ascription-precedence.rs:35:5 + | +LL | *(S: Z); + | ^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/type-ascription-precedence.rs:40:7 + | +LL | -(S: Z); + | ^ expected struct `Z`, found struct `S` + +error[E0600]: cannot apply unary operator `-` to type `Z` + --> $DIR/type-ascription-precedence.rs:40:5 + | +LL | -(S: Z); + | ^^^^^^^ cannot apply unary operator `-` + | +note: an implementation of `std::ops::Neg` might be missing for `Z` + --> $DIR/type-ascription-precedence.rs:9:1 + | +LL | struct Z; + | ^^^^^^^^ must implement `std::ops::Neg` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | pub trait Neg { + | ^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/type-ascription-precedence.rs:45:5 + | +LL | (S + Z): Z; + | ^^^^^^^ expected struct `Z`, found struct `S` + +error[E0308]: mismatched types + --> $DIR/type-ascription-precedence.rs:49:5 + | +LL | (S * Z): Z; + | ^^^^^^^ expected struct `Z`, found struct `S` + +error[E0308]: mismatched types + --> $DIR/type-ascription-precedence.rs:53:5 + | +LL | (S .. S): S; + | ^^^^^^^^ expected struct `S`, found struct `std::ops::Range` + | + = note: expected struct `S` + found struct `std::ops::Range<S>` + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0308, E0600, E0614. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-ascription-soundness.rs b/src/test/ui/type/type-ascription-soundness.rs new file mode 100644 index 000000000..d583fc213 --- /dev/null +++ b/src/test/ui/type/type-ascription-soundness.rs @@ -0,0 +1,13 @@ +// Type ascription doesn't lead to unsoundness + +#![feature(type_ascription)] + +fn main() { + let arr = &[1u8, 2, 3]; + let ref x = arr: &[u8]; //~ ERROR mismatched types + let ref mut x = arr: &[u8]; //~ ERROR mismatched types + match arr: &[u8] { //~ ERROR mismatched types + ref x => {} + } + let _len = (arr: &[u8]).len(); //~ ERROR mismatched types +} diff --git a/src/test/ui/type/type-ascription-soundness.stderr b/src/test/ui/type/type-ascription-soundness.stderr new file mode 100644 index 000000000..6ed940823 --- /dev/null +++ b/src/test/ui/type/type-ascription-soundness.stderr @@ -0,0 +1,39 @@ +error[E0308]: mismatched types + --> $DIR/type-ascription-soundness.rs:7:17 + | +LL | let ref x = arr: &[u8]; + | ^^^ expected slice `[u8]`, found array `[u8; 3]` + | + = note: expected reference `&[u8]` + found reference `&[u8; 3]` + +error[E0308]: mismatched types + --> $DIR/type-ascription-soundness.rs:8:21 + | +LL | let ref mut x = arr: &[u8]; + | ^^^ expected slice `[u8]`, found array `[u8; 3]` + | + = note: expected reference `&[u8]` + found reference `&[u8; 3]` + +error[E0308]: mismatched types + --> $DIR/type-ascription-soundness.rs:9:11 + | +LL | match arr: &[u8] { + | ^^^ expected slice `[u8]`, found array `[u8; 3]` + | + = note: expected reference `&[u8]` + found reference `&[u8; 3]` + +error[E0308]: mismatched types + --> $DIR/type-ascription-soundness.rs:12:17 + | +LL | let _len = (arr: &[u8]).len(); + | ^^^ expected slice `[u8]`, found array `[u8; 3]` + | + = note: expected reference `&[u8]` + found reference `&[u8; 3]` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-ascription-with-fn-call.fixed b/src/test/ui/type/type-ascription-with-fn-call.fixed new file mode 100644 index 000000000..6d96c4303 --- /dev/null +++ b/src/test/ui/type/type-ascription-with-fn-call.fixed @@ -0,0 +1,9 @@ +// run-rustfix +#![feature(type_ascription)] + +fn main() { + f() ; + f(); //~ ERROR expected type, found function +} + +fn f() {} diff --git a/src/test/ui/type/type-ascription-with-fn-call.rs b/src/test/ui/type/type-ascription-with-fn-call.rs new file mode 100644 index 000000000..ed4f7c904 --- /dev/null +++ b/src/test/ui/type/type-ascription-with-fn-call.rs @@ -0,0 +1,9 @@ +// run-rustfix +#![feature(type_ascription)] + +fn main() { + f() : + f(); //~ ERROR expected type, found function +} + +fn f() {} diff --git a/src/test/ui/type/type-ascription-with-fn-call.stderr b/src/test/ui/type/type-ascription-with-fn-call.stderr new file mode 100644 index 000000000..d78fd08fd --- /dev/null +++ b/src/test/ui/type/type-ascription-with-fn-call.stderr @@ -0,0 +1,11 @@ +error[E0573]: expected type, found function `f` + --> $DIR/type-ascription-with-fn-call.rs:6:5 + | +LL | f() : + | - help: maybe you meant to write `;` here +LL | f(); + | ^^^ expecting a type here because of type ascription + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0573`. diff --git a/src/test/ui/type/type-ascription.rs b/src/test/ui/type/type-ascription.rs new file mode 100644 index 000000000..7adb07442 --- /dev/null +++ b/src/test/ui/type/type-ascription.rs @@ -0,0 +1,39 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unused_variables)] +// Type ascription doesn't lead to unsoundness + +#![feature(type_ascription)] + +use std::mem; + +const C1: u8 = 10: u8; +const C2: [u8; 1: usize] = [1]; + +struct S { + a: u8 +} + +fn main() { + assert_eq!(C1.into(): i32, 10); + assert_eq!(C2[0], 1); + + let s = S { a: 10: u8 }; + let arr = &[1u8, 2, 3]; + + let mut v = arr.iter().cloned().collect(): Vec<_>; + v.push(4); + assert_eq!(v, [1, 2, 3, 4]); + + let a = 1: u8; + let b = a.into(): u16; + assert_eq!(v[a.into(): usize], 2); + assert_eq!(mem::size_of_val(&a), 1); + assert_eq!(mem::size_of_val(&b), 2); + assert_eq!(b, 1: u16); + + let mut v = Vec::new(); + v: Vec<u8> = vec![1, 2, 3]; // Place expression type ascription + assert_eq!(v, [1u8, 2, 3]); +} diff --git a/src/test/ui/type/type-check-defaults.rs b/src/test/ui/type/type-check-defaults.rs new file mode 100644 index 000000000..6a0a7ed33 --- /dev/null +++ b/src/test/ui/type/type-check-defaults.rs @@ -0,0 +1,27 @@ +use std::iter::FromIterator; +use std::vec::IntoIter; +use std::ops::Add; + +struct Foo<T, U: FromIterator<T>>(T, U); +struct WellFormed<Z = Foo<i32, i32>>(Z); +//~^ ERROR a value of type `i32` cannot be built from an iterator over elements of type `i32` +struct WellFormedNoBounds<Z:?Sized = Foo<i32, i32>>(Z); +//~^ ERROR a value of type `i32` cannot be built from an iterator over elements of type `i32` + +struct Bounds<T:Copy=String>(T); +//~^ ERROR the trait bound `String: Copy` is not satisfied [E0277] + +struct WhereClause<T=String>(T) where T: Copy; +//~^ ERROR the trait bound `String: Copy` is not satisfied [E0277] + +trait TraitBound<T:Copy=String> {} +//~^ ERROR the trait bound `String: Copy` is not satisfied [E0277] + +trait Super<T: Copy> { } +trait Base<T = String>: Super<T> { } +//~^ ERROR the trait bound `T: Copy` is not satisfied [E0277] + +trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {} +//~^ ERROR cannot add `u8` to `i32` [E0277] + +fn main() { } diff --git a/src/test/ui/type/type-check-defaults.stderr b/src/test/ui/type/type-check-defaults.stderr new file mode 100644 index 000000000..56a9b5317 --- /dev/null +++ b/src/test/ui/type/type-check-defaults.stderr @@ -0,0 +1,81 @@ +error[E0277]: a value of type `i32` cannot be built from an iterator over elements of type `i32` + --> $DIR/type-check-defaults.rs:6:19 + | +LL | struct WellFormed<Z = Foo<i32, i32>>(Z); + | ^^^^^^^^^^^^^^^^^ value of type `i32` cannot be built from `std::iter::Iterator<Item=i32>` + | + = help: the trait `FromIterator<i32>` is not implemented for `i32` +note: required by a bound in `Foo` + --> $DIR/type-check-defaults.rs:5:18 + | +LL | struct Foo<T, U: FromIterator<T>>(T, U); + | ^^^^^^^^^^^^^^^ required by this bound in `Foo` + +error[E0277]: a value of type `i32` cannot be built from an iterator over elements of type `i32` + --> $DIR/type-check-defaults.rs:8:27 + | +LL | struct WellFormedNoBounds<Z:?Sized = Foo<i32, i32>>(Z); + | ^^^^^^^^^^^^^^^^^^^^^^^^ value of type `i32` cannot be built from `std::iter::Iterator<Item=i32>` + | + = help: the trait `FromIterator<i32>` is not implemented for `i32` +note: required by a bound in `Foo` + --> $DIR/type-check-defaults.rs:5:18 + | +LL | struct Foo<T, U: FromIterator<T>>(T, U); + | ^^^^^^^^^^^^^^^ required by this bound in `Foo` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-check-defaults.rs:11:17 + | +LL | struct Bounds<T:Copy=String>(T); + | ^^^^ the trait `Copy` is not implemented for `String` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-check-defaults.rs:14:42 + | +LL | struct WhereClause<T=String>(T) where T: Copy; + | ^^^^ the trait `Copy` is not implemented for `String` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-check-defaults.rs:17:20 + | +LL | trait TraitBound<T:Copy=String> {} + | ^^^^ the trait `Copy` is not implemented for `String` + +error[E0277]: the trait bound `T: Copy` is not satisfied + --> $DIR/type-check-defaults.rs:21:25 + | +LL | trait Base<T = String>: Super<T> { } + | ^^^^^^^^ the trait `Copy` is not implemented for `T` + | +note: required by a bound in `Super` + --> $DIR/type-check-defaults.rs:20:16 + | +LL | trait Super<T: Copy> { } + | ^^^^ required by this bound in `Super` +help: consider further restricting type parameter `T` + | +LL | trait Base<T = String>: Super<T> where T: std::marker::Copy { } + | ++++++++++++++++++++++++++ + +error[E0277]: cannot add `u8` to `i32` + --> $DIR/type-check-defaults.rs:24:66 + | +LL | trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {} + | ^^^^^^^ no implementation for `i32 + u8` + | + = help: the trait `Add<u8>` is not implemented for `i32` + = help: the following other types implement trait `Add<Rhs>`: + <&'a f32 as Add<f32>> + <&'a f64 as Add<f64>> + <&'a i128 as Add<i128>> + <&'a i16 as Add<i16>> + <&'a i32 as Add<i32>> + <&'a i64 as Add<i64>> + <&'a i8 as Add<i8>> + <&'a isize as Add<isize>> + and 48 others + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type/type-check/assignment-expected-bool.rs b/src/test/ui/type/type-check/assignment-expected-bool.rs new file mode 100644 index 000000000..191939bdb --- /dev/null +++ b/src/test/ui/type/type-check/assignment-expected-bool.rs @@ -0,0 +1,34 @@ +// The purpose of this text is to ensure that we get good +// diagnostics when a `bool` is expected but that due to +// an assignment expression `x = y` the type is `()`. + +fn main() { + let _: bool = 0 = 0; //~ ERROR mismatched types [E0308] + + let _: bool = match 0 { + 0 => 0 = 0, //~ ERROR mismatched types [E0308] + _ => 0 = 0, //~ ERROR mismatched types [E0308] + }; + + let _: bool = match true { + true => 0 = 0, //~ ERROR mismatched types [E0308] + _ => (), + }; + + if 0 = 0 {} //~ ERROR mismatched types [E0308] + + let _: bool = if { 0 = 0 } { //~ ERROR mismatched types [E0308] + 0 = 0 //~ ERROR mismatched types [E0308] + } else { + 0 = 0 //~ ERROR mismatched types [E0308] + }; + + let _ = (0 = 0) //~ ERROR mismatched types [E0308] + && { 0 = 0 } //~ ERROR mismatched types [E0308] + || (0 = 0); //~ ERROR mismatched types [E0308] + + // A test to check that not expecting `bool` behaves well: + let _: usize = 0 = 0; + //~^ ERROR mismatched types [E0308] + //~| ERROR invalid left-hand side of assignment [E0070] +} diff --git a/src/test/ui/type/type-check/assignment-expected-bool.stderr b/src/test/ui/type/type-check/assignment-expected-bool.stderr new file mode 100644 index 000000000..e2b821f7b --- /dev/null +++ b/src/test/ui/type/type-check/assignment-expected-bool.stderr @@ -0,0 +1,141 @@ +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:6:19 + | +LL | let _: bool = 0 = 0; + | ^^^^^ expected `bool`, found `()` + | +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 + | +LL | 0 => 0 = 0, + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | 0 => 0 == 0, + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:10:14 + | +LL | _ => 0 = 0, + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | _ => 0 == 0, + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:14:17 + | +LL | true => 0 = 0, + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | true => 0 == 0, + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:18:8 + | +LL | if 0 = 0 {} + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if 0 == 0 {} + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:20:24 + | +LL | let _: bool = if { 0 = 0 } { + | ^^^^^ expected `bool`, found `()` + | +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 + | +LL | 0 = 0 + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | 0 == 0 + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:23:9 + | +LL | 0 = 0 + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | 0 == 0 + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:26:13 + | +LL | let _ = (0 = 0) + | ^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | let _ = (0 == 0) + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:27:14 + | +LL | && { 0 = 0 } + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | && { 0 == 0 } + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:28:12 + | +LL | || (0 = 0); + | ^^^^^^^ expected `bool`, found `()` + | +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 + | +LL | let _: usize = 0 = 0; + | - ^ + | | + | cannot assign to this expression + +error[E0308]: mismatched types + --> $DIR/assignment-expected-bool.rs:31:20 + | +LL | let _: usize = 0 = 0; + | ----- ^^^^^ expected `usize`, found `()` + | | + | expected due to this + +error: aborting due to 13 previous errors + +Some errors have detailed explanations: E0070, E0308. +For more information about an error, try `rustc --explain E0070`. diff --git a/src/test/ui/type/type-check/assignment-in-if.rs b/src/test/ui/type/type-check/assignment-in-if.rs new file mode 100644 index 000000000..8da7b32b4 --- /dev/null +++ b/src/test/ui/type/type-check/assignment-in-if.rs @@ -0,0 +1,43 @@ +// Test that the parser does not attempt to parse struct literals +// within assignments in if expressions. + +#![allow(unused_parens)] + +struct Foo { + foo: usize +} + +fn main() { + let x = 1; + let y: Foo; + + // `x { ... }` should not be interpreted as a struct literal here + if x = x { + //~^ ERROR mismatched types + println!("{}", x); + } + // Explicit parentheses on the left should match behavior of above + if (x = x) { + //~^ ERROR mismatched types + println!("{}", x); + } + // The struct literal interpretation is fine with explicit parentheses on the right + if y = (Foo { foo: x }) { + //~^ ERROR mismatched types + println!("{}", x); + } + // "invalid left-hand side of assignment" error is suppresed + if 3 = x { + //~^ ERROR mismatched types + println!("{}", x); + } + if ( + if true { + x = 4 //~ ERROR mismatched types + } else { + x = 5 //~ 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 new file mode 100644 index 000000000..f4ef44e24 --- /dev/null +++ b/src/test/ui/type/type-check/assignment-in-if.stderr @@ -0,0 +1,69 @@ +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:15:8 + | +LL | if x = x { + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if x == x { + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:20:8 + | +LL | if (x = x) { + | ^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if (x == x) { + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:25:8 + | +LL | if y = (Foo { foo: x }) { + | ^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + | +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 + | +LL | if 3 = x { + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if 3 == x { + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:36:13 + | +LL | x = 4 + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | x == 4 + | ~~ + +error[E0308]: mismatched types + --> $DIR/assignment-in-if.rs:38:13 + | +LL | x = 5 + | ^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | x == 5 + | ~~ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_array.rs b/src/test/ui/type/type-check/cannot_infer_local_or_array.rs new file mode 100644 index 000000000..af7552523 --- /dev/null +++ b/src/test/ui/type/type-check/cannot_infer_local_or_array.rs @@ -0,0 +1,3 @@ +fn main() { + let x = []; //~ ERROR type annotations needed +} diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr new file mode 100644 index 000000000..e823bad26 --- /dev/null +++ b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed for `[_; 0]` + --> $DIR/cannot_infer_local_or_array.rs:2:9 + | +LL | let x = []; + | ^ -- type must be known at this point + | +help: consider giving `x` an explicit type, where the placeholders `_` are specified + | +LL | let x: [_; 0] = []; + | ++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec.rs b/src/test/ui/type/type-check/cannot_infer_local_or_vec.rs new file mode 100644 index 000000000..e72ddabf3 --- /dev/null +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec.rs @@ -0,0 +1,4 @@ +fn main() { + let x = vec![]; + //~^ ERROR type annotations needed +} diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr new file mode 100644 index 000000000..b63d2a3b6 --- /dev/null +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed for `Vec<T>` + --> $DIR/cannot_infer_local_or_vec.rs:2:9 + | +LL | let x = vec![]; + | ^ + | +help: consider giving `x` an explicit type, where the type for type parameter `T` is specified + | +LL | let x: Vec<T> = vec![]; + | ++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.rs b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.rs new file mode 100644 index 000000000..d21456439 --- /dev/null +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.rs @@ -0,0 +1,4 @@ +fn main() { + let (x, ) = (vec![], ); + //~^ ERROR type annotations needed +} diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr new file mode 100644 index 000000000..be60cda68 --- /dev/null +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed for `(Vec<T>,)` + --> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:9 + | +LL | let (x, ) = (vec![], ); + | ^^^^^ + | +help: consider giving this pattern a type, where the type for type parameter `T` is specified + | +LL | let (x, ): (Vec<T>,) = (vec![], ); + | +++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type/type-check/issue-22897.rs b/src/test/ui/type/type-check/issue-22897.rs new file mode 100644 index 000000000..8171a0ef1 --- /dev/null +++ b/src/test/ui/type/type-check/issue-22897.rs @@ -0,0 +1,5 @@ +fn main() { } + +fn unconstrained_type() { + []; //~ ERROR type annotations needed +} diff --git a/src/test/ui/type/type-check/issue-22897.stderr b/src/test/ui/type/type-check/issue-22897.stderr new file mode 100644 index 000000000..fae7b7926 --- /dev/null +++ b/src/test/ui/type/type-check/issue-22897.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/issue-22897.rs:4:5 + | +LL | []; + | ^^ cannot infer type for array `[_; 0]` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type/type-check/issue-40294.rs b/src/test/ui/type/type-check/issue-40294.rs new file mode 100644 index 000000000..5493a4e5f --- /dev/null +++ b/src/test/ui/type/type-check/issue-40294.rs @@ -0,0 +1,13 @@ +trait Foo: Sized { + fn foo(self); +} + +fn foo<'a,'b,T>(x: &'a T, y: &'b T) + where &'a T : Foo, //~ ERROR type annotations needed + &'b T : Foo +{ + x.foo(); + y.foo(); +} + +fn main() { } diff --git a/src/test/ui/type/type-check/issue-40294.stderr b/src/test/ui/type/type-check/issue-40294.stderr new file mode 100644 index 000000000..75feb5698 --- /dev/null +++ b/src/test/ui/type/type-check/issue-40294.stderr @@ -0,0 +1,11 @@ +error[E0283]: type annotations needed: cannot satisfy `&'a T: Foo` + --> $DIR/issue-40294.rs:6:19 + | +LL | where &'a T : Foo, + | ^^^ + | + = note: cannot satisfy `&'a T: Foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/type/type-check/issue-41314.rs b/src/test/ui/type/type-check/issue-41314.rs new file mode 100644 index 000000000..cbd39f5f9 --- /dev/null +++ b/src/test/ui/type/type-check/issue-41314.rs @@ -0,0 +1,10 @@ +enum X { + Y(u32) +} + +fn main() { + match X::Y(0) { + X::Y { number } => {} + //~^ ERROR tuple variant `X::Y` written as struct variant + } +} diff --git a/src/test/ui/type/type-check/issue-41314.stderr b/src/test/ui/type/type-check/issue-41314.stderr new file mode 100644 index 000000000..4a9bf6106 --- /dev/null +++ b/src/test/ui/type/type-check/issue-41314.stderr @@ -0,0 +1,14 @@ +error[E0769]: tuple variant `X::Y` written as struct variant + --> $DIR/issue-41314.rs:7:9 + | +LL | X::Y { number } => {} + | ^^^^^^^^^^^^^^^ + | +help: use the tuple variant pattern syntax instead + | +LL | X::Y(number) => {} + | ~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0769`. diff --git a/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs b/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs new file mode 100644 index 000000000..c39ab9544 --- /dev/null +++ b/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs @@ -0,0 +1,27 @@ +fn main() { + let mut i: i64; + // Expected type is an inference variable `?T` + // because the `match` is used as a statement. + // This is the "initial" type of the `coercion`. + match i { + // Add `bool` to the overall `coercion`. + 0 => true, + + // Necessary to cause the ICE: + 1 => true, + + // Suppose that we had `let _: bool = match i { ... }`. + // In that case, as the expected type would be `bool`, + // we would suggest `i == 1` as a fix. + // + // However, no type error happens when checking `i = 1` because `expected == ?T`, + // which will unify with `typeof(i = 1) == ()`. + // + // However, in #67273, we would delay the unification of this arm with the above + // because we used the hitherto accumulated coercion as opposed to the "initial" type. + 2 => i = 1, + //~^ ERROR `match` arms have incompatible types + + _ => (), + } +} diff --git a/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.stderr b/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.stderr new file mode 100644 index 000000000..a431fe89c --- /dev/null +++ b/src/test/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.stderr @@ -0,0 +1,22 @@ +error[E0308]: `match` arms have incompatible types + --> $DIR/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs:22:14 + | +LL | / match i { +LL | | // Add `bool` to the overall `coercion`. +LL | | 0 => true, + | | ---- this is found to be of type `bool` +LL | | +LL | | // Necessary to cause the ICE: +LL | | 1 => true, + | | ---- this is found to be of type `bool` +... | +LL | | 2 => i = 1, + | | ^^^^^ expected `bool`, found `()` +... | +LL | | _ => (), +LL | | } + | |_____- `match` arms have incompatible types + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs new file mode 100644 index 000000000..e50cc5865 --- /dev/null +++ b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs @@ -0,0 +1,12 @@ +macro_rules! many_args { + ([$($t:tt)*]#$($h:tt)*) => { + many_args!{[$($t)*$($t)*]$($h)*} + }; + ([$($t:tt)*]) => { + fn _f($($t: ()),*) {} //~ ERROR function can not have more than 65535 arguments + } +} + +many_args!{[_]########## ######} + +fn main() {} diff --git a/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr new file mode 100644 index 000000000..615fd2ccb --- /dev/null +++ b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr @@ -0,0 +1,13 @@ +error: function can not have more than 65535 arguments + --> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:24 + | +LL | fn _f($($t: ()),*) {} + | ________________________^ +LL | | } +LL | | } +LL | | +LL | | many_args!{[_]########## ######} + | |____________^ + +error: aborting due to previous error + diff --git a/src/test/ui/type/type-check/missing_trait_impl.rs b/src/test/ui/type/type-check/missing_trait_impl.rs new file mode 100644 index 000000000..0e3e703a2 --- /dev/null +++ b/src/test/ui/type/type-check/missing_trait_impl.rs @@ -0,0 +1,16 @@ +fn main() { +} + +fn foo<T>(x: T, y: T) { + let z = x + y; //~ ERROR cannot add `T` to `T` +} + +fn bar<T>(x: T) { + x += x; //~ ERROR binary assignment operation `+=` cannot be applied to type `T` +} + +fn baz<T>(x: T) { + let y = -x; //~ ERROR cannot apply unary operator `-` to type `T` + let y = !x; //~ ERROR cannot apply unary operator `!` to type `T` + let y = *x; //~ ERROR type `T` cannot be dereferenced +} diff --git a/src/test/ui/type/type-check/missing_trait_impl.stderr b/src/test/ui/type/type-check/missing_trait_impl.stderr new file mode 100644 index 000000000..2b58cd418 --- /dev/null +++ b/src/test/ui/type/type-check/missing_trait_impl.stderr @@ -0,0 +1,58 @@ +error[E0369]: cannot add `T` to `T` + --> $DIR/missing_trait_impl.rs:5:15 + | +LL | let z = x + y; + | - ^ - T + | | + | T + | +help: consider restricting type parameter `T` + | +LL | fn foo<T: std::ops::Add>(x: T, y: T) { + | +++++++++++++++ + +error[E0368]: binary assignment operation `+=` cannot be applied to type `T` + --> $DIR/missing_trait_impl.rs:9:5 + | +LL | x += x; + | -^^^^^ + | | + | cannot use `+=` on type `T` + | +help: consider restricting type parameter `T` + | +LL | fn bar<T: std::ops::AddAssign>(x: T) { + | +++++++++++++++++++++ + +error[E0600]: cannot apply unary operator `-` to type `T` + --> $DIR/missing_trait_impl.rs:13:13 + | +LL | let y = -x; + | ^^ cannot apply unary operator `-` + | +help: consider restricting type parameter `T` + | +LL | fn baz<T: std::ops::Neg>(x: T) { + | +++++++++++++++ + +error[E0600]: cannot apply unary operator `!` to type `T` + --> $DIR/missing_trait_impl.rs:14:13 + | +LL | let y = !x; + | ^^ cannot apply unary operator `!` + | +help: consider restricting type parameter `T` + | +LL | fn baz<T: std::ops::Not>(x: T) { + | +++++++++++++++ + +error[E0614]: type `T` cannot be dereferenced + --> $DIR/missing_trait_impl.rs:15:13 + | +LL | let y = *x; + | ^^ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0368, E0369, E0600, E0614. +For more information about an error, try `rustc --explain E0368`. diff --git a/src/test/ui/type/type-check/unknown_type_for_closure.rs b/src/test/ui/type/type-check/unknown_type_for_closure.rs new file mode 100644 index 000000000..167687c18 --- /dev/null +++ b/src/test/ui/type/type-check/unknown_type_for_closure.rs @@ -0,0 +1,17 @@ +fn infer_in_arg() { + let x = |b: Vec<_>| {}; //~ ERROR E0282 +} + +fn empty_pattern() { + let x = |_| {}; //~ ERROR type annotations needed +} + +fn infer_ty() { + let x = |k: _| {}; //~ ERROR type annotations needed +} + +fn ambig_return() { + let x = || -> Vec<_> { Vec::new() }; //~ ERROR type annotations needed +} + +fn main() {} diff --git a/src/test/ui/type/type-check/unknown_type_for_closure.stderr b/src/test/ui/type/type-check/unknown_type_for_closure.stderr new file mode 100644 index 000000000..9ae97f390 --- /dev/null +++ b/src/test/ui/type/type-check/unknown_type_for_closure.stderr @@ -0,0 +1,37 @@ +error[E0282]: type annotations needed + --> $DIR/unknown_type_for_closure.rs:2:13 + | +LL | let x = |b: Vec<_>| {}; + | ^^^^^^^^^^^^^^ cannot infer type for struct `Vec<_>` + +error[E0282]: type annotations needed + --> $DIR/unknown_type_for_closure.rs:6:14 + | +LL | let x = |_| {}; + | ^ + | +help: consider giving this closure parameter an explicit type + | +LL | let x = |_: _| {}; + | +++ + +error[E0282]: type annotations needed + --> $DIR/unknown_type_for_closure.rs:10:14 + | +LL | let x = |k: _| {}; + | ^ cannot infer type + +error[E0282]: type annotations needed + --> $DIR/unknown_type_for_closure.rs:14:28 + | +LL | let x = || -> Vec<_> { Vec::new() }; + | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Vec` + | +help: consider specifying the generic argument + | +LL | let x = || -> Vec<_> { Vec::<T>::new() }; + | +++++ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type/type-dependent-def-issue-49241.rs b/src/test/ui/type/type-dependent-def-issue-49241.rs new file mode 100644 index 000000000..f37f093d9 --- /dev/null +++ b/src/test/ui/type/type-dependent-def-issue-49241.rs @@ -0,0 +1,6 @@ +fn main() { + let v = vec![0]; + const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant + let s: [u32; l] = v.into_iter().collect(); + //~^ERROR evaluation of constant value failed +} diff --git a/src/test/ui/type/type-dependent-def-issue-49241.stderr b/src/test/ui/type/type-dependent-def-issue-49241.stderr new file mode 100644 index 000000000..02f267c6c --- /dev/null +++ b/src/test/ui/type/type-dependent-def-issue-49241.stderr @@ -0,0 +1,18 @@ +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/type-dependent-def-issue-49241.rs:3:22 + | +LL | const l: usize = v.count(); + | ------- ^ non-constant value + | | + | help: consider using `let` instead of `const`: `let l` + +error[E0080]: evaluation of constant value failed + --> $DIR/type-dependent-def-issue-49241.rs:4:18 + | +LL | let s: [u32; l] = v.into_iter().collect(); + | ^ referenced constant has errors + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0080, E0435. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/type/type-error-break-tail.rs b/src/test/ui/type/type-error-break-tail.rs new file mode 100644 index 000000000..d4e3e93d0 --- /dev/null +++ b/src/test/ui/type/type-error-break-tail.rs @@ -0,0 +1,8 @@ +fn loop_ending() -> i32 { + loop { + if false { break; } //~ ERROR mismatched types + return 42; + } +} + +fn main() {} diff --git a/src/test/ui/type/type-error-break-tail.stderr b/src/test/ui/type/type-error-break-tail.stderr new file mode 100644 index 000000000..16dc6475c --- /dev/null +++ b/src/test/ui/type/type-error-break-tail.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/type-error-break-tail.rs:3:20 + | +LL | fn loop_ending() -> i32 { + | --- expected `i32` because of return type +LL | loop { +LL | if false { break; } + | ^^^^^ + | | + | expected `i32`, found `()` + | help: give it a value of the expected type: `break 42` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-mismatch-multiple.rs b/src/test/ui/type/type-mismatch-multiple.rs new file mode 100644 index 000000000..55d6ceef1 --- /dev/null +++ b/src/test/ui/type/type-mismatch-multiple.rs @@ -0,0 +1,7 @@ +// Checking that the compiler reports multiple type errors at once + +fn main() { let a: bool = 1; let b: i32 = true; } +//~^ ERROR mismatched types +//~| expected `bool`, found integer +//~| ERROR mismatched types +//~| expected `i32`, found `bool` diff --git a/src/test/ui/type/type-mismatch-multiple.stderr b/src/test/ui/type/type-mismatch-multiple.stderr new file mode 100644 index 000000000..2e8654d31 --- /dev/null +++ b/src/test/ui/type/type-mismatch-multiple.stderr @@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/type-mismatch-multiple.rs:3:27 + | +LL | fn main() { let a: bool = 1; let b: i32 = true; } + | ---- ^ expected `bool`, found integer + | | + | expected due to this + +error[E0308]: mismatched types + --> $DIR/type-mismatch-multiple.rs:3:43 + | +LL | fn main() { let a: bool = 1; let b: i32 = true; } + | --- ^^^^ expected `i32`, found `bool` + | | + | expected due to this + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-mismatch-same-crate-name.rs b/src/test/ui/type/type-mismatch-same-crate-name.rs new file mode 100644 index 000000000..c9cdc874c --- /dev/null +++ b/src/test/ui/type/type-mismatch-same-crate-name.rs @@ -0,0 +1,27 @@ +// aux-build:crate_a1.rs +// aux-build:crate_a2.rs + +// This tests the extra note reported when a type error deals with +// seemingly identical types. +// The main use case of this error is when there are two crates +// (generally different versions of the same crate) with the same name +// causing a type mismatch. Here, we simulate that error using block-scoped +// aliased `extern crate` declarations. + +fn main() { + let foo2 = {extern crate crate_a2 as a; a::Foo}; + let bar2 = {extern crate crate_a2 as a; a::bar()}; + { + extern crate crate_a1 as a; + a::try_foo(foo2); + //~^ ERROR mismatched types + //~| perhaps two different versions of crate `crate_a1` + //~| expected struct `main::a::Foo` + a::try_bar(bar2); + //~^ ERROR mismatched types + //~| perhaps two different versions of crate `crate_a1` + //~| expected trait `main::a::Bar` + //~| expected struct `Box<(dyn main::a::Bar + 'static)>` + //~| found struct `Box<dyn main::a::Bar>` + } +} diff --git a/src/test/ui/type/type-mismatch-same-crate-name.stderr b/src/test/ui/type/type-mismatch-same-crate-name.stderr new file mode 100644 index 000000000..783f747fa --- /dev/null +++ b/src/test/ui/type/type-mismatch-same-crate-name.stderr @@ -0,0 +1,35 @@ +error[E0308]: mismatched types + --> $DIR/type-mismatch-same-crate-name.rs:16:20 + | +LL | a::try_foo(foo2); + | ---------- ^^^^ expected struct `main::a::Foo`, found a different struct `main::a::Foo` + | | + | arguments to this function are incorrect + | + = note: perhaps two different versions of crate `crate_a1` are being used? +note: function defined here + --> $DIR/auxiliary/crate_a1.rs:10:8 + | +LL | pub fn try_foo(x: Foo){} + | ^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/type-mismatch-same-crate-name.rs:20:20 + | +LL | a::try_bar(bar2); + | ---------- ^^^^ expected trait `main::a::Bar`, found a different trait `main::a::Bar` + | | + | arguments to this function are incorrect + | + = note: expected struct `Box<(dyn main::a::Bar + 'static)>` + found struct `Box<dyn main::a::Bar>` + = note: perhaps two different versions of crate `crate_a1` are being used? +note: function defined here + --> $DIR/auxiliary/crate_a1.rs:11:8 + | +LL | pub fn try_bar(x: Box<Bar>){} + | ^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-mismatch.rs b/src/test/ui/type/type-mismatch.rs new file mode 100644 index 000000000..11bfa3a72 --- /dev/null +++ b/src/test/ui/type/type-mismatch.rs @@ -0,0 +1,78 @@ +#![allow(non_camel_case_types)] + +trait Qux {} +struct A; +struct B; +impl Qux for A {} +impl Qux for B {} + +struct Foo<T, U: Qux = A, V: Qux = B>(T, U, V); + +struct foo; +struct bar; + +fn want<T>(t: T) {} + +fn have_usize(f: usize) { + want::<foo>(f); //~ ERROR mismatched types + want::<bar>(f); //~ ERROR mismatched types + want::<Foo<usize>>(f); //~ ERROR mismatched types + want::<Foo<usize, B>>(f); //~ ERROR mismatched types + want::<Foo<foo>>(f); //~ ERROR mismatched types + want::<Foo<foo, B>>(f); //~ ERROR mismatched types + want::<Foo<bar>>(f); //~ ERROR mismatched types + want::<Foo<bar, B>>(f); //~ ERROR mismatched types +} + +fn have_foo(f: foo) { + want::<usize>(f); //~ ERROR mismatched types + want::<bar>(f); //~ ERROR mismatched types + want::<Foo<usize>>(f); //~ ERROR mismatched types + want::<Foo<usize, B>>(f); //~ ERROR mismatched types + want::<Foo<foo>>(f); //~ ERROR mismatched types + want::<Foo<foo, B>>(f); //~ ERROR mismatched types + want::<Foo<bar>>(f); //~ ERROR mismatched types + want::<Foo<bar, B>>(f); //~ ERROR mismatched types +} + +fn have_foo_foo(f: Foo<foo>) { + want::<usize>(f); //~ ERROR mismatched types + want::<foo>(f); //~ ERROR mismatched types + want::<bar>(f); //~ ERROR mismatched types + want::<Foo<usize>>(f); //~ ERROR mismatched types + want::<Foo<usize, B>>(f); //~ ERROR mismatched types + want::<Foo<foo, B>>(f); //~ ERROR mismatched types + want::<Foo<bar>>(f); //~ ERROR mismatched types + want::<Foo<bar, B>>(f); //~ ERROR mismatched types + want::<&Foo<foo>>(f); //~ ERROR mismatched types + want::<&Foo<foo, B>>(f); //~ ERROR mismatched types +} + +fn have_foo_foo_b(f: Foo<foo, B>) { + want::<usize>(f); //~ ERROR mismatched types + want::<foo>(f); //~ ERROR mismatched types + want::<bar>(f); //~ ERROR mismatched types + want::<Foo<usize>>(f); //~ ERROR mismatched types + want::<Foo<usize, B>>(f); //~ ERROR mismatched types + want::<Foo<foo>>(f); //~ ERROR mismatched types + want::<Foo<bar>>(f); //~ ERROR mismatched types + want::<Foo<bar, B>>(f); //~ ERROR mismatched types + want::<&Foo<foo>>(f); //~ ERROR mismatched types + want::<&Foo<foo, B>>(f); //~ ERROR mismatched types +} + +fn have_foo_foo_b_a(f: Foo<foo, B, A>) { + want::<usize>(f); //~ ERROR mismatched types + want::<foo>(f); //~ ERROR mismatched types + want::<bar>(f); //~ ERROR mismatched types + want::<Foo<usize>>(f); //~ ERROR mismatched types + want::<Foo<usize, B>>(f); //~ ERROR mismatched types + want::<Foo<foo>>(f); //~ ERROR mismatched types + want::<Foo<foo, B>>(f); //~ ERROR mismatched types + want::<Foo<bar>>(f); //~ ERROR mismatched types + want::<Foo<bar, B>>(f); //~ ERROR mismatched types + want::<&Foo<foo>>(f); //~ ERROR mismatched types + want::<&Foo<foo, B>>(f); //~ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/type/type-mismatch.stderr b/src/test/ui/type/type-mismatch.stderr new file mode 100644 index 000000000..6c187bad0 --- /dev/null +++ b/src/test/ui/type/type-mismatch.stderr @@ -0,0 +1,751 @@ +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:17:17 + | +LL | want::<foo>(f); + | ----------- ^ expected struct `foo`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:18:17 + | +LL | want::<bar>(f); + | ----------- ^ expected struct `bar`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:19:24 + | +LL | want::<Foo<usize>>(f); + | ------------------ ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize>` + found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:20:27 + | +LL | want::<Foo<usize, B>>(f); + | --------------------- ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize, B>` + found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:21:22 + | +LL | want::<Foo<foo>>(f); + | ---------------- ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<foo>` + found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:22:25 + | +LL | want::<Foo<foo, B>>(f); + | ------------------- ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<foo, B>` + found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:23:22 + | +LL | want::<Foo<bar>>(f); + | ---------------- ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar>` + found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:24:25 + | +LL | want::<Foo<bar, B>>(f); + | ------------------- ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar, B>` + found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:28:19 + | +LL | want::<usize>(f); + | ------------- ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:29:17 + | +LL | want::<bar>(f); + | ----------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:30:24 + | +LL | want::<Foo<usize>>(f); + | ------------------ ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize>` + found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:31:27 + | +LL | want::<Foo<usize, B>>(f); + | --------------------- ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize, B>` + found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:32:22 + | +LL | want::<Foo<foo>>(f); + | ---------------- ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<foo>` + found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:33:25 + | +LL | want::<Foo<foo, B>>(f); + | ------------------- ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<foo, B>` + found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:34:22 + | +LL | want::<Foo<bar>>(f); + | ---------------- ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar>` + found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:35:25 + | +LL | want::<Foo<bar, B>>(f); + | ------------------- ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar, B>` + found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:39:19 + | +LL | want::<usize>(f); + | ------------- ^ expected `usize`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected type `usize` + found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:40:17 + | +LL | want::<foo>(f); + | ----------- ^ expected struct `foo`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `foo` + found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:41:17 + | +LL | want::<bar>(f); + | ----------- ^ expected struct `bar`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `bar` + found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:42:24 + | +LL | want::<Foo<usize>>(f); + | ------------------ ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize>` + found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:43:27 + | +LL | want::<Foo<usize, B>>(f); + | --------------------- ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize, B>` + found struct `Foo<foo, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:44:25 + | +LL | want::<Foo<foo, B>>(f); + | ------------------- ^ expected struct `B`, found struct `A` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<_, B>` + found struct `Foo<_, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:45:22 + | +LL | want::<Foo<bar>>(f); + | ---------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar>` + found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:46:25 + | +LL | want::<Foo<bar, B>>(f); + | ------------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar, B>` + found struct `Foo<foo, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:47:23 + | +LL | want::<&Foo<foo>>(f); + | ----------------- ^ + | | | + | | expected `&Foo<foo>`, found struct `Foo` + | | help: consider borrowing here: `&f` + | arguments to this function are incorrect + | + = note: expected reference `&Foo<foo>` + found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:48:26 + | +LL | want::<&Foo<foo, B>>(f); + | -------------------- ^ expected `&Foo<foo, B>`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected reference `&Foo<foo, B>` + found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:52:19 + | +LL | want::<usize>(f); + | ------------- ^ expected `usize`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected type `usize` + found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:53:17 + | +LL | want::<foo>(f); + | ----------- ^ expected struct `foo`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `foo` + found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:54:17 + | +LL | want::<bar>(f); + | ----------- ^ expected struct `bar`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `bar` + found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:55:24 + | +LL | want::<Foo<usize>>(f); + | ------------------ ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize, A>` + found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:56:27 + | +LL | want::<Foo<usize, B>>(f); + | --------------------- ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize, _>` + found struct `Foo<foo, _>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:57:22 + | +LL | want::<Foo<foo>>(f); + | ---------------- ^ expected struct `A`, found struct `B` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<_, A>` + found struct `Foo<_, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:58:22 + | +LL | want::<Foo<bar>>(f); + | ---------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar, A>` + found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:59:25 + | +LL | want::<Foo<bar, B>>(f); + | ------------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar, _>` + found struct `Foo<foo, _>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:60:23 + | +LL | want::<&Foo<foo>>(f); + | ----------------- ^ expected `&Foo<foo>`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected reference `&Foo<foo>` + found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:61:26 + | +LL | want::<&Foo<foo, B>>(f); + | -------------------- ^ + | | | + | | expected `&Foo<foo, B>`, found struct `Foo` + | | help: consider borrowing here: `&f` + | arguments to this function are incorrect + | + = note: expected reference `&Foo<foo, B>` + found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:65:19 + | +LL | want::<usize>(f); + | ------------- ^ expected `usize`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected type `usize` + found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:66:17 + | +LL | want::<foo>(f); + | ----------- ^ expected struct `foo`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `foo` + found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:67:17 + | +LL | want::<bar>(f); + | ----------- ^ expected struct `bar`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `bar` + found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:68:24 + | +LL | want::<Foo<usize>>(f); + | ------------------ ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize, A, B>` + found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:69:27 + | +LL | want::<Foo<usize, B>>(f); + | --------------------- ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<usize, _, B>` + found struct `Foo<foo, _, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:70:22 + | +LL | want::<Foo<foo>>(f); + | ---------------- ^ expected struct `A`, found struct `B` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<_, A, B>` + found struct `Foo<_, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:71:25 + | +LL | want::<Foo<foo, B>>(f); + | ------------------- ^ expected struct `B`, found struct `A` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<_, _, B>` + found struct `Foo<_, _, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:72:22 + | +LL | want::<Foo<bar>>(f); + | ---------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar, A, B>` + found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:73:25 + | +LL | want::<Foo<bar, B>>(f); + | ------------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect + | + = note: expected struct `Foo<bar, _, B>` + found struct `Foo<foo, _, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:74:23 + | +LL | want::<&Foo<foo>>(f); + | ----------------- ^ expected `&Foo<foo>`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected reference `&Foo<foo>` + found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:75:26 + | +LL | want::<&Foo<foo, B>>(f); + | -------------------- ^ expected `&Foo<foo, B>`, found struct `Foo` + | | + | arguments to this function are incorrect + | + = note: expected reference `&Foo<foo, B>` + found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- + +error: aborting due to 47 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.rs b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.rs new file mode 100644 index 000000000..444453dc6 --- /dev/null +++ b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.rs @@ -0,0 +1,17 @@ +// Test a default that references `Self` which is then used in an +// object type. Issue #18956. In this case, the value is supplied by +// the user, but pretty-printing the type during the error message +// caused an ICE. + +trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; } + +impl MyAdd for i32 { + fn add(&self, other: &i32) -> i32 { *self + *other } +} + +fn main() { + let x: i32 = 5; + let y = x as dyn MyAdd<i32>; + //~^ ERROR E0038 + //~| ERROR cast to unsized type: `i32` as `dyn MyAdd<i32>` +} diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr new file mode 100644 index 000000000..8a296dc7e --- /dev/null +++ b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr @@ -0,0 +1,31 @@ +error[E0620]: cast to unsized type: `i32` as `dyn MyAdd<i32>` + --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:13 + | +LL | let y = x as dyn MyAdd<i32>; + | ^^^^^^^^^^^^^^^^^^^ + | +help: consider using a box or reference as appropriate + --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:13 + | +LL | let y = x as dyn MyAdd<i32>; + | ^ + +error[E0038]: the trait `MyAdd` cannot be made into an object + --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:18 + | +LL | let y = x as dyn MyAdd<i32>; + | ^^^^^^^^^^^^^^ `MyAdd` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:6:55 + | +LL | trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; } + | ----- ^^^^ ...because method `add` references the `Self` type in its return type + | | + | this trait cannot be made into an object... + = help: consider moving `add` to another trait + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0038, E0620. +For more information about an error, try `rustc --explain E0038`. diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self.rs b/src/test/ui/type/type-parameter-defaults-referencing-Self.rs new file mode 100644 index 000000000..e5c81556e --- /dev/null +++ b/src/test/ui/type/type-parameter-defaults-referencing-Self.rs @@ -0,0 +1,11 @@ +// Test a default that references `Self` which is then used in an object type. +// Issue #18956. + +trait Foo<T=Self> { + fn method(&self); +} + +fn foo(x: &dyn Foo) { } +//~^ ERROR the type parameter `T` must be explicitly specified + +fn main() { } diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self.stderr b/src/test/ui/type/type-parameter-defaults-referencing-Self.stderr new file mode 100644 index 000000000..67a4745b3 --- /dev/null +++ b/src/test/ui/type/type-parameter-defaults-referencing-Self.stderr @@ -0,0 +1,14 @@ +error[E0393]: the type parameter `T` must be explicitly specified + --> $DIR/type-parameter-defaults-referencing-Self.rs:8:16 + | +LL | trait Foo<T=Self> { + | ----------------- type parameter `T` must be specified for this +... +LL | fn foo(x: &dyn Foo) { } + | ^^^ help: set the type parameter to the desired type: `Foo<T>` + | + = note: because of the default `Self` reference, type parameters must be specified on object types + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0393`. diff --git a/src/test/ui/type/type-parameter-names.rs b/src/test/ui/type/type-parameter-names.rs new file mode 100644 index 000000000..b54a3fae0 --- /dev/null +++ b/src/test/ui/type/type-parameter-names.rs @@ -0,0 +1,12 @@ +// Test that we print out the names of type parameters correctly in +// our error messages. + +fn foo<Foo, Bar>(x: Foo) -> Bar { + x +//~^ ERROR mismatched types +//~| expected type parameter `Bar`, found type parameter `Foo` +//~| expected type parameter `Bar` +//~| found type parameter `Foo` +} + +fn main() {} diff --git a/src/test/ui/type/type-parameter-names.stderr b/src/test/ui/type/type-parameter-names.stderr new file mode 100644 index 000000000..f0ca8afca --- /dev/null +++ b/src/test/ui/type/type-parameter-names.stderr @@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/type-parameter-names.rs:5:5 + | +LL | fn foo<Foo, Bar>(x: Foo) -> Bar { + | --- --- --- expected `Bar` because of return type + | | | + | | expected type parameter + | found type parameter +LL | x + | ^ expected type parameter `Bar`, found type parameter `Foo` + | + = note: expected type parameter `Bar` + found type parameter `Foo` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-params-in-different-spaces-1.rs b/src/test/ui/type/type-params-in-different-spaces-1.rs new file mode 100644 index 000000000..6efd14d37 --- /dev/null +++ b/src/test/ui/type/type-params-in-different-spaces-1.rs @@ -0,0 +1,18 @@ +use std::ops::Add; + +trait BrokenAdd: Copy + Add<Output=Self> { + fn broken_add<T>(&self, rhs: T) -> Self { + *self + rhs //~ ERROR mismatched types + //~| expected type parameter `Self`, found type parameter `T` + //~| expected type parameter `Self` + //~| found type parameter `T` + } +} + +impl<T: Copy + Add<Output=T>> BrokenAdd for T {} + +pub fn main() { + let foo: u8 = 0; + let x: u8 = foo.broken_add("hello darkness my old friend".to_string()); + println!("{}", x); +} diff --git a/src/test/ui/type/type-params-in-different-spaces-1.stderr b/src/test/ui/type/type-params-in-different-spaces-1.stderr new file mode 100644 index 000000000..4e73e10a3 --- /dev/null +++ b/src/test/ui/type/type-params-in-different-spaces-1.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/type-params-in-different-spaces-1.rs:5:17 + | +LL | trait BrokenAdd: Copy + Add<Output=Self> { + | ---------------------------------------- expected type parameter +LL | fn broken_add<T>(&self, rhs: T) -> Self { + | - found type parameter +LL | *self + rhs + | ^^^ expected type parameter `Self`, found type parameter `T` + | + = note: expected type parameter `Self` + found type parameter `T` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-params-in-different-spaces-2.rs b/src/test/ui/type/type-params-in-different-spaces-2.rs new file mode 100644 index 000000000..1211e465b --- /dev/null +++ b/src/test/ui/type/type-params-in-different-spaces-2.rs @@ -0,0 +1,21 @@ +// Test static calls to make sure that we align the Self and input +// type parameters on a trait correctly. + +trait Tr<T> : Sized { + fn op(_: T) -> Self; +} + +trait A: Tr<Self> { + fn test<U>(u: U) -> Self { + Tr::op(u) //~ ERROR E0277 + } +} + +trait B<T>: Tr<T> { + fn test<U>(u: U) -> Self { + Tr::op(u) //~ ERROR E0277 + } +} + +fn main() { +} diff --git a/src/test/ui/type/type-params-in-different-spaces-2.stderr b/src/test/ui/type/type-params-in-different-spaces-2.stderr new file mode 100644 index 000000000..53610985f --- /dev/null +++ b/src/test/ui/type/type-params-in-different-spaces-2.stderr @@ -0,0 +1,25 @@ +error[E0277]: the trait bound `Self: Tr<U>` is not satisfied + --> $DIR/type-params-in-different-spaces-2.rs:10:9 + | +LL | Tr::op(u) + | ^^^^^^ the trait `Tr<U>` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn test<U>(u: U) -> Self where Self: Tr<U> { + | +++++++++++++++++ + +error[E0277]: the trait bound `Self: Tr<U>` is not satisfied + --> $DIR/type-params-in-different-spaces-2.rs:16:9 + | +LL | Tr::op(u) + | ^^^^^^ the trait `Tr<U>` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn test<U>(u: U) -> Self where Self: Tr<U> { + | +++++++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type/type-params-in-different-spaces-3.rs b/src/test/ui/type/type-params-in-different-spaces-3.rs new file mode 100644 index 000000000..ac7b0c11f --- /dev/null +++ b/src/test/ui/type/type-params-in-different-spaces-3.rs @@ -0,0 +1,7 @@ +trait Tr : Sized { + fn test<X>(u: X) -> Self { + u //~ ERROR mismatched types + } +} + +fn main() {} diff --git a/src/test/ui/type/type-params-in-different-spaces-3.stderr b/src/test/ui/type/type-params-in-different-spaces-3.stderr new file mode 100644 index 000000000..c538d6731 --- /dev/null +++ b/src/test/ui/type/type-params-in-different-spaces-3.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/type-params-in-different-spaces-3.rs:3:9 + | +LL | trait Tr : Sized { + | ---------------- expected type parameter +LL | fn test<X>(u: X) -> Self { + | - ---- expected `Self` because of return type + | | + | found type parameter +LL | u + | ^ expected type parameter `Self`, found type parameter `X` + | + = note: expected type parameter `Self` + found type parameter `X` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-path-err-node-types.rs b/src/test/ui/type/type-path-err-node-types.rs new file mode 100644 index 000000000..b3795772e --- /dev/null +++ b/src/test/ui/type/type-path-err-node-types.rs @@ -0,0 +1,26 @@ +// Type arguments in unresolved entities (reporting errors before type checking) +// should have their types recorded. + +trait Tr<T> {} + +fn local_type() { + let _: Nonexistent<u8, Assoc = u16>; //~ ERROR cannot find type `Nonexistent` in this scope +} + +fn ufcs_trait() { + <u8 as Tr<u8>>::nonexistent(); //~ ERROR cannot find method or associated constant `nonexistent` +} + +fn ufcs_item() { + NonExistent::Assoc::<u8>; //~ ERROR undeclared type `NonExistent` +} + +fn method() { + nonexistent.nonexistent::<u8>(); //~ ERROR cannot find value `nonexistent` +} + +fn closure() { + let _ = |a, b: _| -> _ { 0 }; //~ ERROR type annotations needed +} + +fn main() {} diff --git a/src/test/ui/type/type-path-err-node-types.stderr b/src/test/ui/type/type-path-err-node-types.stderr new file mode 100644 index 000000000..c1ae10efa --- /dev/null +++ b/src/test/ui/type/type-path-err-node-types.stderr @@ -0,0 +1,39 @@ +error[E0433]: failed to resolve: use of undeclared type `NonExistent` + --> $DIR/type-path-err-node-types.rs:15:5 + | +LL | NonExistent::Assoc::<u8>; + | ^^^^^^^^^^^ use of undeclared type `NonExistent` + +error[E0412]: cannot find type `Nonexistent` in this scope + --> $DIR/type-path-err-node-types.rs:7:12 + | +LL | let _: Nonexistent<u8, Assoc = u16>; + | ^^^^^^^^^^^ not found in this scope + +error[E0576]: cannot find method or associated constant `nonexistent` in trait `Tr` + --> $DIR/type-path-err-node-types.rs:11:21 + | +LL | <u8 as Tr<u8>>::nonexistent(); + | ^^^^^^^^^^^ not found in `Tr` + +error[E0425]: cannot find value `nonexistent` in this scope + --> $DIR/type-path-err-node-types.rs:19:5 + | +LL | nonexistent.nonexistent::<u8>(); + | ^^^^^^^^^^^ not found in this scope + +error[E0282]: type annotations needed + --> $DIR/type-path-err-node-types.rs:23:14 + | +LL | let _ = |a, b: _| -> _ { 0 }; + | ^ + | +help: consider giving this closure parameter an explicit type + | +LL | let _ = |a: _, b: _| -> _ { 0 }; + | +++ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0282, E0412, E0425, E0433, E0576. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/type/type-recursive-box-shadowed.rs b/src/test/ui/type/type-recursive-box-shadowed.rs new file mode 100644 index 000000000..e141c2149 --- /dev/null +++ b/src/test/ui/type/type-recursive-box-shadowed.rs @@ -0,0 +1,12 @@ +//FIXME(compiler-errors): This fixup should suggest the full box path, not just `Box` + +struct Box<T> { + t: T, +} + +struct Foo { + //~^ ERROR recursive type `Foo` has infinite size + inner: Foo, +} + +fn main() {} diff --git a/src/test/ui/type/type-recursive-box-shadowed.stderr b/src/test/ui/type/type-recursive-box-shadowed.stderr new file mode 100644 index 000000000..c22d848f3 --- /dev/null +++ b/src/test/ui/type/type-recursive-box-shadowed.stderr @@ -0,0 +1,17 @@ +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 + | +LL | inner: Box<Foo>, + | ++++ + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/ui/type/type-recursive.rs b/src/test/ui/type/type-recursive.rs new file mode 100644 index 000000000..e8084f0d0 --- /dev/null +++ b/src/test/ui/type/type-recursive.rs @@ -0,0 +1,30 @@ +struct T1 { //~ ERROR E0072 + foo: isize, + foolish: T1, +} + +struct T2 { //~ ERROR E0072 + inner: Option<T2>, +} + +type OptionT3 = Option<T3>; + +struct T3 { //~ ERROR E0072 + inner: OptionT3, +} + +struct T4(Option<T4>); //~ ERROR E0072 + +enum T5 { //~ ERROR E0072 + Variant(Option<T5>), +} + +enum T6 { //~ ERROR E0072 + Variant{ field: Option<T6> }, +} + +struct T7 { //~ ERROR E0072 + foo: std::cell::Cell<Option<T7>>, +} + +fn main() { } diff --git a/src/test/ui/type/type-recursive.stderr b/src/test/ui/type/type-recursive.stderr new file mode 100644 index 000000000..320271028 --- /dev/null +++ b/src/test/ui/type/type-recursive.stderr @@ -0,0 +1,95 @@ +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 + | +LL | foolish: Box<T1>, + | ++++ + + +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 + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T2` representable + | +LL | inner: Option<Box<T2>>, + | ++++ + + +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 + | +LL | inner: Box<OptionT3>, + | ++++ + + +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 + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T4` representable + | +LL | struct T4(Option<Box<T4>>); + | ++++ + + +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 + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T5` representable + | +LL | Variant(Option<Box<T5>>), + | ++++ + + +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 + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T6` representable + | +LL | Variant{ field: Option<Box<T6>> }, + | ++++ + + +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 + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `T7` representable + | +LL | foo: Box<std::cell::Cell<Option<T7>>>, + | ++++ + + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/ui/type/type-shadow.rs b/src/test/ui/type/type-shadow.rs new file mode 100644 index 000000000..48a68a390 --- /dev/null +++ b/src/test/ui/type/type-shadow.rs @@ -0,0 +1,8 @@ +fn main() { + type X = isize; + type Y = X; + if true { + type X = &'static str; + let y: Y = "hello"; //~ ERROR mismatched types + } +} diff --git a/src/test/ui/type/type-shadow.stderr b/src/test/ui/type/type-shadow.stderr new file mode 100644 index 000000000..25b4bff4d --- /dev/null +++ b/src/test/ui/type/type-shadow.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/type-shadow.rs:6:20 + | +LL | let y: Y = "hello"; + | - ^^^^^^^ expected `isize`, found `&str` + | | + | expected due to this + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-unsatisfiable.rs b/src/test/ui/type/type-unsatisfiable.rs new file mode 100644 index 000000000..7fbbb50dc --- /dev/null +++ b/src/test/ui/type/type-unsatisfiable.rs @@ -0,0 +1,59 @@ +// revisions: lib usage +//[lib] compile-flags: --crate-type=lib +//[lib] build-pass + +use std::ops::Sub; +trait Vector2 { + type ScalarType; + + fn from_values(x: Self::ScalarType, y: Self::ScalarType) -> Self + where + Self: Sized; + + fn x(&self) -> Self::ScalarType; + fn y(&self) -> Self::ScalarType; +} + +impl<T> Sub for dyn Vector2<ScalarType = T> +where + T: Sub<Output = T>, + (dyn Vector2<ScalarType = T>): Sized, +{ + type Output = dyn Vector2<ScalarType = T>; + + fn sub(self, rhs: Self) -> Self::Output { + Self::from_values(self.x() - rhs.x(), self.y() - rhs.y()) + } +} + +struct Vec2 { + x: i32, + y: i32, +} + +impl Vector2 for Vec2 { + type ScalarType = i32; + + fn from_values(x: Self::ScalarType, y: Self::ScalarType) -> Self + where + Self: Sized, + { + Self { x, y } + } + + fn x(&self) -> Self::ScalarType { + self.x + } + fn y(&self) -> Self::ScalarType { + self.y + } +} + +#[cfg(usage)] +fn main() { + let hey: Box<dyn Vector2<ScalarType = i32>> = Box::new(Vec2 { x: 1, y: 2 }); + let word: Box<dyn Vector2<ScalarType = i32>> = Box::new(Vec2 { x: 1, y: 2 }); + + let bar = *hey - *word; + //[usage]~^ ERROR cannot subtract +} diff --git a/src/test/ui/type/type-unsatisfiable.usage.stderr b/src/test/ui/type/type-unsatisfiable.usage.stderr new file mode 100644 index 000000000..56e2e30af --- /dev/null +++ b/src/test/ui/type/type-unsatisfiable.usage.stderr @@ -0,0 +1,11 @@ +error[E0369]: cannot subtract `(dyn Vector2<ScalarType = i32> + 'static)` from `dyn Vector2<ScalarType = i32>` + --> $DIR/type-unsatisfiable.rs:57:20 + | +LL | let bar = *hey - *word; + | ---- ^ ----- (dyn Vector2<ScalarType = i32> + 'static) + | | + | dyn Vector2<ScalarType = i32> + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/type_length_limit.polonius.stderr b/src/test/ui/type_length_limit.polonius.stderr new file mode 100644 index 000000000..82d066b2a --- /dev/null +++ b/src/test/ui/type_length_limit.polonius.stderr @@ -0,0 +1,11 @@ +error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((...,....., ...), ..., ...), ..., ...)>>` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | +LL | pub fn drop<T>(_x: T) {} + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit.polonius/type_length_limit.long-type.txt' + = help: consider adding a `#![type_length_limit="8"]` attribute to your crate + +error: aborting due to previous error + diff --git a/src/test/ui/type_length_limit.rs b/src/test/ui/type_length_limit.rs new file mode 100644 index 000000000..ce6fdf811 --- /dev/null +++ b/src/test/ui/type_length_limit.rs @@ -0,0 +1,29 @@ +// build-fail +// error-pattern: reached the type-length limit while instantiating +// compile-flags: -Copt-level=0 +// normalize-stderr-test: ".nll/" -> "/" + +// Test that the type length limit can be changed. +// The exact type depends on optimizations, so disable them. + +#![allow(dead_code)] +#![type_length_limit="4"] + +macro_rules! link { + ($id:ident, $t:ty) => { + pub type $id = ($t, $t, $t); + } +} + +link! { A, B } +link! { B, C } +link! { C, D } +link! { D, E } +link! { E, F } +link! { F, G } + +pub struct G; + +fn main() { + drop::<Option<A>>(None); +} diff --git a/src/test/ui/type_length_limit.stderr b/src/test/ui/type_length_limit.stderr new file mode 100644 index 000000000..1508b84c1 --- /dev/null +++ b/src/test/ui/type_length_limit.stderr @@ -0,0 +1,20 @@ +error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((...,....., ...), ..., ...), ..., ...)>>` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + | +LL | pub fn drop<T>(_x: T) {} + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt' + = help: consider adding a `#![type_length_limit="8"]` attribute to your crate + +error: reached the type-length limit while instantiating `<[closure@std::rt::lang_start<()...e<()>>::call_once - shim(vtable)` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt' + = help: consider adding a `#![type_length_limit="8"]` attribute to your crate + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/typeck/assign-non-lval-derefmut.fixed b/src/test/ui/typeck/assign-non-lval-derefmut.fixed new file mode 100644 index 000000000..0c23199af --- /dev/null +++ b/src/test/ui/typeck/assign-non-lval-derefmut.fixed @@ -0,0 +1,15 @@ +// run-rustfix + +fn main() { + let x = std::sync::Mutex::new(1usize); + *x.lock().unwrap() = 2; + //~^ ERROR invalid left-hand side of assignment + *x.lock().unwrap() += 1; + //~^ ERROR binary assignment operation `+=` cannot be applied to type `MutexGuard<'_, usize>` + + let mut y = x.lock().unwrap(); + *y = 2; + //~^ ERROR mismatched types + *y += 1; + //~^ ERROR binary assignment operation `+=` cannot be applied to type `MutexGuard<'_, usize>` +} diff --git a/src/test/ui/typeck/assign-non-lval-derefmut.rs b/src/test/ui/typeck/assign-non-lval-derefmut.rs new file mode 100644 index 000000000..ec1882f52 --- /dev/null +++ b/src/test/ui/typeck/assign-non-lval-derefmut.rs @@ -0,0 +1,15 @@ +// run-rustfix + +fn main() { + let x = std::sync::Mutex::new(1usize); + x.lock().unwrap() = 2; + //~^ ERROR invalid left-hand side of assignment + x.lock().unwrap() += 1; + //~^ ERROR binary assignment operation `+=` cannot be applied to type `MutexGuard<'_, usize>` + + let mut y = x.lock().unwrap(); + y = 2; + //~^ ERROR mismatched types + y += 1; + //~^ ERROR binary assignment operation `+=` cannot be applied to type `MutexGuard<'_, usize>` +} diff --git a/src/test/ui/typeck/assign-non-lval-derefmut.stderr b/src/test/ui/typeck/assign-non-lval-derefmut.stderr new file mode 100644 index 000000000..a6fcdfe21 --- /dev/null +++ b/src/test/ui/typeck/assign-non-lval-derefmut.stderr @@ -0,0 +1,58 @@ +error[E0070]: invalid left-hand side of assignment + --> $DIR/assign-non-lval-derefmut.rs:5:23 + | +LL | x.lock().unwrap() = 2; + | ----------------- ^ + | | + | cannot assign to this expression + | +help: consider dereferencing here to assign to the mutably borrowed value + | +LL | *x.lock().unwrap() = 2; + | + + +error[E0368]: binary assignment operation `+=` cannot be applied to type `MutexGuard<'_, usize>` + --> $DIR/assign-non-lval-derefmut.rs:7:5 + | +LL | x.lock().unwrap() += 1; + | -----------------^^^^^ + | | + | cannot use `+=` on type `MutexGuard<'_, usize>` + | +help: `+=` can be used on `usize`, you can dereference `x.lock().unwrap()` + | +LL | *x.lock().unwrap() += 1; + | + + +error[E0308]: mismatched types + --> $DIR/assign-non-lval-derefmut.rs:11:9 + | +LL | let mut y = x.lock().unwrap(); + | ----------------- expected due to this value +LL | y = 2; + | ^ expected struct `MutexGuard`, found integer + | + = note: expected struct `MutexGuard<'_, usize>` + found type `{integer}` +help: consider dereferencing here to assign to the mutably borrowed value + | +LL | *y = 2; + | + + +error[E0368]: binary assignment operation `+=` cannot be applied to type `MutexGuard<'_, usize>` + --> $DIR/assign-non-lval-derefmut.rs:13:5 + | +LL | y += 1; + | -^^^^^ + | | + | cannot use `+=` on type `MutexGuard<'_, usize>` + | +help: `+=` can be used on `usize`, you can dereference `y` + | +LL | *y += 1; + | + + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0070, E0308, E0368. +For more information about an error, try `rustc --explain E0070`. diff --git a/src/test/ui/typeck/assign-non-lval-mut-ref.fixed b/src/test/ui/typeck/assign-non-lval-mut-ref.fixed new file mode 100644 index 000000000..10c7b9dbf --- /dev/null +++ b/src/test/ui/typeck/assign-non-lval-mut-ref.fixed @@ -0,0 +1,15 @@ +// run-rustfix + +fn main() { + let mut x = vec![1usize]; + *x.last_mut().unwrap() = 2; + //~^ ERROR invalid left-hand side of assignment + *x.last_mut().unwrap() += 1; + //~^ ERROR binary assignment operation `+=` cannot be applied to type `&mut usize` + + let y = x.last_mut().unwrap(); + *y = 2; + //~^ ERROR mismatched types + *y += 1; + //~^ ERROR binary assignment operation `+=` cannot be applied to type `&mut usize` +} diff --git a/src/test/ui/typeck/assign-non-lval-mut-ref.rs b/src/test/ui/typeck/assign-non-lval-mut-ref.rs new file mode 100644 index 000000000..bceff0ef0 --- /dev/null +++ b/src/test/ui/typeck/assign-non-lval-mut-ref.rs @@ -0,0 +1,15 @@ +// run-rustfix + +fn main() { + let mut x = vec![1usize]; + x.last_mut().unwrap() = 2; + //~^ ERROR invalid left-hand side of assignment + x.last_mut().unwrap() += 1; + //~^ ERROR binary assignment operation `+=` cannot be applied to type `&mut usize` + + let y = x.last_mut().unwrap(); + y = 2; + //~^ ERROR mismatched types + y += 1; + //~^ ERROR binary assignment operation `+=` cannot be applied to type `&mut usize` +} diff --git a/src/test/ui/typeck/assign-non-lval-mut-ref.stderr b/src/test/ui/typeck/assign-non-lval-mut-ref.stderr new file mode 100644 index 000000000..be2e9fe95 --- /dev/null +++ b/src/test/ui/typeck/assign-non-lval-mut-ref.stderr @@ -0,0 +1,56 @@ +error[E0070]: invalid left-hand side of assignment + --> $DIR/assign-non-lval-mut-ref.rs:5:27 + | +LL | x.last_mut().unwrap() = 2; + | --------------------- ^ + | | + | cannot assign to this expression + | +help: consider dereferencing here to assign to the mutably borrowed value + | +LL | *x.last_mut().unwrap() = 2; + | + + +error[E0368]: binary assignment operation `+=` cannot be applied to type `&mut usize` + --> $DIR/assign-non-lval-mut-ref.rs:7:5 + | +LL | x.last_mut().unwrap() += 1; + | ---------------------^^^^^ + | | + | cannot use `+=` on type `&mut usize` + | +help: `+=` can be used on `usize`, you can dereference `x.last_mut().unwrap()` + | +LL | *x.last_mut().unwrap() += 1; + | + + +error[E0308]: mismatched types + --> $DIR/assign-non-lval-mut-ref.rs:11:9 + | +LL | let y = x.last_mut().unwrap(); + | --------------------- expected due to this value +LL | y = 2; + | ^ expected `&mut usize`, found integer + | +help: consider dereferencing here to assign to the mutably borrowed value + | +LL | *y = 2; + | + + +error[E0368]: binary assignment operation `+=` cannot be applied to type `&mut usize` + --> $DIR/assign-non-lval-mut-ref.rs:13:5 + | +LL | y += 1; + | -^^^^^ + | | + | cannot use `+=` on type `&mut usize` + | +help: `+=` can be used on `usize`, you can dereference `y` + | +LL | *y += 1; + | + + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0070, E0308, E0368. +For more information about an error, try `rustc --explain E0070`. diff --git a/src/test/ui/typeck/autoderef-with-param-env-error.rs b/src/test/ui/typeck/autoderef-with-param-env-error.rs new file mode 100644 index 000000000..ec96c61c6 --- /dev/null +++ b/src/test/ui/typeck/autoderef-with-param-env-error.rs @@ -0,0 +1,9 @@ +fn foo() +where + T: Send, + //~^ cannot find type `T` in this scope +{ + let s = "abc".to_string(); +} + +fn main() {} diff --git a/src/test/ui/typeck/autoderef-with-param-env-error.stderr b/src/test/ui/typeck/autoderef-with-param-env-error.stderr new file mode 100644 index 000000000..cde800336 --- /dev/null +++ b/src/test/ui/typeck/autoderef-with-param-env-error.stderr @@ -0,0 +1,12 @@ +error[E0412]: cannot find type `T` in this scope + --> $DIR/autoderef-with-param-env-error.rs:3:5 + | +LL | fn foo() + | - help: you might be missing a type parameter: `<T>` +LL | where +LL | T: Send, + | ^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/typeck/auxiliary/issue-36708.rs b/src/test/ui/typeck/auxiliary/issue-36708.rs new file mode 100644 index 000000000..bd8580f97 --- /dev/null +++ b/src/test/ui/typeck/auxiliary/issue-36708.rs @@ -0,0 +1,5 @@ +#![crate_type = "lib"] + +pub trait Foo { + fn foo(); +} diff --git a/src/test/ui/typeck/auxiliary/issue-81943-lib.rs b/src/test/ui/typeck/auxiliary/issue-81943-lib.rs new file mode 100644 index 000000000..521c54f89 --- /dev/null +++ b/src/test/ui/typeck/auxiliary/issue-81943-lib.rs @@ -0,0 +1,7 @@ +pub fn g(t: i32) -> i32 { t } +// This function imitates `dbg!` so that future changes +// to its macro definition won't make this test a dud. +#[macro_export] +macro_rules! d { + ($e:expr) => { match $e { x => { $crate::g(x) } } } +} diff --git a/src/test/ui/typeck/auxiliary/tdticc_coherence_lib.rs b/src/test/ui/typeck/auxiliary/tdticc_coherence_lib.rs new file mode 100644 index 000000000..ef2cd415f --- /dev/null +++ b/src/test/ui/typeck/auxiliary/tdticc_coherence_lib.rs @@ -0,0 +1,6 @@ +#![feature(auto_traits, core)] +#![crate_type = "rlib"] + +pub auto trait DefaultedTrait { } + +pub struct Something<T> { t: T } diff --git a/src/test/ui/typeck/auxiliary/xcrate-issue-43189-a.rs b/src/test/ui/typeck/auxiliary/xcrate-issue-43189-a.rs new file mode 100644 index 000000000..9ab570fd1 --- /dev/null +++ b/src/test/ui/typeck/auxiliary/xcrate-issue-43189-a.rs @@ -0,0 +1,7 @@ +#![crate_type="lib"] + + +pub trait A { + fn a(&self) {} +} +impl A for () {} diff --git a/src/test/ui/typeck/auxiliary/xcrate-issue-43189-b.rs b/src/test/ui/typeck/auxiliary/xcrate-issue-43189-b.rs new file mode 100644 index 000000000..31dfb050b --- /dev/null +++ b/src/test/ui/typeck/auxiliary/xcrate-issue-43189-b.rs @@ -0,0 +1,3 @@ +#![crate_type="lib"] + +pub extern crate xcrate_issue_43189_a; diff --git a/src/test/ui/typeck/auxiliary/xcrate-issue-46112-rexport-core.rs b/src/test/ui/typeck/auxiliary/xcrate-issue-46112-rexport-core.rs new file mode 100644 index 000000000..2b517b578 --- /dev/null +++ b/src/test/ui/typeck/auxiliary/xcrate-issue-46112-rexport-core.rs @@ -0,0 +1,3 @@ +#![crate_type="lib"] + +pub extern crate core; diff --git a/src/test/ui/typeck/auxiliary/xcrate-issue-61711-b.rs b/src/test/ui/typeck/auxiliary/xcrate-issue-61711-b.rs new file mode 100644 index 000000000..88a040529 --- /dev/null +++ b/src/test/ui/typeck/auxiliary/xcrate-issue-61711-b.rs @@ -0,0 +1,5 @@ +// edition:2018 +#![crate_type="lib"] +#![crate_name="xcrate_issue_61711_b"] +pub struct Struct; +pub use crate as alias; diff --git a/src/test/ui/typeck/call-block.rs b/src/test/ui/typeck/call-block.rs new file mode 100644 index 000000000..0390d7db0 --- /dev/null +++ b/src/test/ui/typeck/call-block.rs @@ -0,0 +1,3 @@ +fn main() { + let _ = {42}(); //~ ERROR expected function, found `{integer}` +} diff --git a/src/test/ui/typeck/call-block.stderr b/src/test/ui/typeck/call-block.stderr new file mode 100644 index 000000000..68984bc1c --- /dev/null +++ b/src/test/ui/typeck/call-block.stderr @@ -0,0 +1,11 @@ +error[E0618]: expected function, found `{integer}` + --> $DIR/call-block.rs:2:13 + | +LL | let _ = {42}(); + | ^^^^-- + | | + | call expression requires function + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0618`. diff --git a/src/test/ui/typeck/conversion-methods.rs b/src/test/ui/typeck/conversion-methods.rs new file mode 100644 index 000000000..46c2e511f --- /dev/null +++ b/src/test/ui/typeck/conversion-methods.rs @@ -0,0 +1,13 @@ +use std::path::{Path, PathBuf}; + + +fn main() { + let _tis_an_instants_play: String = "'Tis a fond Ambush—"; //~ ERROR mismatched types + let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise"); + //~^ ERROR mismatched types + + let _but_should_the_play: String = 2; // Perhaps surprisingly, we suggest .to_string() here + //~^ ERROR mismatched types + + let _prove_piercing_earnest: Vec<usize> = &[1, 2, 3]; //~ ERROR mismatched types +} diff --git a/src/test/ui/typeck/conversion-methods.stderr b/src/test/ui/typeck/conversion-methods.stderr new file mode 100644 index 000000000..091502bdd --- /dev/null +++ b/src/test/ui/typeck/conversion-methods.stderr @@ -0,0 +1,45 @@ +error[E0308]: mismatched types + --> $DIR/conversion-methods.rs:5:41 + | +LL | let _tis_an_instants_play: String = "'Tis a fond Ambush—"; + | ------ ^^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_string()` + | | | + | | expected struct `String`, found `&str` + | expected due to this + +error[E0308]: mismatched types + --> $DIR/conversion-methods.rs:6:40 + | +LL | let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise"); + | ------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_path_buf()` + | | | + | | expected struct `PathBuf`, found `&Path` + | expected due to this + +error[E0308]: mismatched types + --> $DIR/conversion-methods.rs:9:40 + | +LL | let _but_should_the_play: String = 2; // Perhaps surprisingly, we suggest .to_string() here + | ------ ^- help: try using a conversion method: `.to_string()` + | | | + | | expected struct `String`, found integer + | expected due to this + +error[E0308]: mismatched types + --> $DIR/conversion-methods.rs:12:47 + | +LL | let _prove_piercing_earnest: Vec<usize> = &[1, 2, 3]; + | ---------- ^^^^^^^^^^ expected struct `Vec`, found `&[{integer}; 3]` + | | + | expected due to this + | + = note: expected struct `Vec<usize>` + found reference `&[{integer}; 3]` +help: try using a conversion method + | +LL | let _prove_piercing_earnest: Vec<usize> = (&[1, 2, 3]).to_vec(); + | + ++++++++++ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/deref-multi.rs b/src/test/ui/typeck/deref-multi.rs new file mode 100644 index 000000000..3dc4771fe --- /dev/null +++ b/src/test/ui/typeck/deref-multi.rs @@ -0,0 +1,26 @@ +fn a(x: &&i32) -> i32 { + x + //~^ ERROR mismatched types +} + +fn a2(x: &&&&&i32) -> i32 { + x + //~^ ERROR mismatched types +} + +fn b(x: &i32) -> i32 { + &x + //~^ ERROR mismatched types +} + +fn c(x: Box<i32>) -> i32 { + &x + //~^ ERROR mismatched types +} + +fn d(x: std::sync::Mutex<&i32>) -> i32 { + x.lock().unwrap() + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/typeck/deref-multi.stderr b/src/test/ui/typeck/deref-multi.stderr new file mode 100644 index 000000000..bd6575c73 --- /dev/null +++ b/src/test/ui/typeck/deref-multi.stderr @@ -0,0 +1,72 @@ +error[E0308]: mismatched types + --> $DIR/deref-multi.rs:2:5 + | +LL | fn a(x: &&i32) -> i32 { + | --- expected `i32` because of return type +LL | x + | ^ expected `i32`, found `&&i32` + | +help: consider dereferencing the borrow + | +LL | **x + | ++ + +error[E0308]: mismatched types + --> $DIR/deref-multi.rs:7:5 + | +LL | fn a2(x: &&&&&i32) -> i32 { + | --- expected `i32` because of return type +LL | x + | ^ expected `i32`, found `&&&&&i32` + | +help: consider dereferencing the borrow + | +LL | *****x + | +++++ + +error[E0308]: mismatched types + --> $DIR/deref-multi.rs:12:5 + | +LL | fn b(x: &i32) -> i32 { + | --- expected `i32` because of return type +LL | &x + | ^^ expected `i32`, found `&&i32` + | +help: consider removing the `&` and dereferencing the borrow instead + | +LL | *x + | ~ + +error[E0308]: mismatched types + --> $DIR/deref-multi.rs:17:5 + | +LL | fn c(x: Box<i32>) -> i32 { + | --- expected `i32` because of return type +LL | &x + | ^^ expected `i32`, found `&Box<i32>` + | + = note: expected type `i32` + found reference `&Box<i32>` +help: consider removing the `&` and dereferencing the borrow instead + | +LL | *x + | ~ + +error[E0308]: mismatched types + --> $DIR/deref-multi.rs:22:5 + | +LL | fn d(x: std::sync::Mutex<&i32>) -> i32 { + | --- expected `i32` because of return type +LL | x.lock().unwrap() + | ^^^^^^^^^^^^^^^^^ expected `i32`, found struct `MutexGuard` + | + = note: expected type `i32` + found struct `MutexGuard<'_, &i32>` +help: consider dereferencing the type + | +LL | **x.lock().unwrap() + | ++ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/do-not-suggest-adding-missing-zero-to-floating-point-number.rs b/src/test/ui/typeck/do-not-suggest-adding-missing-zero-to-floating-point-number.rs new file mode 100644 index 000000000..501f4b6ef --- /dev/null +++ b/src/test/ui/typeck/do-not-suggest-adding-missing-zero-to-floating-point-number.rs @@ -0,0 +1,21 @@ +macro_rules! num { () => { 1 } } + +fn main() { + let x = 1i32; + x.e10; //~ERROR `i32` is a primitive type and therefore doesn't have fields + + let y = 1; + y.e10; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields + + 2u32.e10; //~ERROR `u32` is a primitive type and therefore doesn't have fields + + num!().e10; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields + + 2.e10foo; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields + + 42._; + //~^ERROR expected identifier, found reserved identifier `_` + //~|ERROR `{integer}` is a primitive type and therefore doesn't have fields + + 42.a; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields +} diff --git a/src/test/ui/typeck/do-not-suggest-adding-missing-zero-to-floating-point-number.stderr b/src/test/ui/typeck/do-not-suggest-adding-missing-zero-to-floating-point-number.stderr new file mode 100644 index 000000000..1ef1d4c28 --- /dev/null +++ b/src/test/ui/typeck/do-not-suggest-adding-missing-zero-to-floating-point-number.stderr @@ -0,0 +1,51 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:16:8 + | +LL | 42._; + | ^ expected identifier, found reserved identifier + +error[E0610]: `i32` is a primitive type and therefore doesn't have fields + --> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:5:7 + | +LL | x.e10; + | ^^^ + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:8:7 + | +LL | y.e10; + | ^^^ + +error[E0610]: `u32` is a primitive type and therefore doesn't have fields + --> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:10:10 + | +LL | 2u32.e10; + | ^^^ + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:12:12 + | +LL | num!().e10; + | ^^^ + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:14:7 + | +LL | 2.e10foo; + | ^^^^^^ + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:16:8 + | +LL | 42._; + | ^ + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:20:8 + | +LL | 42.a; + | ^ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0610`. diff --git a/src/test/ui/typeck/explain_clone_autoref.rs b/src/test/ui/typeck/explain_clone_autoref.rs new file mode 100644 index 000000000..9279e4c39 --- /dev/null +++ b/src/test/ui/typeck/explain_clone_autoref.rs @@ -0,0 +1,13 @@ +struct NotClone; + +fn main() { + clone_thing(&NotClone); +} + +fn clone_thing(nc: &NotClone) -> NotClone { + //~^ NOTE expected `NotClone` because of return type + nc.clone() + //~^ ERROR mismatched type + //~| NOTE `NotClone` does not implement `Clone`, so `&NotClone` was cloned instead + //~| NOTE expected struct `NotClone`, found `&NotClone` +} diff --git a/src/test/ui/typeck/explain_clone_autoref.stderr b/src/test/ui/typeck/explain_clone_autoref.stderr new file mode 100644 index 000000000..faac680ea --- /dev/null +++ b/src/test/ui/typeck/explain_clone_autoref.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/explain_clone_autoref.rs:9:5 + | +LL | fn clone_thing(nc: &NotClone) -> NotClone { + | -------- expected `NotClone` because of return type +LL | +LL | nc.clone() + | ^^^^^^^^^^ expected struct `NotClone`, found `&NotClone` + | +note: `NotClone` does not implement `Clone`, so `&NotClone` was cloned instead + --> $DIR/explain_clone_autoref.rs:9:5 + | +LL | nc.clone() + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/issue-10401.rs b/src/test/ui/typeck/issue-10401.rs new file mode 100644 index 000000000..d77ff381e --- /dev/null +++ b/src/test/ui/typeck/issue-10401.rs @@ -0,0 +1,5 @@ +fn main() { + let mut a = "a"; + a += { "b" }; + //~^ ERROR: binary assignment operation `+=` cannot be applied +} diff --git a/src/test/ui/typeck/issue-10401.stderr b/src/test/ui/typeck/issue-10401.stderr new file mode 100644 index 000000000..1f68abcfb --- /dev/null +++ b/src/test/ui/typeck/issue-10401.stderr @@ -0,0 +1,11 @@ +error[E0368]: binary assignment operation `+=` cannot be applied to type `&str` + --> $DIR/issue-10401.rs:3:5 + | +LL | a += { "b" }; + | -^^^^^^^^^^^ + | | + | cannot use `+=` on type `&str` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0368`. diff --git a/src/test/ui/typeck/issue-13853-2.rs b/src/test/ui/typeck/issue-13853-2.rs new file mode 100644 index 000000000..27319c98d --- /dev/null +++ b/src/test/ui/typeck/issue-13853-2.rs @@ -0,0 +1,6 @@ +trait FromStructReader<'a> { } +trait ResponseHook { + fn get(&self); +} +fn foo(res : Box<dyn ResponseHook>) { res.get } //~ ERROR attempted to take value of method +fn main() {} diff --git a/src/test/ui/typeck/issue-13853-2.stderr b/src/test/ui/typeck/issue-13853-2.stderr new file mode 100644 index 000000000..92068df6c --- /dev/null +++ b/src/test/ui/typeck/issue-13853-2.stderr @@ -0,0 +1,14 @@ +error[E0615]: attempted to take value of method `get` on type `Box<(dyn ResponseHook + 'static)>` + --> $DIR/issue-13853-2.rs:5:43 + | +LL | fn foo(res : Box<dyn ResponseHook>) { res.get } + | ^^^ method, not a field + | +help: use parentheses to call the method + | +LL | fn foo(res : Box<dyn ResponseHook>) { res.get() } + | ++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0615`. diff --git a/src/test/ui/typeck/issue-13853-5.rs b/src/test/ui/typeck/issue-13853-5.rs new file mode 100644 index 000000000..2afdf95aa --- /dev/null +++ b/src/test/ui/typeck/issue-13853-5.rs @@ -0,0 +1,13 @@ +trait Deserializer<'a> { } + +trait Deserializable { + fn deserialize_token<'a, D: Deserializer<'a>>(_: D, _: &'a str) -> Self; +} + +impl<'a, T: Deserializable> Deserializable for &'a str { + //~^ ERROR type parameter `T` is not constrained + fn deserialize_token<D: Deserializer<'a>>(_x: D, _y: &'a str) -> &'a str { + } +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-13853-5.stderr b/src/test/ui/typeck/issue-13853-5.stderr new file mode 100644 index 000000000..3d8f824ec --- /dev/null +++ b/src/test/ui/typeck/issue-13853-5.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-13853-5.rs:7:10 + | +LL | impl<'a, T: Deserializable> Deserializable for &'a str { + | ^ unconstrained type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/typeck/issue-13853.rs b/src/test/ui/typeck/issue-13853.rs new file mode 100644 index 000000000..ac9886d2e --- /dev/null +++ b/src/test/ui/typeck/issue-13853.rs @@ -0,0 +1,38 @@ +trait Node { + fn zomg(); +} + +trait Graph<N: Node> { + fn nodes<'a, I: Iterator<Item=&'a N>>(&'a self) -> I + where N: 'a; +} + +impl<N: Node> Graph<N> for Vec<N> { + fn nodes<'a, I: Iterator<Item=&'a N>>(&self) -> I + where N: 'a + { + self.iter() //~ ERROR mismatched types + } +} + +struct Stuff; + +impl Node for Stuff { + fn zomg() { + println!("zomg"); + } +} + +fn iterate<N: Node, G: Graph<N>>(graph: &G) { + for node in graph.iter() { //~ ERROR no method named `iter` found + node.zomg(); + } +} + +pub fn main() { + let graph = Vec::new(); + + graph.push(Stuff); + + iterate(graph); //~ ERROR mismatched types +} diff --git a/src/test/ui/typeck/issue-13853.stderr b/src/test/ui/typeck/issue-13853.stderr new file mode 100644 index 000000000..657bda5f6 --- /dev/null +++ b/src/test/ui/typeck/issue-13853.stderr @@ -0,0 +1,40 @@ +error[E0308]: mismatched types + --> $DIR/issue-13853.rs:14:9 + | +LL | fn nodes<'a, I: Iterator<Item=&'a N>>(&self) -> I + | - this type parameter - expected `I` because of return type +... +LL | self.iter() + | ^^^^^^^^^^^ expected type parameter `I`, found struct `std::slice::Iter` + | + = note: expected type parameter `I` + found struct `std::slice::Iter<'_, N>` + +error[E0599]: no method named `iter` found for reference `&G` in the current scope + --> $DIR/issue-13853.rs:27:23 + | +LL | for node in graph.iter() { + | ^^^^ method not found in `&G` + +error[E0308]: mismatched types + --> $DIR/issue-13853.rs:37:13 + | +LL | iterate(graph); + | ------- ^^^^^ + | | | + | | expected reference, found struct `Vec` + | | help: consider borrowing here: `&graph` + | arguments to this function are incorrect + | + = note: expected reference `&_` + found struct `Vec<Stuff>` +note: function defined here + --> $DIR/issue-13853.rs:26:4 + | +LL | fn iterate<N: Node, G: Graph<N>>(graph: &G) { + | ^^^^^^^ --------- + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0308, E0599. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/issue-29124.rs b/src/test/ui/typeck/issue-29124.rs new file mode 100644 index 000000000..dd2784841 --- /dev/null +++ b/src/test/ui/typeck/issue-29124.rs @@ -0,0 +1,19 @@ +struct Ret; +struct Obj; + +impl Obj { + fn func() -> Ret { + Ret + } +} + +fn func() -> Ret { + Ret +} + +fn main() { + Obj::func.x(); + //~^ ERROR no method named `x` found + func.x(); + //~^ ERROR no method named `x` found +} diff --git a/src/test/ui/typeck/issue-29124.stderr b/src/test/ui/typeck/issue-29124.stderr new file mode 100644 index 000000000..c5d2ec084 --- /dev/null +++ b/src/test/ui/typeck/issue-29124.stderr @@ -0,0 +1,19 @@ +error[E0599]: no method named `x` found for fn item `fn() -> Ret {Obj::func}` in the current scope + --> $DIR/issue-29124.rs:15:15 + | +LL | Obj::func.x(); + | --------- ^ method not found in `fn() -> Ret {Obj::func}` + | | + | this is a function, perhaps you wish to call it + +error[E0599]: no method named `x` found for fn item `fn() -> Ret {func}` in the current scope + --> $DIR/issue-29124.rs:17:10 + | +LL | func.x(); + | ---- ^ method not found in `fn() -> Ret {func}` + | | + | this is a function, perhaps you wish to call it + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/typeck/issue-36708.rs b/src/test/ui/typeck/issue-36708.rs new file mode 100644 index 000000000..c9d9f2a6d --- /dev/null +++ b/src/test/ui/typeck/issue-36708.rs @@ -0,0 +1,12 @@ +// aux-build:issue-36708.rs + +extern crate issue_36708 as lib; + +struct Bar; + +impl lib::Foo for Bar { + fn foo<T>() {} + //~^ ERROR E0049 +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-36708.stderr b/src/test/ui/typeck/issue-36708.stderr new file mode 100644 index 000000000..140f19f1f --- /dev/null +++ b/src/test/ui/typeck/issue-36708.stderr @@ -0,0 +1,9 @@ +error[E0049]: method `foo` has 1 type parameter but its trait declaration has 0 type parameters + --> $DIR/issue-36708.rs:8:12 + | +LL | fn foo<T>() {} + | ^ found 1 type parameter, expected 0 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0049`. diff --git a/src/test/ui/typeck/issue-43189.rs b/src/test/ui/typeck/issue-43189.rs new file mode 100644 index 000000000..ce667a500 --- /dev/null +++ b/src/test/ui/typeck/issue-43189.rs @@ -0,0 +1,12 @@ +// Issue 46112: An extern crate pub re-exporting libcore was causing +// paths rooted from `std` to be misrendered in the diagnostic output. + +// ignore-windows +// aux-build:xcrate-issue-43189-a.rs +// aux-build:xcrate-issue-43189-b.rs + +extern crate xcrate_issue_43189_b; +fn main() { + ().a(); + //~^ ERROR no method named `a` found +} diff --git a/src/test/ui/typeck/issue-43189.stderr b/src/test/ui/typeck/issue-43189.stderr new file mode 100644 index 000000000..caf7530b8 --- /dev/null +++ b/src/test/ui/typeck/issue-43189.stderr @@ -0,0 +1,20 @@ +error[E0599]: no method named `a` found for unit type `()` in the current scope + --> $DIR/issue-43189.rs:10:8 + | +LL | ().a(); + | ^ method not found in `()` + | + ::: $DIR/auxiliary/xcrate-issue-43189-a.rs:5:8 + | +LL | fn a(&self) {} + | - the method is available for `()` here + | + = help: items from traits can only be used if the trait is in scope +help: the following trait is implemented but not in scope; perhaps add a `use` for it: + | +LL | use xcrate_issue_43189_b::xcrate_issue_43189_a::A; + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/typeck/issue-46112.rs b/src/test/ui/typeck/issue-46112.rs new file mode 100644 index 000000000..0cdd2c27f --- /dev/null +++ b/src/test/ui/typeck/issue-46112.rs @@ -0,0 +1,10 @@ +// Issue 46112: An extern crate pub re-exporting libcore was causing +// paths rooted from `std` to be misrendered in the diagnostic output. + +// ignore-windows +// aux-build:xcrate-issue-46112-rexport-core.rs + +extern crate xcrate_issue_46112_rexport_core; +fn test(r: Result<Option<()>, &'static str>) { } +fn main() { test(Ok(())); } +//~^ mismatched types diff --git a/src/test/ui/typeck/issue-46112.stderr b/src/test/ui/typeck/issue-46112.stderr new file mode 100644 index 000000000..91381e8ef --- /dev/null +++ b/src/test/ui/typeck/issue-46112.stderr @@ -0,0 +1,23 @@ +error[E0308]: mismatched types + --> $DIR/issue-46112.rs:9:21 + | +LL | fn main() { test(Ok(())); } + | -- ^^ expected enum `Option`, found `()` + | | + | arguments to this enum variant are incorrect + | + = note: expected enum `Option<()>` + found unit type `()` +note: tuple variant defined here + --> $SRC_DIR/core/src/result.rs:LL:COL + | +LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), + | ^^ +help: try wrapping the expression in `Some` + | +LL | fn main() { test(Ok(Some(()))); } + | +++++ + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/issue-52082-type-param-shadows-existing-type.rs b/src/test/ui/typeck/issue-52082-type-param-shadows-existing-type.rs new file mode 100644 index 000000000..7bf151514 --- /dev/null +++ b/src/test/ui/typeck/issue-52082-type-param-shadows-existing-type.rs @@ -0,0 +1,54 @@ +// Fix issue 52082: Confusing error if accidentally defining a type parameter with the same name as +// an existing type +// +// To this end, make sure that when trying to retrieve a field of a (reference to) type parameter, +// rustc points to the point where the parameter was defined. +#[derive(Debug)] +struct Point +{ + x: i32, + y: i32 +} + +impl Point +{ + fn add(a: &Point, b: &Point) -> Point + { + Point {x: a.x + b.x, y: a.y + b.y} + } +} + +trait Eq +{ + fn equals_ref<T>(a: &T, b: &T) -> bool; + fn equals_val<T>(a: T, b: T) -> bool; +} + +impl Eq for Point +{ + fn equals_ref<Point>(a: &Point, b: &Point) -> bool + { + a.x == b.x && a.y == b.y //~ ERROR no field `x` on type `&Point` [E0609] + //~|ERROR no field `x` on type `&Point` [E0609] + //~|ERROR no field `y` on type `&Point` [E0609] + //~|ERROR no field `y` on type `&Point` [E0609] + } + + fn equals_val<Point>(a: Point, b: Point) -> bool + { + a.x == b.x && a.y == b.y //~ ERROR no field `x` on type `Point` [E0609] + //~|ERROR no field `x` on type `Point` [E0609] + //~|ERROR no field `y` on type `Point` [E0609] + //~|ERROR no field `y` on type `Point` [E0609] + } +} + +fn main() +{ + let p1 = Point {x: 0, y: 10}; + let p2 = Point {x: 20, y: 42}; + println!("{:?}", Point::add(&p1, &p2)); + println!("p1: {:?}, p2: {:?}", p1, p2); + println!("&p1 == &p2: {:?}", Point::equals_ref(&p1, &p2)); + println!("p1 == p2: {:?}", Point::equals_val(p1, p2)); +} diff --git a/src/test/ui/typeck/issue-52082-type-param-shadows-existing-type.stderr b/src/test/ui/typeck/issue-52082-type-param-shadows-existing-type.stderr new file mode 100644 index 000000000..4be4c91df --- /dev/null +++ b/src/test/ui/typeck/issue-52082-type-param-shadows-existing-type.stderr @@ -0,0 +1,75 @@ +error[E0609]: no field `x` on type `&Point` + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:31:11 + | +LL | fn equals_ref<Point>(a: &Point, b: &Point) -> bool + | ----- type parameter 'Point' declared here +LL | { +LL | a.x == b.x && a.y == b.y + | ^ + +error[E0609]: no field `x` on type `&Point` + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:31:18 + | +LL | fn equals_ref<Point>(a: &Point, b: &Point) -> bool + | ----- type parameter 'Point' declared here +LL | { +LL | a.x == b.x && a.y == b.y + | ^ + +error[E0609]: no field `y` on type `&Point` + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:31:25 + | +LL | fn equals_ref<Point>(a: &Point, b: &Point) -> bool + | ----- type parameter 'Point' declared here +LL | { +LL | a.x == b.x && a.y == b.y + | ^ + +error[E0609]: no field `y` on type `&Point` + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:31:32 + | +LL | fn equals_ref<Point>(a: &Point, b: &Point) -> bool + | ----- type parameter 'Point' declared here +LL | { +LL | a.x == b.x && a.y == b.y + | ^ + +error[E0609]: no field `x` on type `Point` + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:39:11 + | +LL | fn equals_val<Point>(a: Point, b: Point) -> bool + | ----- type parameter 'Point' declared here +LL | { +LL | a.x == b.x && a.y == b.y + | ^ + +error[E0609]: no field `x` on type `Point` + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:39:18 + | +LL | fn equals_val<Point>(a: Point, b: Point) -> bool + | ----- type parameter 'Point' declared here +LL | { +LL | a.x == b.x && a.y == b.y + | ^ + +error[E0609]: no field `y` on type `Point` + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:39:25 + | +LL | fn equals_val<Point>(a: Point, b: Point) -> bool + | ----- type parameter 'Point' declared here +LL | { +LL | a.x == b.x && a.y == b.y + | ^ + +error[E0609]: no field `y` on type `Point` + --> $DIR/issue-52082-type-param-shadows-existing-type.rs:39:32 + | +LL | fn equals_val<Point>(a: Point, b: Point) -> bool + | ----- type parameter 'Point' declared here +LL | { +LL | a.x == b.x && a.y == b.y + | ^ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0609`. diff --git a/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs b/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs new file mode 100644 index 000000000..23ea0ad61 --- /dev/null +++ b/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs @@ -0,0 +1,23 @@ +// check-pass + +// rust-lang/rust#55810: types for a binding in a match arm can be +// inferred from arms that come later in the match. + +struct S; + +impl S { + fn method(&self) -> bool { + unimplemented!() + } +} + +fn get<T>() -> T { + unimplemented!() +} + +fn main() { + match get() { + x if x.method() => {} + &S => {} + } +} diff --git a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.rs b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.rs new file mode 100644 index 000000000..0a4e7da2b --- /dev/null +++ b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.rs @@ -0,0 +1,7 @@ +//extern crate has_assoc_type; + +//fn ice(x: Box<dyn has_assoc_type::Foo<Assoc=()>>) { +fn ice(x: Box<dyn Iterator<Item=()>>) { + *x //~ ERROR mismatched types [E0308] +} +fn main() {} diff --git a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr new file mode 100644 index 000000000..b92a6f2ec --- /dev/null +++ b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/issue-57673-ice-on-deref-of-boxed-trait.rs:5:5 + | +LL | fn ice(x: Box<dyn Iterator<Item=()>>) { + | - help: try adding a return type: `-> (dyn Iterator<Item = ()> + 'static)` +LL | *x + | ^^ expected `()`, found trait object `dyn Iterator` + | + = note: expected unit type `()` + found trait object `(dyn Iterator<Item = ()> + 'static)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/issue-61711-once-caused-rustc-inf-loop.rs b/src/test/ui/typeck/issue-61711-once-caused-rustc-inf-loop.rs new file mode 100644 index 000000000..de7d6a0d8 --- /dev/null +++ b/src/test/ui/typeck/issue-61711-once-caused-rustc-inf-loop.rs @@ -0,0 +1,11 @@ +// Issue 61711: A crate pub re-exporting `crate` was causing an +// infinite loop. + +// edition:2018 +// aux-build:xcrate-issue-61711-b.rs +// compile-flags:--extern xcrate_issue_61711_b + +// build-pass + +fn f<F: Fn(xcrate_issue_61711_b::Struct)>(_: F) { } +fn main() { } diff --git a/src/test/ui/typeck/issue-65611.rs b/src/test/ui/typeck/issue-65611.rs new file mode 100644 index 000000000..764531149 --- /dev/null +++ b/src/test/ui/typeck/issue-65611.rs @@ -0,0 +1,63 @@ +use std::mem::MaybeUninit; +use std::ops::Deref; + +pub unsafe trait Array { + /// The array’s element type + type Item; + #[doc(hidden)] + /// The smallest index type that indexes the array. + type Index: Index; + #[doc(hidden)] + fn as_ptr(&self) -> *const Self::Item; + #[doc(hidden)] + fn as_mut_ptr(&mut self) -> *mut Self::Item; + #[doc(hidden)] + fn capacity() -> usize; +} + +pub trait Index : PartialEq + Copy { + fn to_usize(self) -> usize; + fn from(i: usize) -> Self; +} + +impl Index for usize { + fn to_usize(self) -> usize { self } + fn from(val: usize) -> Self { + val + } +} + +unsafe impl<T> Array for [T; 1] { + type Item = T; + type Index = usize; + fn as_ptr(&self) -> *const T { self as *const _ as *const _ } + fn as_mut_ptr(&mut self) -> *mut T { self as *mut _ as *mut _} + fn capacity() -> usize { 1 } +} + +impl<A: Array> Deref for ArrayVec<A> { + type Target = [A::Item]; + #[inline] + fn deref(&self) -> &[A::Item] { + panic!() + } +} + +pub struct ArrayVec<A: Array> { + xs: MaybeUninit<A>, + len: usize, +} + +impl<A: Array> ArrayVec<A> { + pub fn new() -> ArrayVec<A> { + panic!() + } +} + +fn main() { + let mut buffer = ArrayVec::new(); + let x = buffer.last().unwrap().0.clone(); + //~^ ERROR type annotations needed + //~| ERROR no field `0` on type `&_` + buffer.reverse(); +} diff --git a/src/test/ui/typeck/issue-65611.stderr b/src/test/ui/typeck/issue-65611.stderr new file mode 100644 index 000000000..003c63079 --- /dev/null +++ b/src/test/ui/typeck/issue-65611.stderr @@ -0,0 +1,16 @@ +error[E0282]: type annotations needed + --> $DIR/issue-65611.rs:59:13 + | +LL | let x = buffer.last().unwrap().0.clone(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` + +error[E0609]: no field `0` on type `&_` + --> $DIR/issue-65611.rs:59:36 + | +LL | let x = buffer.last().unwrap().0.clone(); + | ^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0282, E0609. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/typeck/issue-67971.rs b/src/test/ui/typeck/issue-67971.rs new file mode 100644 index 000000000..8bf725cb5 --- /dev/null +++ b/src/test/ui/typeck/issue-67971.rs @@ -0,0 +1,9 @@ +struct S {} + +fn foo(ctx: &mut S) -> String { //~ ERROR mismatched types + // Don't suggest to remove semicolon as it won't fix anything + ctx.sleep = 0; + //~^ ERROR no field `sleep` on type `&mut S` +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-67971.stderr b/src/test/ui/typeck/issue-67971.stderr new file mode 100644 index 000000000..5d07f9cc7 --- /dev/null +++ b/src/test/ui/typeck/issue-67971.stderr @@ -0,0 +1,18 @@ +error[E0609]: no field `sleep` on type `&mut S` + --> $DIR/issue-67971.rs:5:9 + | +LL | ctx.sleep = 0; + | ^^^^^ unknown field + +error[E0308]: mismatched types + --> $DIR/issue-67971.rs:3:24 + | +LL | fn foo(ctx: &mut S) -> String { + | --- ^^^^^^ expected struct `String`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0308, E0609. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/issue-68590-reborrow-through-derefmut.rs b/src/test/ui/typeck/issue-68590-reborrow-through-derefmut.rs new file mode 100644 index 000000000..e4436260e --- /dev/null +++ b/src/test/ui/typeck/issue-68590-reborrow-through-derefmut.rs @@ -0,0 +1,25 @@ +// check-pass + +// rust-lang/rust#68590: confusing diagnostics when reborrowing through DerefMut. + +use std::cell::RefCell; + +struct A; + +struct S<'a> { + a: &'a mut A, +} + +fn take_a(_: &mut A) {} + +fn test<'a>(s: &RefCell<S<'a>>) { + let mut guard = s.borrow_mut(); + take_a(guard.a); + let _s2 = S { a: guard.a }; +} + +fn main() { + let a = &mut A; + let s = RefCell::new(S { a }); + test(&s); +} diff --git a/src/test/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.rs b/src/test/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.rs new file mode 100644 index 000000000..571692a53 --- /dev/null +++ b/src/test/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.rs @@ -0,0 +1,9 @@ +// Regression test for #69378: no type for node after struct parse recovery + +struct Foo { 0: u8 } //~ ERROR expected identifier + +fn test(f: Foo) { + Foo{foo: 4, ..f}; +} + +fn main() {} 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 new file mode 100644 index 000000000..6bc9c8498 --- /dev/null +++ b/src/test/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.stderr @@ -0,0 +1,8 @@ +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 + +error: aborting due to previous error + diff --git a/src/test/ui/typeck/issue-72225-call-fnmut-through-derefmut.rs b/src/test/ui/typeck/issue-72225-call-fnmut-through-derefmut.rs new file mode 100644 index 000000000..3ea05389f --- /dev/null +++ b/src/test/ui/typeck/issue-72225-call-fnmut-through-derefmut.rs @@ -0,0 +1,21 @@ +// check-pass + +// rust-lang/rust#72225: confusing diagnostics when calling FnMut through DerefMut. + +use std::cell::RefCell; + +struct S { + f: Box<dyn FnMut()> +} + +fn test(s: &RefCell<S>) { + let mut guard = s.borrow_mut(); + (guard.f)(); +} + +fn main() { + let s = RefCell::new(S { + f: Box::new(|| ()) + }); + test(&s); +} diff --git a/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.fixed b/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.fixed new file mode 100644 index 000000000..7fdd618c2 --- /dev/null +++ b/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.fixed @@ -0,0 +1,59 @@ +// check-pass +// run-rustfix +// +// rust-lang/rust#73592: borrow_mut through Deref should work. +// +// Before #72280, when we see something like `&mut *rcvr.method()`, we +// incorrectly requires `rcvr` to be type-checked as a mut place. While this +// requirement is usually correct for smart pointers, it is overly restrictive +// for types like `Mutex` or `RefCell` which can produce a guard that +// implements `DerefMut` from `&self`. +// +// Making it more confusing, because we use Deref as the fallback when DerefMut +// is implemented, we won't see an issue when the smart pointer does not +// implement `DerefMut`. It only causes an issue when `rcvr` is obtained via a +// type that implements both `Deref` or `DerefMut`. +// +// This bug is only discovered in #73592 after it is already fixed as a side-effect +// of a refactoring made in #72280. + +#![warn(unused_mut)] + +use std::pin::Pin; +use std::cell::RefCell; + +struct S(RefCell<()>); + +fn test_pin(s: Pin<&S>) { + // This works before #72280. + let _ = &mut *s.0.borrow_mut(); +} + +fn test_pin_mut(s: Pin<&mut S>) { + // This should compile but didn't before #72280. + let _ = &mut *s.0.borrow_mut(); +} + +fn test_vec(s: &Vec<RefCell<()>>) { + // This should compile but didn't before #72280. + let _ = &mut *s[0].borrow_mut(); +} + +fn test_mut_pin(s: Pin<&S>) { + //~^ WARN variable does not need to be mutable + let _ = &mut *s.0.borrow_mut(); +} + +fn test_mut_pin_mut(s: Pin<&mut S>) { + //~^ WARN variable does not need to be mutable + let _ = &mut *s.0.borrow_mut(); +} + +fn main() { + let mut s = S(RefCell::new(())); + test_pin(Pin::new(&s)); + test_pin_mut(Pin::new(&mut s)); + test_mut_pin(Pin::new(&s)); + test_mut_pin_mut(Pin::new(&mut s)); + test_vec(&vec![s.0]); +} diff --git a/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.rs b/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.rs new file mode 100644 index 000000000..3b399e629 --- /dev/null +++ b/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.rs @@ -0,0 +1,59 @@ +// check-pass +// run-rustfix +// +// rust-lang/rust#73592: borrow_mut through Deref should work. +// +// Before #72280, when we see something like `&mut *rcvr.method()`, we +// incorrectly requires `rcvr` to be type-checked as a mut place. While this +// requirement is usually correct for smart pointers, it is overly restrictive +// for types like `Mutex` or `RefCell` which can produce a guard that +// implements `DerefMut` from `&self`. +// +// Making it more confusing, because we use Deref as the fallback when DerefMut +// is implemented, we won't see an issue when the smart pointer does not +// implement `DerefMut`. It only causes an issue when `rcvr` is obtained via a +// type that implements both `Deref` or `DerefMut`. +// +// This bug is only discovered in #73592 after it is already fixed as a side-effect +// of a refactoring made in #72280. + +#![warn(unused_mut)] + +use std::pin::Pin; +use std::cell::RefCell; + +struct S(RefCell<()>); + +fn test_pin(s: Pin<&S>) { + // This works before #72280. + let _ = &mut *s.0.borrow_mut(); +} + +fn test_pin_mut(s: Pin<&mut S>) { + // This should compile but didn't before #72280. + let _ = &mut *s.0.borrow_mut(); +} + +fn test_vec(s: &Vec<RefCell<()>>) { + // This should compile but didn't before #72280. + let _ = &mut *s[0].borrow_mut(); +} + +fn test_mut_pin(mut s: Pin<&S>) { + //~^ WARN variable does not need to be mutable + let _ = &mut *s.0.borrow_mut(); +} + +fn test_mut_pin_mut(mut s: Pin<&mut S>) { + //~^ WARN variable does not need to be mutable + let _ = &mut *s.0.borrow_mut(); +} + +fn main() { + let mut s = S(RefCell::new(())); + test_pin(Pin::new(&s)); + test_pin_mut(Pin::new(&mut s)); + test_mut_pin(Pin::new(&s)); + test_mut_pin_mut(Pin::new(&mut s)); + test_vec(&vec![s.0]); +} diff --git a/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.stderr b/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.stderr new file mode 100644 index 000000000..5f5f672c3 --- /dev/null +++ b/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.stderr @@ -0,0 +1,24 @@ +warning: variable does not need to be mutable + --> $DIR/issue-73592-borrow_mut-through-deref.rs:42:17 + | +LL | fn test_mut_pin(mut s: Pin<&S>) { + | ----^ + | | + | help: remove this `mut` + | +note: the lint level is defined here + --> $DIR/issue-73592-borrow_mut-through-deref.rs:20:9 + | +LL | #![warn(unused_mut)] + | ^^^^^^^^^^ + +warning: variable does not need to be mutable + --> $DIR/issue-73592-borrow_mut-through-deref.rs:47:21 + | +LL | fn test_mut_pin_mut(mut s: Pin<&mut S>) { + | ----^ + | | + | help: remove this `mut` + +warning: 2 warnings emitted + diff --git a/src/test/ui/typeck/issue-74086.rs b/src/test/ui/typeck/issue-74086.rs new file mode 100644 index 000000000..9b7c0d7cc --- /dev/null +++ b/src/test/ui/typeck/issue-74086.rs @@ -0,0 +1,5 @@ +fn main() { + static BUG: fn(_) -> u8 = |_| 8; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR the placeholder `_` is not allowed within types on item signatures for static items +} diff --git a/src/test/ui/typeck/issue-74086.stderr b/src/test/ui/typeck/issue-74086.stderr new file mode 100644 index 000000000..95ebf9a90 --- /dev/null +++ b/src/test/ui/typeck/issue-74086.stderr @@ -0,0 +1,15 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/issue-74086.rs:2:20 + | +LL | static BUG: fn(_) -> u8 = |_| 8; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static items + --> $DIR/issue-74086.rs:2:20 + | +LL | static BUG: fn(_) -> u8 = |_| 8; + | ^ not allowed in type signatures + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/typeck/issue-74933.rs b/src/test/ui/typeck/issue-74933.rs new file mode 100644 index 000000000..4b6c173b8 --- /dev/null +++ b/src/test/ui/typeck/issue-74933.rs @@ -0,0 +1,38 @@ +// check-pass +// +// rust-lang/rust#74933: Lifetime error when indexing with borrowed index + +use std::ops::{Index, IndexMut}; + +struct S(V); +struct K<'a>(&'a ()); +struct V; + +impl<'a> Index<&'a K<'a>> for S { + type Output = V; + + fn index(&self, _: &'a K<'a>) -> &V { + &self.0 + } +} + +impl<'a> IndexMut<&'a K<'a>> for S { + fn index_mut(&mut self, _: &'a K<'a>) -> &mut V { + &mut self.0 + } +} + +impl V { + fn foo(&mut self) {} +} + +fn test(s: &mut S, k: &K<'_>) { + s[k] = V; + s[k].foo(); +} + +fn main() { + let mut s = S(V); + let k = K(&()); + test(&mut s, &k); +} diff --git a/src/test/ui/typeck/issue-75883.rs b/src/test/ui/typeck/issue-75883.rs new file mode 100644 index 000000000..885acc482 --- /dev/null +++ b/src/test/ui/typeck/issue-75883.rs @@ -0,0 +1,22 @@ +// Regression test for #75883. + +pub struct UI {} + +impl UI { + pub fn run() -> Result<_> { + //~^ ERROR: this enum takes 2 generic arguments but 1 generic argument was supplied + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for return types + let mut ui = UI {}; + ui.interact(); + + unimplemented!(); + } + + pub fn interact(&mut self) -> Result<_> { + //~^ ERROR: this enum takes 2 generic arguments but 1 generic argument was supplied + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for return types + unimplemented!(); + } +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-75883.stderr b/src/test/ui/typeck/issue-75883.stderr new file mode 100644 index 000000000..3861e0507 --- /dev/null +++ b/src/test/ui/typeck/issue-75883.stderr @@ -0,0 +1,52 @@ +error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied + --> $DIR/issue-75883.rs:6:21 + | +LL | pub fn run() -> Result<_> { + | ^^^^^^ - supplied 1 generic argument + | | + | expected 2 generic arguments + | +note: enum defined here, with 2 generic parameters: `T`, `E` + --> $SRC_DIR/core/src/result.rs:LL:COL + | +LL | pub enum Result<T, E> { + | ^^^^^^ - - +help: add missing generic argument + | +LL | pub fn run() -> Result<_, E> { + | +++ + +error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied + --> $DIR/issue-75883.rs:15:35 + | +LL | pub fn interact(&mut self) -> Result<_> { + | ^^^^^^ - supplied 1 generic argument + | | + | expected 2 generic arguments + | +note: enum defined here, with 2 generic parameters: `T`, `E` + --> $SRC_DIR/core/src/result.rs:LL:COL + | +LL | pub enum Result<T, E> { + | ^^^^^^ - - +help: add missing generic argument + | +LL | pub fn interact(&mut self) -> Result<_, E> { + | +++ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/issue-75883.rs:15:42 + | +LL | pub fn interact(&mut self) -> Result<_> { + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/issue-75883.rs:6:28 + | +LL | pub fn run() -> Result<_> { + | ^ not allowed in type signatures + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0107, E0121. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/typeck/issue-75889.rs b/src/test/ui/typeck/issue-75889.rs new file mode 100644 index 000000000..84c067ed0 --- /dev/null +++ b/src/test/ui/typeck/issue-75889.rs @@ -0,0 +1,6 @@ +// Regression test for #75889. + +const FOO: dyn Fn() -> _ = ""; //~ ERROR E0121 +static BOO: dyn Fn() -> _ = ""; //~ ERROR E0121 + +fn main() {} diff --git a/src/test/ui/typeck/issue-75889.stderr b/src/test/ui/typeck/issue-75889.stderr new file mode 100644 index 000000000..1438f481e --- /dev/null +++ b/src/test/ui/typeck/issue-75889.stderr @@ -0,0 +1,15 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constant items + --> $DIR/issue-75889.rs:3:24 + | +LL | const FOO: dyn Fn() -> _ = ""; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static items + --> $DIR/issue-75889.rs:4:25 + | +LL | static BOO: dyn Fn() -> _ = ""; + | ^ not allowed in type signatures + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/typeck/issue-79040.rs b/src/test/ui/typeck/issue-79040.rs new file mode 100644 index 000000000..941612542 --- /dev/null +++ b/src/test/ui/typeck/issue-79040.rs @@ -0,0 +1,5 @@ +fn main() { + const FOO = "hello" + 1; //~ ERROR cannot add `{integer}` to `&str` + //~^ missing type for `const` item + println!("{}", FOO); +} diff --git a/src/test/ui/typeck/issue-79040.stderr b/src/test/ui/typeck/issue-79040.stderr new file mode 100644 index 000000000..aec2e1ec9 --- /dev/null +++ b/src/test/ui/typeck/issue-79040.stderr @@ -0,0 +1,17 @@ +error[E0369]: cannot add `{integer}` to `&str` + --> $DIR/issue-79040.rs:2:25 + | +LL | const FOO = "hello" + 1; + | ------- ^ - {integer} + | | + | &str + +error: missing type for `const` item + --> $DIR/issue-79040.rs:2:11 + | +LL | const FOO = "hello" + 1; + | ^^^ help: provide a type for the item: `FOO: <type>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/typeck/issue-80207-unsized-return.rs b/src/test/ui/typeck/issue-80207-unsized-return.rs new file mode 100644 index 000000000..75430da14 --- /dev/null +++ b/src/test/ui/typeck/issue-80207-unsized-return.rs @@ -0,0 +1,20 @@ +// check-pass + +trait Foo { + fn do_stuff() -> Self; +} + +trait Bar { + type Output; +} + +impl<T> Foo for dyn Bar<Output = T> +where + Self: Sized, +{ + fn do_stuff() -> Self { + todo!() + } +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-80779.rs b/src/test/ui/typeck/issue-80779.rs new file mode 100644 index 000000000..1624f6b77 --- /dev/null +++ b/src/test/ui/typeck/issue-80779.rs @@ -0,0 +1,13 @@ +// Regression test for #80779. + +pub struct T<'a>(&'a str); + +pub fn f<'a>(val: T<'a>) -> _ { + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for return types + g(val) +} + +pub fn g(_: T<'static>) -> _ {} +//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for return types + +fn main() {} diff --git a/src/test/ui/typeck/issue-80779.stderr b/src/test/ui/typeck/issue-80779.stderr new file mode 100644 index 000000000..2261ba616 --- /dev/null +++ b/src/test/ui/typeck/issue-80779.stderr @@ -0,0 +1,21 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/issue-80779.rs:10:28 + | +LL | pub fn g(_: T<'static>) -> _ {} + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `()` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/issue-80779.rs:5:29 + | +LL | pub fn f<'a>(val: T<'a>) -> _ { + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `()` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/typeck/issue-81293.rs b/src/test/ui/typeck/issue-81293.rs new file mode 100644 index 000000000..076b8c944 --- /dev/null +++ b/src/test/ui/typeck/issue-81293.rs @@ -0,0 +1,9 @@ +fn main() { + let a: u16; + let b: u16 = 42; + let c: usize = 5; + + a = c + b * 5; //~ ERROR: mismatched types [E0308] + //~| ERROR: mismatched types [E0308] + //~| ERROR: cannot add `u16` to `usize` [E0277] +} diff --git a/src/test/ui/typeck/issue-81293.stderr b/src/test/ui/typeck/issue-81293.stderr new file mode 100644 index 000000000..9658288ac --- /dev/null +++ b/src/test/ui/typeck/issue-81293.stderr @@ -0,0 +1,37 @@ +error[E0308]: mismatched types + --> $DIR/issue-81293.rs:6:13 + | +LL | a = c + b * 5; + | ^^^^^ expected `usize`, found `u16` + +error[E0308]: mismatched types + --> $DIR/issue-81293.rs:6:9 + | +LL | let a: u16; + | --- expected due to this type +... +LL | a = c + b * 5; + | ^^^^^^^^^ expected `u16`, found `usize` + +error[E0277]: cannot add `u16` to `usize` + --> $DIR/issue-81293.rs:6:11 + | +LL | a = c + b * 5; + | ^ no implementation for `usize + u16` + | + = help: the trait `Add<u16>` is not implemented for `usize` + = help: the following other types implement trait `Add<Rhs>`: + <&'a f32 as Add<f32>> + <&'a f64 as Add<f64>> + <&'a i128 as Add<i128>> + <&'a i16 as Add<i16>> + <&'a i32 as Add<i32>> + <&'a i64 as Add<i64>> + <&'a i8 as Add<i8>> + <&'a isize as Add<isize>> + and 48 others + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/typeck/issue-81885.rs b/src/test/ui/typeck/issue-81885.rs new file mode 100644 index 000000000..fb3949478 --- /dev/null +++ b/src/test/ui/typeck/issue-81885.rs @@ -0,0 +1,9 @@ +const TEST4: fn() -> _ = 42; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + //~| ERROR the placeholder `_` is not allowed within types on item signatures for constant items + +fn main() { + const TEST5: fn() -> _ = 42; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + //~| ERROR the placeholder `_` is not allowed within types on item signatures for constant items +} diff --git a/src/test/ui/typeck/issue-81885.stderr b/src/test/ui/typeck/issue-81885.stderr new file mode 100644 index 000000000..91c08bd82 --- /dev/null +++ b/src/test/ui/typeck/issue-81885.stderr @@ -0,0 +1,27 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/issue-81885.rs:1:22 + | +LL | const TEST4: fn() -> _ = 42; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constant items + --> $DIR/issue-81885.rs:1:22 + | +LL | const TEST4: fn() -> _ = 42; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/issue-81885.rs:6:26 + | +LL | const TEST5: fn() -> _ = 42; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constant items + --> $DIR/issue-81885.rs:6:26 + | +LL | const TEST5: fn() -> _ = 42; + | ^ not allowed in type signatures + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/typeck/issue-81943.rs b/src/test/ui/typeck/issue-81943.rs new file mode 100644 index 000000000..18f5970a3 --- /dev/null +++ b/src/test/ui/typeck/issue-81943.rs @@ -0,0 +1,13 @@ +// aux-build:issue-81943-lib.rs +extern crate issue_81943_lib as lib; + +fn f<F: Fn(i32)>(f: F) { f(0); } +fn g(t: i32) -> i32 { t } +fn main() { + f(|x| lib::d!(x)); //~ERROR + f(|x| match x { tmp => { g(tmp) } }); //~ERROR + macro_rules! d { + ($e:expr) => { match $e { x => { g(x) } } } //~ERROR + } + f(|x| d!(x)); +} diff --git a/src/test/ui/typeck/issue-81943.stderr b/src/test/ui/typeck/issue-81943.stderr new file mode 100644 index 000000000..041ff1075 --- /dev/null +++ b/src/test/ui/typeck/issue-81943.stderr @@ -0,0 +1,51 @@ +error[E0308]: mismatched types + --> $DIR/issue-81943.rs:7:9 + | +LL | f(|x| lib::d!(x)); + | ^^^^^^^^^^ expected `()`, found `i32` + | + = note: this error originates in the macro `lib::d` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0308]: mismatched types + --> $DIR/issue-81943.rs:8:28 + | +LL | f(|x| match x { tmp => { g(tmp) } }); + | -------------------^^^^^^---- + | | | + | | expected `()`, found `i32` + | expected this to be `()` + | +help: consider using a semicolon here + | +LL | f(|x| match x { tmp => { g(tmp); } }); + | + +help: consider using a semicolon here + | +LL | f(|x| match x { tmp => { g(tmp) } };); + | + + +error[E0308]: mismatched types + --> $DIR/issue-81943.rs:10:38 + | +LL | ($e:expr) => { match $e { x => { g(x) } } } + | ------------------^^^^---- + | | | + | | expected `()`, found `i32` + | expected this to be `()` +LL | } +LL | f(|x| d!(x)); + | ----- in this macro invocation + | + = note: this error originates in the macro `d` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider using a semicolon here + | +LL | ($e:expr) => { match $e { x => { g(x); } } } + | + +help: consider using a semicolon here + | +LL | ($e:expr) => { match $e { x => { g(x) } }; } + | + + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/issue-82772.rs b/src/test/ui/typeck/issue-82772.rs new file mode 100644 index 000000000..326273bfe --- /dev/null +++ b/src/test/ui/typeck/issue-82772.rs @@ -0,0 +1,13 @@ +// edition:2018 + +fn main() { + use a::ModPrivateStruct; + let Box { 0: _, .. }: Box<()>; //~ ERROR field `0` of + let Box { 1: _, .. }: Box<()>; //~ ERROR field `1` of + let ModPrivateStruct { 1: _, .. } = ModPrivateStruct::default(); //~ ERROR field `1` of +} + +mod a { + #[derive(Default)] + pub struct ModPrivateStruct(u8, u8); +} diff --git a/src/test/ui/typeck/issue-82772.stderr b/src/test/ui/typeck/issue-82772.stderr new file mode 100644 index 000000000..321143cb9 --- /dev/null +++ b/src/test/ui/typeck/issue-82772.stderr @@ -0,0 +1,21 @@ +error[E0451]: field `0` of struct `Box` is private + --> $DIR/issue-82772.rs:5:15 + | +LL | let Box { 0: _, .. }: Box<()>; + | ^^^^ private field + +error[E0451]: field `1` of struct `Box` is private + --> $DIR/issue-82772.rs:6:15 + | +LL | let Box { 1: _, .. }: Box<()>; + | ^^^^ private field + +error[E0451]: field `1` of struct `ModPrivateStruct` is private + --> $DIR/issue-82772.rs:7:28 + | +LL | let ModPrivateStruct { 1: _, .. } = ModPrivateStruct::default(); + | ^^^^ private field + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0451`. diff --git a/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.rs b/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.rs new file mode 100644 index 000000000..16ec2a546 --- /dev/null +++ b/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.rs @@ -0,0 +1,7 @@ +// Regression test for #83621. + +extern "C" { + static x: _; //~ ERROR: [E0121] +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.stderr b/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.stderr new file mode 100644 index 000000000..9376e8bcf --- /dev/null +++ b/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.stderr @@ -0,0 +1,9 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/issue-83621-placeholder-static-in-extern.rs:4:15 + | +LL | static x: _; + | ^ not allowed in type signatures + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/typeck/issue-83693.rs b/src/test/ui/typeck/issue-83693.rs new file mode 100644 index 000000000..a42558220 --- /dev/null +++ b/src/test/ui/typeck/issue-83693.rs @@ -0,0 +1,19 @@ +// Regression test for the ICE described in #83693. + +#![feature(fn_traits)] +#![crate_type="lib"] + +impl F { +//~^ ERROR: cannot find type `F` in this scope [E0412] + fn call() { + <Self as Fn(&TestResult)>::call + //~^ ERROR: cannot find type `TestResult` in this scope [E0412] + //~| associated type bindings are not allowed here [E0229] + } +} + +fn call() { + <x as Fn(&usize)>::call + //~^ ERROR: cannot find type `x` in this scope [E0412] + //~| ERROR: associated type bindings are not allowed here [E0229] +} diff --git a/src/test/ui/typeck/issue-83693.stderr b/src/test/ui/typeck/issue-83693.stderr new file mode 100644 index 000000000..0d8bbf1ce --- /dev/null +++ b/src/test/ui/typeck/issue-83693.stderr @@ -0,0 +1,39 @@ +error[E0412]: cannot find type `F` in this scope + --> $DIR/issue-83693.rs:6:6 + | +LL | impl F { + | ^ help: a trait with a similar name exists: `Fn` + | + ::: $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | pub trait Fn<Args>: FnMut<Args> { + | ------------------------------- similarly named trait `Fn` defined here + +error[E0412]: cannot find type `TestResult` in this scope + --> $DIR/issue-83693.rs:9:22 + | +LL | <Self as Fn(&TestResult)>::call + | ^^^^^^^^^^ not found in this scope + +error[E0412]: cannot find type `x` in this scope + --> $DIR/issue-83693.rs:16:6 + | +LL | <x as Fn(&usize)>::call + | ^ not found in this scope + +error[E0229]: associated type bindings are not allowed here + --> $DIR/issue-83693.rs:9:18 + | +LL | <Self as Fn(&TestResult)>::call + | ^^^^^^^^^^^^^^^ associated type not allowed here + +error[E0229]: associated type bindings are not allowed here + --> $DIR/issue-83693.rs:16:11 + | +LL | <x as Fn(&usize)>::call + | ^^^^^^^^^^ associated type not allowed here + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0229, E0412. +For more information about an error, try `rustc --explain E0229`. diff --git a/src/test/ui/typeck/issue-84160.rs b/src/test/ui/typeck/issue-84160.rs new file mode 100644 index 000000000..7b444df85 --- /dev/null +++ b/src/test/ui/typeck/issue-84160.rs @@ -0,0 +1,9 @@ +fn mismatched_types_with_reference(x: &u32) -> &u32 { + if false { + return x; + } + return "test"; + //~^ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-84160.stderr b/src/test/ui/typeck/issue-84160.stderr new file mode 100644 index 000000000..24c188b3f --- /dev/null +++ b/src/test/ui/typeck/issue-84160.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/issue-84160.rs:5:12 + | +LL | fn mismatched_types_with_reference(x: &u32) -> &u32 { + | ---- expected `&u32` because of return type +... +LL | return "test"; + | ^^^^^^ expected `u32`, found `str` + | + = note: expected reference `&u32` + found reference `&'static str` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/issue-84768.rs b/src/test/ui/typeck/issue-84768.rs new file mode 100644 index 000000000..ffa92823b --- /dev/null +++ b/src/test/ui/typeck/issue-84768.rs @@ -0,0 +1,10 @@ +// Regression test for the ICE described in #84768. + +#![feature(fn_traits)] +#![crate_type="lib"] + +fn transform_mut<F>(f: F) where F: for<'b> FnOnce(&'b mut u8) { + <F as FnOnce(&mut u8)>::call_once(f, 1) + //~^ ERROR: associated type bindings are not allowed here [E0229] + //~| ERROR: mismatched types [E0308] +} diff --git a/src/test/ui/typeck/issue-84768.stderr b/src/test/ui/typeck/issue-84768.stderr new file mode 100644 index 000000000..04dc0e365 --- /dev/null +++ b/src/test/ui/typeck/issue-84768.stderr @@ -0,0 +1,26 @@ +error[E0229]: associated type bindings are not allowed here + --> $DIR/issue-84768.rs:7:11 + | +LL | <F as FnOnce(&mut u8)>::call_once(f, 1) + | ^^^^^^^^^^^^^^^ associated type not allowed here + +error[E0308]: mismatched types + --> $DIR/issue-84768.rs:7:42 + | +LL | <F as FnOnce(&mut u8)>::call_once(f, 1) + | --------------------------------- ^ expected tuple, found integer + | | + | arguments to this function are incorrect + | + = note: expected tuple `(&mut u8,)` + found type `{integer}` +note: associated function defined here + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; + | ^^^^^^^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0229, E0308. +For more information about an error, try `rustc --explain E0229`. diff --git a/src/test/ui/typeck/issue-84831.rs b/src/test/ui/typeck/issue-84831.rs new file mode 100644 index 000000000..c646f7107 --- /dev/null +++ b/src/test/ui/typeck/issue-84831.rs @@ -0,0 +1,9 @@ +fn f() { + std::<0>; //~ ERROR expected value +} +fn j() { + std::<_ as _>; //~ ERROR expected value + //~^ ERROR expected one of `,` or `>`, found keyword `as` +} + +fn main () {} diff --git a/src/test/ui/typeck/issue-84831.stderr b/src/test/ui/typeck/issue-84831.stderr new file mode 100644 index 000000000..461ccb142 --- /dev/null +++ b/src/test/ui/typeck/issue-84831.stderr @@ -0,0 +1,26 @@ +error: expected one of `,` or `>`, found keyword `as` + --> $DIR/issue-84831.rs:5:13 + | +LL | std::<_ as _>; + | ^^ expected one of `,` or `>` + | +help: expressions must be enclosed in braces to be used as const generic arguments + | +LL | std::<{ _ as _ }>; + | + + + +error[E0423]: expected value, found crate `std` + --> $DIR/issue-84831.rs:2:5 + | +LL | std::<0>; + | ^^^^^^^^ not a value + +error[E0423]: expected value, found crate `std` + --> $DIR/issue-84831.rs:5:5 + | +LL | std::<_ as _>; + | ^^^^^^^^^^^^^ not a value + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0423`. diff --git a/src/test/ui/typeck/issue-86721-return-expr-ice.rev1.stderr b/src/test/ui/typeck/issue-86721-return-expr-ice.rev1.stderr new file mode 100644 index 000000000..b1111fcf1 --- /dev/null +++ b/src/test/ui/typeck/issue-86721-return-expr-ice.rev1.stderr @@ -0,0 +1,9 @@ +error[E0572]: return statement outside of function body + --> $DIR/issue-86721-return-expr-ice.rs:9:22 + | +LL | const U: usize = return; + | ^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0572`. diff --git a/src/test/ui/typeck/issue-86721-return-expr-ice.rev2.stderr b/src/test/ui/typeck/issue-86721-return-expr-ice.rev2.stderr new file mode 100644 index 000000000..f489ae200 --- /dev/null +++ b/src/test/ui/typeck/issue-86721-return-expr-ice.rev2.stderr @@ -0,0 +1,9 @@ +error[E0572]: return statement outside of function body + --> $DIR/issue-86721-return-expr-ice.rs:15:20 + | +LL | fn foo(a: [(); return]); + | ^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0572`. diff --git a/src/test/ui/typeck/issue-86721-return-expr-ice.rs b/src/test/ui/typeck/issue-86721-return-expr-ice.rs new file mode 100644 index 000000000..cd7135f18 --- /dev/null +++ b/src/test/ui/typeck/issue-86721-return-expr-ice.rs @@ -0,0 +1,17 @@ +// Regression test for the ICE described in #86721. + +// revisions: rev1 rev2 +#![cfg_attr(any(), rev1, rev2)] +#![crate_type="lib"] + +#[cfg(any(rev1))] +trait T { + const U: usize = return; + //[rev1]~^ ERROR: return statement outside of function body [E0572] +} + +#[cfg(any(rev2))] +trait T2 { + fn foo(a: [(); return]); + //[rev2]~^ ERROR: return statement outside of function body [E0572] +} diff --git a/src/test/ui/typeck/issue-87181/empty-tuple-method.rs b/src/test/ui/typeck/issue-87181/empty-tuple-method.rs new file mode 100644 index 000000000..1875d8280 --- /dev/null +++ b/src/test/ui/typeck/issue-87181/empty-tuple-method.rs @@ -0,0 +1,14 @@ +struct Bar<T> { + bar: T +} + +struct Foo(); +impl Foo { + fn foo() { } +} + +fn main() { + let thing = Bar { bar: Foo }; + thing.bar.foo(); + //~^ ERROR no method named `foo` found for fn item `fn() -> Foo {Foo}` in the current scope [E0599] +} diff --git a/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr b/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr new file mode 100644 index 000000000..6ed70b301 --- /dev/null +++ b/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr @@ -0,0 +1,16 @@ +error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo}` in the current scope + --> $DIR/empty-tuple-method.rs:12:15 + | +LL | thing.bar.foo(); + | --------- ^^^ method not found in `fn() -> Foo {Foo}` + | | + | this is the constructor of a struct + | +help: call the constructor + | +LL | (thing.bar)().foo(); + | + +++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/typeck/issue-87181/enum-variant.rs b/src/test/ui/typeck/issue-87181/enum-variant.rs new file mode 100644 index 000000000..3b926b90f --- /dev/null +++ b/src/test/ui/typeck/issue-87181/enum-variant.rs @@ -0,0 +1,16 @@ +struct Bar<T> { + bar: T +} + +enum Foo{ + Tup() +} +impl Foo { + fn foo() { } +} + +fn main() { + let thing = Bar { bar: Foo::Tup }; + thing.bar.foo(); + //~^ ERROR no method named `foo` found for fn item `fn() -> Foo {Foo::Tup}` in the current scope [E0599] +} diff --git a/src/test/ui/typeck/issue-87181/enum-variant.stderr b/src/test/ui/typeck/issue-87181/enum-variant.stderr new file mode 100644 index 000000000..a3a818696 --- /dev/null +++ b/src/test/ui/typeck/issue-87181/enum-variant.stderr @@ -0,0 +1,16 @@ +error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo::Tup}` in the current scope + --> $DIR/enum-variant.rs:14:15 + | +LL | thing.bar.foo(); + | --------- ^^^ method not found in `fn() -> Foo {Foo::Tup}` + | | + | this is the constructor of an enum variant + | +help: call the constructor + | +LL | (thing.bar)().foo(); + | + +++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/typeck/issue-87181/tuple-field.rs b/src/test/ui/typeck/issue-87181/tuple-field.rs new file mode 100644 index 000000000..00e3b460e --- /dev/null +++ b/src/test/ui/typeck/issue-87181/tuple-field.rs @@ -0,0 +1,14 @@ +struct Bar<T> { + bar: T +} + +struct Foo(char, u16); +impl Foo { + fn foo() { } +} + +fn main() { + let thing = Bar { bar: Foo }; + thing.bar.0; + //~^ ERROR no field `0` on type `fn(char, u16) -> Foo {Foo}` [E0609] +} diff --git a/src/test/ui/typeck/issue-87181/tuple-field.stderr b/src/test/ui/typeck/issue-87181/tuple-field.stderr new file mode 100644 index 000000000..4d22ada02 --- /dev/null +++ b/src/test/ui/typeck/issue-87181/tuple-field.stderr @@ -0,0 +1,16 @@ +error[E0609]: no field `0` on type `fn(char, u16) -> Foo {Foo}` + --> $DIR/tuple-field.rs:12:15 + | +LL | thing.bar.0; + | --------- ^ + | | + | this is the constructor of a struct + | +help: call the constructor + | +LL | (thing.bar)(_, _).0; + | + +++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0609`. diff --git a/src/test/ui/typeck/issue-87181/tuple-method.rs b/src/test/ui/typeck/issue-87181/tuple-method.rs new file mode 100644 index 000000000..e88f642b0 --- /dev/null +++ b/src/test/ui/typeck/issue-87181/tuple-method.rs @@ -0,0 +1,14 @@ +struct Bar<T> { + bar: T +} + +struct Foo(u8, i32); +impl Foo { + fn foo() { } +} + +fn main() { + let thing = Bar { bar: Foo }; + thing.bar.foo(); + //~^ ERROR no method named `foo` found for fn item `fn(u8, i32) -> Foo {Foo}` in the current scope [E0599] +} diff --git a/src/test/ui/typeck/issue-87181/tuple-method.stderr b/src/test/ui/typeck/issue-87181/tuple-method.stderr new file mode 100644 index 000000000..1e392e179 --- /dev/null +++ b/src/test/ui/typeck/issue-87181/tuple-method.stderr @@ -0,0 +1,16 @@ +error[E0599]: no method named `foo` found for fn item `fn(u8, i32) -> Foo {Foo}` in the current scope + --> $DIR/tuple-method.rs:12:15 + | +LL | thing.bar.foo(); + | --------- ^^^ method not found in `fn(u8, i32) -> Foo {Foo}` + | | + | this is the constructor of a struct + | +help: call the constructor + | +LL | (thing.bar)(_, _).foo(); + | + +++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/typeck/issue-87771-ice-assign-assign-to-bool.rs b/src/test/ui/typeck/issue-87771-ice-assign-assign-to-bool.rs new file mode 100644 index 000000000..751dc8719 --- /dev/null +++ b/src/test/ui/typeck/issue-87771-ice-assign-assign-to-bool.rs @@ -0,0 +1,4 @@ +fn main() { + let mut a; + a = a = true; //~ ERROR mismatched types +} diff --git a/src/test/ui/typeck/issue-87771-ice-assign-assign-to-bool.stderr b/src/test/ui/typeck/issue-87771-ice-assign-assign-to-bool.stderr new file mode 100644 index 000000000..56817ee2c --- /dev/null +++ b/src/test/ui/typeck/issue-87771-ice-assign-assign-to-bool.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/issue-87771-ice-assign-assign-to-bool.rs:3:9 + | +LL | let mut a; + | ----- expected due to the type of this binding +LL | a = a = true; + | ^^^^^^^^ expected `bool`, found `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.rs b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.rs new file mode 100644 index 000000000..326e958aa --- /dev/null +++ b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.rs @@ -0,0 +1,11 @@ +pub mod foo { + pub struct Foo { + pub you_can_use_this_field: bool, + you_cant_use_this_field: bool, + } +} + +fn main() { + foo::Foo {}; + //~^ ERROR cannot construct `Foo` with struct literal syntax due to private fields +} diff --git a/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr new file mode 100644 index 000000000..f0bd3e0dd --- /dev/null +++ b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr @@ -0,0 +1,10 @@ +error: cannot construct `Foo` with struct literal syntax due to private fields + --> $DIR/issue-87872-missing-inaccessible-field-literal.rs:9:5 + | +LL | foo::Foo {}; + | ^^^^^^^^ + | + = note: ... and other private field `you_cant_use_this_field` that was not provided + +error: aborting due to previous error + diff --git a/src/test/ui/typeck/issue-87872-missing-inaccessible-field-pattern.rs b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-pattern.rs new file mode 100644 index 000000000..d28e17559 --- /dev/null +++ b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-pattern.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, unused_variables)] + +pub mod foo { + #[derive(Default)] + pub struct Foo { pub visible: bool, invisible: bool, } +} + +fn main() { + let foo::Foo {} = foo::Foo::default(); + //~^ ERROR pattern does not mention field `visible` and inaccessible fields +} diff --git a/src/test/ui/typeck/issue-87872-missing-inaccessible-field-pattern.stderr b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-pattern.stderr new file mode 100644 index 000000000..dc3097510 --- /dev/null +++ b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-pattern.stderr @@ -0,0 +1,18 @@ +error[E0027]: pattern does not mention field `visible` and inaccessible fields + --> $DIR/issue-87872-missing-inaccessible-field-pattern.rs:9:9 + | +LL | let foo::Foo {} = foo::Foo::default(); + | ^^^^^^^^^^^ missing field `visible` and inaccessible fields + | +help: include the missing field in the pattern and ignore the inaccessible fields + | +LL | let foo::Foo { visible, .. } = foo::Foo::default(); + | ~~~~~~~~~~~~~~~ +help: if you don't care about this missing field, you can explicitly ignore it + | +LL | let foo::Foo { .. } = foo::Foo::default(); + | ~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0027`. diff --git a/src/test/ui/typeck/issue-87935-unsized-box-expr.rs b/src/test/ui/typeck/issue-87935-unsized-box-expr.rs new file mode 100644 index 000000000..cd2a82074 --- /dev/null +++ b/src/test/ui/typeck/issue-87935-unsized-box-expr.rs @@ -0,0 +1,10 @@ +#![feature(box_syntax)] +// Box expression needs to be movable, and hence has to be of a Sized type. +fn main() { + let _x: Box<[u32]> = box { loop {} }; + //~^ ERROR: the size for values of type `[u32]` cannot be known at compilation time + + // Check that a deduced size does not cause issues. + let _y: Box<[u32]> = box []; + let _z: Box<[u32; 0]> = box { loop {} }; +} diff --git a/src/test/ui/typeck/issue-87935-unsized-box-expr.stderr b/src/test/ui/typeck/issue-87935-unsized-box-expr.stderr new file mode 100644 index 000000000..9ff822352 --- /dev/null +++ b/src/test/ui/typeck/issue-87935-unsized-box-expr.stderr @@ -0,0 +1,12 @@ +error[E0277]: the size for values of type `[u32]` cannot be known at compilation time + --> $DIR/issue-87935-unsized-box-expr.rs:4:30 + | +LL | let _x: Box<[u32]> = box { loop {} }; + | ^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u32]` + = note: the type of a box expression must have a statically known size + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/typeck/issue-88609.rs b/src/test/ui/typeck/issue-88609.rs new file mode 100644 index 000000000..dc459c885 --- /dev/null +++ b/src/test/ui/typeck/issue-88609.rs @@ -0,0 +1,19 @@ +// Regression test for #88609: +// The return type for `main` is not normalized while checking if it implements +// the trait `std::process::Termination`. + +// build-pass + +trait Same { + type Output; +} + +impl<T> Same for T { + type Output = T; +} + +type Unit = <() as Same>::Output; + +fn main() -> Result<Unit, std::io::Error> { + unimplemented!() +} diff --git a/src/test/ui/typeck/issue-88643.rs b/src/test/ui/typeck/issue-88643.rs new file mode 100644 index 000000000..4435cba02 --- /dev/null +++ b/src/test/ui/typeck/issue-88643.rs @@ -0,0 +1,19 @@ +// Regression test for the ICE described in #88643. Specifically: +// https://github.com/rust-lang/rust/issues/88643#issuecomment-913128893 +// and https://github.com/rust-lang/rust/issues/88643#issuecomment-913171935 +// and https://github.com/rust-lang/rust/issues/88643#issuecomment-913765984 + +use std::collections::HashMap; + +pub trait T {} + +static CALLBACKS: HashMap<*const dyn T, dyn FnMut(&mut _) + 'static> = HashMap::new(); +//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for static items [E0121] + +static CALLBACKS2: Vec<dyn Fn(& _)> = Vec::new(); +//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for static items [E0121] + +static CALLBACKS3: Option<dyn Fn(& _)> = None; +//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for static items [E0121] + +fn main() {} diff --git a/src/test/ui/typeck/issue-88643.stderr b/src/test/ui/typeck/issue-88643.stderr new file mode 100644 index 000000000..d5d596b6f --- /dev/null +++ b/src/test/ui/typeck/issue-88643.stderr @@ -0,0 +1,21 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static items + --> $DIR/issue-88643.rs:10:56 + | +LL | static CALLBACKS: HashMap<*const dyn T, dyn FnMut(&mut _) + 'static> = HashMap::new(); + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static items + --> $DIR/issue-88643.rs:13:33 + | +LL | static CALLBACKS2: Vec<dyn Fn(& _)> = Vec::new(); + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static items + --> $DIR/issue-88643.rs:16:36 + | +LL | static CALLBACKS3: Option<dyn Fn(& _)> = None; + | ^ not allowed in type signatures + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/typeck/issue-88803-call-expr-method.fixed b/src/test/ui/typeck/issue-88803-call-expr-method.fixed new file mode 100644 index 000000000..19b96ecf3 --- /dev/null +++ b/src/test/ui/typeck/issue-88803-call-expr-method.fixed @@ -0,0 +1,9 @@ +// run-rustfix + +fn main() { + let a = Some(42); + println!( + "The value is {}.", + a.unwrap() //~ERROR [E0615] + ); +} diff --git a/src/test/ui/typeck/issue-88803-call-expr-method.rs b/src/test/ui/typeck/issue-88803-call-expr-method.rs new file mode 100644 index 000000000..a06199466 --- /dev/null +++ b/src/test/ui/typeck/issue-88803-call-expr-method.rs @@ -0,0 +1,9 @@ +// run-rustfix + +fn main() { + let a = Some(42); + println!( + "The value is {}.", + (a.unwrap)() //~ERROR [E0615] + ); +} diff --git a/src/test/ui/typeck/issue-88803-call-expr-method.stderr b/src/test/ui/typeck/issue-88803-call-expr-method.stderr new file mode 100644 index 000000000..645c04b87 --- /dev/null +++ b/src/test/ui/typeck/issue-88803-call-expr-method.stderr @@ -0,0 +1,15 @@ +error[E0615]: attempted to take value of method `unwrap` on type `Option<{integer}>` + --> $DIR/issue-88803-call-expr-method.rs:7:12 + | +LL | (a.unwrap)() + | ^^^^^^ method, not a field + | +help: remove wrapping parentheses to call the method + | +LL - (a.unwrap)() +LL + a.unwrap() + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0615`. diff --git a/src/test/ui/typeck/issue-88844.rs b/src/test/ui/typeck/issue-88844.rs new file mode 100644 index 000000000..116c75aab --- /dev/null +++ b/src/test/ui/typeck/issue-88844.rs @@ -0,0 +1,14 @@ +// Regression test for #88844. + +struct Struct { value: i32 } +//~^ NOTE: similarly named struct `Struct` defined here + +impl Stuct { +//~^ ERROR: cannot find type `Stuct` in this scope [E0412] +//~| HELP: a struct with a similar name exists + fn new() -> Self { + Self { value: 42 } + } +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-88844.stderr b/src/test/ui/typeck/issue-88844.stderr new file mode 100644 index 000000000..90bba90be --- /dev/null +++ b/src/test/ui/typeck/issue-88844.stderr @@ -0,0 +1,12 @@ +error[E0412]: cannot find type `Stuct` in this scope + --> $DIR/issue-88844.rs:6:6 + | +LL | struct Struct { value: i32 } + | ------------- similarly named struct `Struct` defined here +... +LL | impl Stuct { + | ^^^^^ help: a struct with a similar name exists: `Struct` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/typeck/issue-89044-wrapped-expr-method.fixed b/src/test/ui/typeck/issue-89044-wrapped-expr-method.fixed new file mode 100644 index 000000000..0a3086a34 --- /dev/null +++ b/src/test/ui/typeck/issue-89044-wrapped-expr-method.fixed @@ -0,0 +1,9 @@ +// run-rustfix + +fn main() { + let a = Some(42); + println!( + "The value is {}.", + (a.unwrap()) //~ERROR [E0615] + ); +} diff --git a/src/test/ui/typeck/issue-89044-wrapped-expr-method.rs b/src/test/ui/typeck/issue-89044-wrapped-expr-method.rs new file mode 100644 index 000000000..83617e035 --- /dev/null +++ b/src/test/ui/typeck/issue-89044-wrapped-expr-method.rs @@ -0,0 +1,9 @@ +// run-rustfix + +fn main() { + let a = Some(42); + println!( + "The value is {}.", + (a.unwrap) //~ERROR [E0615] + ); +} diff --git a/src/test/ui/typeck/issue-89044-wrapped-expr-method.stderr b/src/test/ui/typeck/issue-89044-wrapped-expr-method.stderr new file mode 100644 index 000000000..6fa0915dc --- /dev/null +++ b/src/test/ui/typeck/issue-89044-wrapped-expr-method.stderr @@ -0,0 +1,14 @@ +error[E0615]: attempted to take value of method `unwrap` on type `Option<{integer}>` + --> $DIR/issue-89044-wrapped-expr-method.rs:7:12 + | +LL | (a.unwrap) + | ^^^^^^ method, not a field + | +help: use parentheses to call the method + | +LL | (a.unwrap()) + | ++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0615`. diff --git a/src/test/ui/typeck/issue-89275.rs b/src/test/ui/typeck/issue-89275.rs new file mode 100644 index 000000000..b91c00175 --- /dev/null +++ b/src/test/ui/typeck/issue-89275.rs @@ -0,0 +1,29 @@ +#![recursion_limit = "5"] // To reduce noise + +//expect mutability error when ambiguous traits are in scope +//and not an overflow error on the span in the main function. + +struct Ratio<T>(T); + +pub trait Pow { + fn pow(self) -> Self; +} + +impl<'a, T> Pow for &'a Ratio<T> +where + &'a T: Pow, +{ + fn pow(self) -> Self { + self + } +} + +fn downcast<'a, W: ?Sized>() -> &'a W { + todo!() +} + +struct Other; + +fn main() { + let other: &mut Other = downcast();//~ERROR 28:29: 28:39: mismatched types [E0308] +} diff --git a/src/test/ui/typeck/issue-89275.stderr b/src/test/ui/typeck/issue-89275.stderr new file mode 100644 index 000000000..d73e647d2 --- /dev/null +++ b/src/test/ui/typeck/issue-89275.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/issue-89275.rs:28:29 + | +LL | let other: &mut Other = downcast(); + | ---------- ^^^^^^^^^^ types differ in mutability + | | + | expected due to this + | + = note: expected mutable reference `&mut Other` + found reference `&_` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/issue-89806.rs b/src/test/ui/typeck/issue-89806.rs new file mode 100644 index 000000000..69cec0865 --- /dev/null +++ b/src/test/ui/typeck/issue-89806.rs @@ -0,0 +1,3 @@ +fn main() { + 0u8.as_ref(); //~ ERROR no method named `as_ref` found for type `u8` in the current scope +} diff --git a/src/test/ui/typeck/issue-89806.stderr b/src/test/ui/typeck/issue-89806.stderr new file mode 100644 index 000000000..c36b4967e --- /dev/null +++ b/src/test/ui/typeck/issue-89806.stderr @@ -0,0 +1,9 @@ +error[E0599]: no method named `as_ref` found for type `u8` in the current scope + --> $DIR/issue-89806.rs:2:9 + | +LL | 0u8.as_ref(); + | ^^^^^^ method not found in `u8` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/typeck/issue-89856.rs b/src/test/ui/typeck/issue-89856.rs new file mode 100644 index 000000000..b021e349e --- /dev/null +++ b/src/test/ui/typeck/issue-89856.rs @@ -0,0 +1,8 @@ +fn take_str_maybe(x: Option<&str>) -> Option<&str> { None } + +fn main() { + let string = String::from("Hello, world"); + let option = Some(&string); + take_str_maybe(option); + //~^ ERROR: mismatched types [E0308] +} diff --git a/src/test/ui/typeck/issue-89856.stderr b/src/test/ui/typeck/issue-89856.stderr new file mode 100644 index 000000000..5fa1ae1a5 --- /dev/null +++ b/src/test/ui/typeck/issue-89856.stderr @@ -0,0 +1,23 @@ +error[E0308]: mismatched types + --> $DIR/issue-89856.rs:6:20 + | +LL | take_str_maybe(option); + | -------------- ^^^^^^ expected `str`, found struct `String` + | | + | arguments to this function are incorrect + | + = note: expected enum `Option<&str>` + found enum `Option<&String>` +note: function defined here + --> $DIR/issue-89856.rs:1:4 + | +LL | fn take_str_maybe(x: Option<&str>) -> Option<&str> { None } + | ^^^^^^^^^^^^^^ --------------- +help: try converting the passed type into a `&str` + | +LL | take_str_maybe(option.map(|x| &**x)); + | ++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/issue-89935.rs b/src/test/ui/typeck/issue-89935.rs new file mode 100644 index 000000000..03f8f09a7 --- /dev/null +++ b/src/test/ui/typeck/issue-89935.rs @@ -0,0 +1,18 @@ +// check-pass + +trait Foo: Baz {} +trait Bar {} +trait Baz: Bar { + fn bar(&self); +} + +impl<T: Foo> Bar for T {} +impl<T: Foo> Baz for T { + fn bar(&self) {} +} + +fn accept_foo(x: Box<dyn Foo>) { + x.bar(); +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-90101.rs b/src/test/ui/typeck/issue-90101.rs new file mode 100644 index 000000000..1954ee6f1 --- /dev/null +++ b/src/test/ui/typeck/issue-90101.rs @@ -0,0 +1,8 @@ +use std::path::{Path, PathBuf}; + +fn func(path: impl Into<PathBuf>, code: impl Into<String>) {} + +fn main() { + func(Path::new("hello").to_path_buf().to_string_lossy(), "world") + //~^ ERROR [E0277] +} diff --git a/src/test/ui/typeck/issue-90101.stderr b/src/test/ui/typeck/issue-90101.stderr new file mode 100644 index 000000000..ab9a72edf --- /dev/null +++ b/src/test/ui/typeck/issue-90101.stderr @@ -0,0 +1,24 @@ +error[E0277]: the trait bound `PathBuf: From<Cow<'_, str>>` is not satisfied + --> $DIR/issue-90101.rs:6:10 + | +LL | func(Path::new("hello").to_path_buf().to_string_lossy(), "world") + | ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<Cow<'_, str>>` is not implemented for `PathBuf` + | | + | required by a bound introduced by this call + | + = help: the following other types implement trait `From<T>`: + <PathBuf as From<&T>> + <PathBuf as From<Box<Path>>> + <PathBuf as From<Cow<'a, Path>>> + <PathBuf as From<OsString>> + <PathBuf as From<String>> + = note: required because of the requirements on the impl of `Into<PathBuf>` for `Cow<'_, str>` +note: required by a bound in `func` + --> $DIR/issue-90101.rs:3:20 + | +LL | fn func(path: impl Into<PathBuf>, code: impl Into<String>) {} + | ^^^^^^^^^^^^^ required by this bound in `func` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/typeck/issue-90164.rs b/src/test/ui/typeck/issue-90164.rs new file mode 100644 index 000000000..63350433e --- /dev/null +++ b/src/test/ui/typeck/issue-90164.rs @@ -0,0 +1,9 @@ +fn copy<R: Unpin, W>(_: R, _: W) {} + +fn f<T>(r: T) { + let w = (); + copy(r, w); + //~^ ERROR [E0277] +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-90164.stderr b/src/test/ui/typeck/issue-90164.stderr new file mode 100644 index 000000000..1e2f1bae3 --- /dev/null +++ b/src/test/ui/typeck/issue-90164.stderr @@ -0,0 +1,22 @@ +error[E0277]: `T` cannot be unpinned + --> $DIR/issue-90164.rs:5:10 + | +LL | copy(r, w); + | ---- ^ the trait `Unpin` is not implemented for `T` + | | + | required by a bound introduced by this call + | + = note: consider using `Box::pin` +note: required by a bound in `copy` + --> $DIR/issue-90164.rs:1:12 + | +LL | fn copy<R: Unpin, W>(_: R, _: W) {} + | ^^^^^ required by this bound in `copy` +help: consider restricting type parameter `T` + | +LL | fn f<T: std::marker::Unpin>(r: T) { + | ++++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/typeck/issue-90319.rs b/src/test/ui/typeck/issue-90319.rs new file mode 100644 index 000000000..57e6ac7cf --- /dev/null +++ b/src/test/ui/typeck/issue-90319.rs @@ -0,0 +1,17 @@ +struct Wrapper<T>(T); + +trait Trait { + fn method(&self) {} +} + +impl<'a, T> Trait for Wrapper<&'a T> where Wrapper<T>: Trait {} + +fn get<T>() -> T { + unimplemented!() +} + +fn main() { + let thing = get::<Thing>();//~ERROR cannot find type `Thing` in this scope [E0412] + let wrapper = Wrapper(thing); + Trait::method(&wrapper); +} diff --git a/src/test/ui/typeck/issue-90319.stderr b/src/test/ui/typeck/issue-90319.stderr new file mode 100644 index 000000000..61549dd70 --- /dev/null +++ b/src/test/ui/typeck/issue-90319.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Thing` in this scope + --> $DIR/issue-90319.rs:14:23 + | +LL | let thing = get::<Thing>(); + | ^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/typeck/issue-90483-inaccessible-field-adjustment.rs b/src/test/ui/typeck/issue-90483-inaccessible-field-adjustment.rs new file mode 100644 index 000000000..74e50d46e --- /dev/null +++ b/src/test/ui/typeck/issue-90483-inaccessible-field-adjustment.rs @@ -0,0 +1,14 @@ +// edition:2021 + +mod m { + pub struct S { foo: i32 } + impl S { + pub fn foo(&self) -> i32 { 42 } + } +} + +fn bar(s: &m::S) { + || s.foo() + s.foo; //~ ERROR E0616 +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-90483-inaccessible-field-adjustment.stderr b/src/test/ui/typeck/issue-90483-inaccessible-field-adjustment.stderr new file mode 100644 index 000000000..02cdc102c --- /dev/null +++ b/src/test/ui/typeck/issue-90483-inaccessible-field-adjustment.stderr @@ -0,0 +1,14 @@ +error[E0616]: field `foo` of struct `S` is private + --> $DIR/issue-90483-inaccessible-field-adjustment.rs:11:18 + | +LL | || s.foo() + s.foo; + | ^^^ private field + | +help: a method `foo` also exists, call it with parentheses + | +LL | || s.foo() + s.foo(); + | ++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0616`. diff --git a/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.rs b/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.rs new file mode 100644 index 000000000..f891a42fc --- /dev/null +++ b/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.rs @@ -0,0 +1,11 @@ +// Do not suggest referencing the parameter to `check` + +trait Marker<T> {} + +impl<T> Marker<i32> for T {} + +pub fn check<T: Marker<u32>>(_: T) {} + +pub fn main() { + check::<()>(()); //~ ERROR [E0277] +} diff --git a/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.stderr b/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.stderr new file mode 100644 index 000000000..08eab0253 --- /dev/null +++ b/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `(): Marker<u32>` is not satisfied + --> $DIR/issue-90804-incorrect-reference-suggestion.rs:10:17 + | +LL | check::<()>(()); + | ----------- ^^ the trait `Marker<u32>` is not implemented for `()` + | | + | required by a bound introduced by this call + | +note: required by a bound in `check` + --> $DIR/issue-90804-incorrect-reference-suggestion.rs:7:17 + | +LL | pub fn check<T: Marker<u32>>(_: T) {} + | ^^^^^^^^^^^ required by this bound in `check` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/typeck/issue-91210-ptr-method.fixed b/src/test/ui/typeck/issue-91210-ptr-method.fixed new file mode 100644 index 000000000..94200cce7 --- /dev/null +++ b/src/test/ui/typeck/issue-91210-ptr-method.fixed @@ -0,0 +1,15 @@ +// Regression test for issue #91210. + +// run-rustfix + +#![allow(unused)] + +struct Foo { read: i32 } + +unsafe fn blah(x: *mut Foo) { + (*x).read = 4; + //~^ ERROR: attempted to take value of method + //~| HELP: to access the field, dereference first +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-91210-ptr-method.rs b/src/test/ui/typeck/issue-91210-ptr-method.rs new file mode 100644 index 000000000..ed0ce6eff --- /dev/null +++ b/src/test/ui/typeck/issue-91210-ptr-method.rs @@ -0,0 +1,15 @@ +// Regression test for issue #91210. + +// run-rustfix + +#![allow(unused)] + +struct Foo { read: i32 } + +unsafe fn blah(x: *mut Foo) { + x.read = 4; + //~^ ERROR: attempted to take value of method + //~| HELP: to access the field, dereference first +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-91210-ptr-method.stderr b/src/test/ui/typeck/issue-91210-ptr-method.stderr new file mode 100644 index 000000000..503a32373 --- /dev/null +++ b/src/test/ui/typeck/issue-91210-ptr-method.stderr @@ -0,0 +1,11 @@ +error[E0615]: attempted to take value of method `read` on type `*mut Foo` + --> $DIR/issue-91210-ptr-method.rs:10:7 + | +LL | x.read = 4; + | - ^^^^ method, not a field + | | + | help: to access the field, dereference first: `(*x)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0615`. diff --git a/src/test/ui/typeck/issue-91267.rs b/src/test/ui/typeck/issue-91267.rs new file mode 100644 index 000000000..f5a37e9cb --- /dev/null +++ b/src/test/ui/typeck/issue-91267.rs @@ -0,0 +1,6 @@ +fn main() { + 0: u8<e<5>=e> + //~^ ERROR: cannot find type `e` in this scope [E0412] + //~| ERROR: associated type bindings are not allowed here [E0229] + //~| ERROR: mismatched types [E0308] +} diff --git a/src/test/ui/typeck/issue-91267.stderr b/src/test/ui/typeck/issue-91267.stderr new file mode 100644 index 000000000..aac00b9b6 --- /dev/null +++ b/src/test/ui/typeck/issue-91267.stderr @@ -0,0 +1,27 @@ +error[E0412]: cannot find type `e` in this scope + --> $DIR/issue-91267.rs:2:16 + | +LL | 0: u8<e<5>=e> + | ^ + | | + | not found in this scope + | help: maybe you meant to write an assignment here: `let e` + +error[E0229]: associated type bindings are not allowed here + --> $DIR/issue-91267.rs:2:11 + | +LL | 0: u8<e<5>=e> + | ^^^^^^ associated type not allowed here + +error[E0308]: mismatched types + --> $DIR/issue-91267.rs:2:5 + | +LL | fn main() { + | - expected `()` because of default return type +LL | 0: u8<e<5>=e> + | ^^^^^^^^^^^^^ expected `()`, found `u8` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0229, E0308, E0412. +For more information about an error, try `rustc --explain E0229`. diff --git a/src/test/ui/typeck/issue-91328.fixed b/src/test/ui/typeck/issue-91328.fixed new file mode 100644 index 000000000..c0384399a --- /dev/null +++ b/src/test/ui/typeck/issue-91328.fixed @@ -0,0 +1,47 @@ +// Regression test for issue #91328. + +// run-rustfix + +#![allow(dead_code)] + +fn foo(r: Result<Vec<i32>, i32>) -> i32 { + match r.as_deref() { + //~^ HELP: consider using `as_deref` here + Ok([a, b]) => a + b, + //~^ ERROR: expected an array or slice + //~| NOTE: pattern cannot match with input type + _ => 42, + } +} + +fn bar(o: Option<Vec<i32>>) -> i32 { + match o.as_deref() { + //~^ HELP: consider using `as_deref` here + Some([a, b]) => a + b, + //~^ ERROR: expected an array or slice + //~| NOTE: pattern cannot match with input type + _ => 42, + } +} + +fn baz(v: Vec<i32>) -> i32 { + match v[..] { + //~^ HELP: consider slicing here + [a, b] => a + b, + //~^ ERROR: expected an array or slice + //~| NOTE: pattern cannot match with input type + _ => 42, + } +} + +fn qux(a: &Option<Box<[i32; 2]>>) -> i32 { + match a.as_deref() { + //~^ HELP: consider using `as_deref` here + Some([a, b]) => a + b, + //~^ ERROR: expected an array or slice + //~| NOTE: pattern cannot match with input type + _ => 42, + } +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-91328.rs b/src/test/ui/typeck/issue-91328.rs new file mode 100644 index 000000000..63602d26f --- /dev/null +++ b/src/test/ui/typeck/issue-91328.rs @@ -0,0 +1,47 @@ +// Regression test for issue #91328. + +// run-rustfix + +#![allow(dead_code)] + +fn foo(r: Result<Vec<i32>, i32>) -> i32 { + match r { + //~^ HELP: consider using `as_deref` here + Ok([a, b]) => a + b, + //~^ ERROR: expected an array or slice + //~| NOTE: pattern cannot match with input type + _ => 42, + } +} + +fn bar(o: Option<Vec<i32>>) -> i32 { + match o { + //~^ HELP: consider using `as_deref` here + Some([a, b]) => a + b, + //~^ ERROR: expected an array or slice + //~| NOTE: pattern cannot match with input type + _ => 42, + } +} + +fn baz(v: Vec<i32>) -> i32 { + match v { + //~^ HELP: consider slicing here + [a, b] => a + b, + //~^ ERROR: expected an array or slice + //~| NOTE: pattern cannot match with input type + _ => 42, + } +} + +fn qux(a: &Option<Box<[i32; 2]>>) -> i32 { + match a { + //~^ HELP: consider using `as_deref` here + Some([a, b]) => a + b, + //~^ ERROR: expected an array or slice + //~| NOTE: pattern cannot match with input type + _ => 42, + } +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-91328.stderr b/src/test/ui/typeck/issue-91328.stderr new file mode 100644 index 000000000..f2f407bca --- /dev/null +++ b/src/test/ui/typeck/issue-91328.stderr @@ -0,0 +1,39 @@ +error[E0529]: expected an array or slice, found `Vec<i32>` + --> $DIR/issue-91328.rs:10:12 + | +LL | match r { + | - help: consider using `as_deref` here: `r.as_deref()` +LL | +LL | Ok([a, b]) => a + b, + | ^^^^^^ pattern cannot match with input type `Vec<i32>` + +error[E0529]: expected an array or slice, found `Vec<i32>` + --> $DIR/issue-91328.rs:20:14 + | +LL | match o { + | - help: consider using `as_deref` here: `o.as_deref()` +LL | +LL | Some([a, b]) => a + b, + | ^^^^^^ pattern cannot match with input type `Vec<i32>` + +error[E0529]: expected an array or slice, found `Vec<i32>` + --> $DIR/issue-91328.rs:30:9 + | +LL | match v { + | - help: consider slicing here: `v[..]` +LL | +LL | [a, b] => a + b, + | ^^^^^^ pattern cannot match with input type `Vec<i32>` + +error[E0529]: expected an array or slice, found `Box<[i32; 2]>` + --> $DIR/issue-91328.rs:40:14 + | +LL | match a { + | - help: consider using `as_deref` here: `a.as_deref()` +LL | +LL | Some([a, b]) => a + b, + | ^^^^^^ pattern cannot match with input type `Box<[i32; 2]>` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0529`. diff --git a/src/test/ui/typeck/issue-91334.rs b/src/test/ui/typeck/issue-91334.rs new file mode 100644 index 000000000..bf9a5a626 --- /dev/null +++ b/src/test/ui/typeck/issue-91334.rs @@ -0,0 +1,10 @@ +// Regression test for the ICE described in issue #91334. + +// error-pattern: this file contains an unclosed delimiter +// error-pattern: expected one of +// error-pattern: mismatched closing delimiter +// error-pattern: mismatched types + +#![feature(generators)] + +fn f(){||yield(((){), diff --git a/src/test/ui/typeck/issue-91334.stderr b/src/test/ui/typeck/issue-91334.stderr new file mode 100644 index 000000000..8508f7a38 --- /dev/null +++ b/src/test/ui/typeck/issue-91334.stderr @@ -0,0 +1,50 @@ +error: this file contains an unclosed delimiter + --> $DIR/issue-91334.rs:10:23 + | +LL | fn f(){||yield(((){), + | - - ^ + | | | + | | unclosed delimiter + | unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-91334.rs:10:23 + | +LL | fn f(){||yield(((){), + | - - ^ + | | | + | | unclosed delimiter + | unclosed delimiter + +error: expected one of `)`, `,`, `.`, `?`, or an operator, found `{` + --> $DIR/issue-91334.rs:10:19 + | +LL | fn f(){||yield(((){), + | ^ + | | + | expected one of `)`, `,`, `.`, `?`, or an operator + | help: missing `,` + +error: mismatched closing delimiter: `)` + --> $DIR/issue-91334.rs:10:19 + | +LL | fn f(){||yield(((){), + | - ^^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error[E0308]: mismatched types + --> $DIR/issue-91334.rs:10:8 + | +LL | fn f(){||yield(((){), + | -^^^^^^^^^^^^^^^ expected `()`, found generator + | | + | help: a return type might be missing here: `-> _` + | + = note: expected unit type `()` + found generator `[generator@$DIR/issue-91334.rs:10:8: 10:10]` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/issue-91450-inner-ty-error.rs b/src/test/ui/typeck/issue-91450-inner-ty-error.rs new file mode 100644 index 000000000..3c7c990d4 --- /dev/null +++ b/src/test/ui/typeck/issue-91450-inner-ty-error.rs @@ -0,0 +1,7 @@ +// Regression test for #91450. +// This test ensures that the compiler does not suggest `Foo<[type error]>` in diagnostic messages. + +fn foo() -> Option<_> {} //~ ERROR: [E0308] +//~^ ERROR: the placeholder `_` is not allowed + +fn main() {} diff --git a/src/test/ui/typeck/issue-91450-inner-ty-error.stderr b/src/test/ui/typeck/issue-91450-inner-ty-error.stderr new file mode 100644 index 000000000..32f4c8f6f --- /dev/null +++ b/src/test/ui/typeck/issue-91450-inner-ty-error.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/issue-91450-inner-ty-error.rs:4:13 + | +LL | fn foo() -> Option<_> {} + | --- ^^^^^^^^^ expected enum `Option`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | + = note: expected enum `Option<_>` + found unit type `()` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/issue-91450-inner-ty-error.rs:4:20 + | +LL | fn foo() -> Option<_> {} + | ^ not allowed in type signatures + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0121, E0308. +For more information about an error, try `rustc --explain E0121`. diff --git a/src/test/ui/typeck/issue-93486.rs b/src/test/ui/typeck/issue-93486.rs new file mode 100644 index 000000000..f8f98d5c1 --- /dev/null +++ b/src/test/ui/typeck/issue-93486.rs @@ -0,0 +1,6 @@ +fn main() { + while let 1 = 1 { + vec![].last_mut().unwrap() = 3_u8; + //~^ ERROR invalid left-hand side of assignment + } +} diff --git a/src/test/ui/typeck/issue-93486.stderr b/src/test/ui/typeck/issue-93486.stderr new file mode 100644 index 000000000..167edc894 --- /dev/null +++ b/src/test/ui/typeck/issue-93486.stderr @@ -0,0 +1,16 @@ +error[E0070]: invalid left-hand side of assignment + --> $DIR/issue-93486.rs:3:36 + | +LL | vec![].last_mut().unwrap() = 3_u8; + | -------------------------- ^ + | | + | cannot assign to this expression + | +help: consider dereferencing here to assign to the mutably borrowed value + | +LL | *vec![].last_mut().unwrap() = 3_u8; + | + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0070`. diff --git a/src/test/ui/typeck/issue-96738.rs b/src/test/ui/typeck/issue-96738.rs new file mode 100644 index 000000000..ce2556f86 --- /dev/null +++ b/src/test/ui/typeck/issue-96738.rs @@ -0,0 +1,4 @@ +fn main() { + Some.nonexistent_method(); //~ ERROR: no method named `nonexistent_method` found + Some.nonexistent_field; //~ ERROR: no field `nonexistent_field` +} diff --git a/src/test/ui/typeck/issue-96738.stderr b/src/test/ui/typeck/issue-96738.stderr new file mode 100644 index 000000000..32f538498 --- /dev/null +++ b/src/test/ui/typeck/issue-96738.stderr @@ -0,0 +1,30 @@ +error[E0599]: no method named `nonexistent_method` found for fn item `fn(_) -> Option<_> {Option::<_>::Some}` in the current scope + --> $DIR/issue-96738.rs:2:10 + | +LL | Some.nonexistent_method(); + | ---- ^^^^^^^^^^^^^^^^^^ method not found in `fn(_) -> Option<_> {Option::<_>::Some}` + | | + | this is the constructor of an enum variant + | +help: call the constructor + | +LL | (Some)(_).nonexistent_method(); + | + ++++ + +error[E0609]: no field `nonexistent_field` on type `fn(_) -> Option<_> {Option::<_>::Some}` + --> $DIR/issue-96738.rs:3:10 + | +LL | Some.nonexistent_field; + | ---- ^^^^^^^^^^^^^^^^^ + | | + | this is the constructor of an enum variant + | +help: call the constructor + | +LL | (Some)(_).nonexistent_field; + | + ++++ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0599, E0609. +For more information about an error, try `rustc --explain E0599`. diff --git a/src/test/ui/typeck/issue-98260.rs b/src/test/ui/typeck/issue-98260.rs new file mode 100644 index 000000000..cf48294e1 --- /dev/null +++ b/src/test/ui/typeck/issue-98260.rs @@ -0,0 +1,9 @@ +fn main() {} +trait A { + fn a(aa: B) -> Result<_, B> { + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for return types [E0121] + Ok(()) + } +} + +enum B {} diff --git a/src/test/ui/typeck/issue-98260.stderr b/src/test/ui/typeck/issue-98260.stderr new file mode 100644 index 000000000..08a1d17e2 --- /dev/null +++ b/src/test/ui/typeck/issue-98260.stderr @@ -0,0 +1,12 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/issue-98260.rs:3:27 + | +LL | fn a(aa: B) -> Result<_, B> { + | -------^---- + | | | + | | not allowed in type signatures + | help: replace with the correct return type: `Result<(), B>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/typeck/missing-private-fields-in-struct-literal.rs b/src/test/ui/typeck/missing-private-fields-in-struct-literal.rs new file mode 100644 index 000000000..9f1560bfb --- /dev/null +++ b/src/test/ui/typeck/missing-private-fields-in-struct-literal.rs @@ -0,0 +1,18 @@ +pub mod m { + pub struct S { + pub visible: bool, + a: (), + b: (), + c: (), + d: (), + e: (), + } +} + +fn main() { + let _ = m::S { //~ ERROR cannot construct `S` with struct literal syntax due to private fields + visible: true, + a: (), + b: (), + }; +} diff --git a/src/test/ui/typeck/missing-private-fields-in-struct-literal.stderr b/src/test/ui/typeck/missing-private-fields-in-struct-literal.stderr new file mode 100644 index 000000000..234110f31 --- /dev/null +++ b/src/test/ui/typeck/missing-private-fields-in-struct-literal.stderr @@ -0,0 +1,15 @@ +error: cannot construct `S` with struct literal syntax due to private fields + --> $DIR/missing-private-fields-in-struct-literal.rs:13:13 + | +LL | let _ = m::S { + | ^^^^ +LL | visible: true, +LL | a: (), + | ----- private field +LL | b: (), + | ----- private field + | + = note: ... and other private fields `c`, `d` and `e` that were not provided + +error: aborting due to previous error + diff --git a/src/test/ui/typeck/no-type-for-node-ice.rs b/src/test/ui/typeck/no-type-for-node-ice.rs new file mode 100644 index 000000000..d0cfdbf50 --- /dev/null +++ b/src/test/ui/typeck/no-type-for-node-ice.rs @@ -0,0 +1,5 @@ +// Related issues: #20401, #20506, #20614, #20752, #20829, #20846, #20885, #20886 + +fn main() { + "".homura[""]; //~ no field `homura` on type `&'static str` +} diff --git a/src/test/ui/typeck/no-type-for-node-ice.stderr b/src/test/ui/typeck/no-type-for-node-ice.stderr new file mode 100644 index 000000000..b50241fb1 --- /dev/null +++ b/src/test/ui/typeck/no-type-for-node-ice.stderr @@ -0,0 +1,9 @@ +error[E0609]: no field `homura` on type `&'static str` + --> $DIR/no-type-for-node-ice.rs:4:8 + | +LL | "".homura[""]; + | ^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0609`. diff --git a/src/test/ui/typeck/point-at-type-parameter-definition.rs b/src/test/ui/typeck/point-at-type-parameter-definition.rs new file mode 100644 index 000000000..856c0db08 --- /dev/null +++ b/src/test/ui/typeck/point-at-type-parameter-definition.rs @@ -0,0 +1,17 @@ +trait Trait { + fn do_stuff(&self); +} + +struct Hello; + +impl Hello { + fn method(&self) {} +} + +impl<Hello> Trait for Vec<Hello> { + fn do_stuff(&self) { + self[0].method(); //~ ERROR no method named `method` found for type parameter `Hello` in the current scope + } +} + +fn main() {} diff --git a/src/test/ui/typeck/point-at-type-parameter-definition.stderr b/src/test/ui/typeck/point-at-type-parameter-definition.stderr new file mode 100644 index 000000000..8a6ab6110 --- /dev/null +++ b/src/test/ui/typeck/point-at-type-parameter-definition.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `method` found for type parameter `Hello` in the current scope + --> $DIR/point-at-type-parameter-definition.rs:13:17 + | +LL | impl<Hello> Trait for Vec<Hello> { + | ----- method `method` not found for this type parameter +LL | fn do_stuff(&self) { +LL | self[0].method(); + | ^^^^^^ method not found in `Hello` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/typeck/prim-with-args.fixed b/src/test/ui/typeck/prim-with-args.fixed new file mode 100644 index 000000000..e3f99479a --- /dev/null +++ b/src/test/ui/typeck/prim-with-args.fixed @@ -0,0 +1,28 @@ +// run-rustfix +fn main() { + +let _x: isize; //~ ERROR type arguments are not allowed on builtin type +let _x: i8; //~ ERROR type arguments are not allowed on builtin type +let _x: i16; //~ ERROR type arguments are not allowed on builtin type +let _x: i32; //~ ERROR type arguments are not allowed on builtin type +let _x: i64; //~ ERROR type arguments are not allowed on builtin type +let _x: usize; //~ ERROR type arguments are not allowed on builtin type +let _x: u8; //~ ERROR type arguments are not allowed on builtin type +let _x: u16; //~ ERROR type arguments are not allowed on builtin type +let _x: u32; //~ ERROR type arguments are not allowed on builtin type +let _x: u64; //~ ERROR type arguments are not allowed on builtin type +let _x: char; //~ ERROR type arguments are not allowed on builtin type + +let _x: isize; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i8; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i16; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i32; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i64; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: usize; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u8; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u16; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u32; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u64; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: char; //~ ERROR lifetime arguments are not allowed on builtin type + +} diff --git a/src/test/ui/typeck/prim-with-args.rs b/src/test/ui/typeck/prim-with-args.rs new file mode 100644 index 000000000..b10471ecc --- /dev/null +++ b/src/test/ui/typeck/prim-with-args.rs @@ -0,0 +1,28 @@ +// run-rustfix +fn main() { + +let _x: isize<isize>; //~ ERROR type arguments are not allowed on builtin type +let _x: i8<isize>; //~ ERROR type arguments are not allowed on builtin type +let _x: i16<isize>; //~ ERROR type arguments are not allowed on builtin type +let _x: i32<isize>; //~ ERROR type arguments are not allowed on builtin type +let _x: i64<isize>; //~ ERROR type arguments are not allowed on builtin type +let _x: usize<isize>; //~ ERROR type arguments are not allowed on builtin type +let _x: u8<isize>; //~ ERROR type arguments are not allowed on builtin type +let _x: u16<isize>; //~ ERROR type arguments are not allowed on builtin type +let _x: u32<isize>; //~ ERROR type arguments are not allowed on builtin type +let _x: u64<isize>; //~ ERROR type arguments are not allowed on builtin type +let _x: char<isize>; //~ ERROR type arguments are not allowed on builtin type + +let _x: isize<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i8<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i16<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i32<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i64<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: usize<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u8<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u16<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u32<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u64<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: char<'static>; //~ ERROR lifetime arguments are not allowed on builtin type + +} diff --git a/src/test/ui/typeck/prim-with-args.stderr b/src/test/ui/typeck/prim-with-args.stderr new file mode 100644 index 000000000..2ddad5ad7 --- /dev/null +++ b/src/test/ui/typeck/prim-with-args.stderr @@ -0,0 +1,311 @@ +error[E0109]: type arguments are not allowed on builtin type `isize` + --> $DIR/prim-with-args.rs:4:15 + | +LL | let _x: isize<isize>; + | ----- ^^^^^ type argument not allowed + | | + | not allowed on builtin type `isize` + | +help: primitive type `isize` doesn't have generic parameters + | +LL - let _x: isize<isize>; +LL + let _x: isize; + | + +error[E0109]: type arguments are not allowed on builtin type `i8` + --> $DIR/prim-with-args.rs:5:12 + | +LL | let _x: i8<isize>; + | -- ^^^^^ type argument not allowed + | | + | not allowed on builtin type `i8` + | +help: primitive type `i8` doesn't have generic parameters + | +LL - let _x: i8<isize>; +LL + let _x: i8; + | + +error[E0109]: type arguments are not allowed on builtin type `i16` + --> $DIR/prim-with-args.rs:6:13 + | +LL | let _x: i16<isize>; + | --- ^^^^^ type argument not allowed + | | + | not allowed on builtin type `i16` + | +help: primitive type `i16` doesn't have generic parameters + | +LL - let _x: i16<isize>; +LL + let _x: i16; + | + +error[E0109]: type arguments are not allowed on builtin type `i32` + --> $DIR/prim-with-args.rs:7:13 + | +LL | let _x: i32<isize>; + | --- ^^^^^ type argument not allowed + | | + | not allowed on builtin type `i32` + | +help: primitive type `i32` doesn't have generic parameters + | +LL - let _x: i32<isize>; +LL + let _x: i32; + | + +error[E0109]: type arguments are not allowed on builtin type `i64` + --> $DIR/prim-with-args.rs:8:13 + | +LL | let _x: i64<isize>; + | --- ^^^^^ type argument not allowed + | | + | not allowed on builtin type `i64` + | +help: primitive type `i64` doesn't have generic parameters + | +LL - let _x: i64<isize>; +LL + let _x: i64; + | + +error[E0109]: type arguments are not allowed on builtin type `usize` + --> $DIR/prim-with-args.rs:9:15 + | +LL | let _x: usize<isize>; + | ----- ^^^^^ type argument not allowed + | | + | not allowed on builtin type `usize` + | +help: primitive type `usize` doesn't have generic parameters + | +LL - let _x: usize<isize>; +LL + let _x: usize; + | + +error[E0109]: type arguments are not allowed on builtin type `u8` + --> $DIR/prim-with-args.rs:10:12 + | +LL | let _x: u8<isize>; + | -- ^^^^^ type argument not allowed + | | + | not allowed on builtin type `u8` + | +help: primitive type `u8` doesn't have generic parameters + | +LL - let _x: u8<isize>; +LL + let _x: u8; + | + +error[E0109]: type arguments are not allowed on builtin type `u16` + --> $DIR/prim-with-args.rs:11:13 + | +LL | let _x: u16<isize>; + | --- ^^^^^ type argument not allowed + | | + | not allowed on builtin type `u16` + | +help: primitive type `u16` doesn't have generic parameters + | +LL - let _x: u16<isize>; +LL + let _x: u16; + | + +error[E0109]: type arguments are not allowed on builtin type `u32` + --> $DIR/prim-with-args.rs:12:13 + | +LL | let _x: u32<isize>; + | --- ^^^^^ type argument not allowed + | | + | not allowed on builtin type `u32` + | +help: primitive type `u32` doesn't have generic parameters + | +LL - let _x: u32<isize>; +LL + let _x: u32; + | + +error[E0109]: type arguments are not allowed on builtin type `u64` + --> $DIR/prim-with-args.rs:13:13 + | +LL | let _x: u64<isize>; + | --- ^^^^^ type argument not allowed + | | + | not allowed on builtin type `u64` + | +help: primitive type `u64` doesn't have generic parameters + | +LL - let _x: u64<isize>; +LL + let _x: u64; + | + +error[E0109]: type arguments are not allowed on builtin type `char` + --> $DIR/prim-with-args.rs:14:14 + | +LL | let _x: char<isize>; + | ---- ^^^^^ type argument not allowed + | | + | not allowed on builtin type `char` + | +help: primitive type `char` doesn't have generic parameters + | +LL - let _x: char<isize>; +LL + let _x: char; + | + +error[E0109]: lifetime arguments are not allowed on builtin type `isize` + --> $DIR/prim-with-args.rs:16:15 + | +LL | let _x: isize<'static>; + | ----- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on builtin type `isize` + | +help: primitive type `isize` doesn't have generic parameters + | +LL - let _x: isize<'static>; +LL + let _x: isize; + | + +error[E0109]: lifetime arguments are not allowed on builtin type `i8` + --> $DIR/prim-with-args.rs:17:12 + | +LL | let _x: i8<'static>; + | -- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on builtin type `i8` + | +help: primitive type `i8` doesn't have generic parameters + | +LL - let _x: i8<'static>; +LL + let _x: i8; + | + +error[E0109]: lifetime arguments are not allowed on builtin type `i16` + --> $DIR/prim-with-args.rs:18:13 + | +LL | let _x: i16<'static>; + | --- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on builtin type `i16` + | +help: primitive type `i16` doesn't have generic parameters + | +LL - let _x: i16<'static>; +LL + let _x: i16; + | + +error[E0109]: lifetime arguments are not allowed on builtin type `i32` + --> $DIR/prim-with-args.rs:19:13 + | +LL | let _x: i32<'static>; + | --- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on builtin type `i32` + | +help: primitive type `i32` doesn't have generic parameters + | +LL - let _x: i32<'static>; +LL + let _x: i32; + | + +error[E0109]: lifetime arguments are not allowed on builtin type `i64` + --> $DIR/prim-with-args.rs:20:13 + | +LL | let _x: i64<'static>; + | --- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on builtin type `i64` + | +help: primitive type `i64` doesn't have generic parameters + | +LL - let _x: i64<'static>; +LL + let _x: i64; + | + +error[E0109]: lifetime arguments are not allowed on builtin type `usize` + --> $DIR/prim-with-args.rs:21:15 + | +LL | let _x: usize<'static>; + | ----- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on builtin type `usize` + | +help: primitive type `usize` doesn't have generic parameters + | +LL - let _x: usize<'static>; +LL + let _x: usize; + | + +error[E0109]: lifetime arguments are not allowed on builtin type `u8` + --> $DIR/prim-with-args.rs:22:12 + | +LL | let _x: u8<'static>; + | -- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on builtin type `u8` + | +help: primitive type `u8` doesn't have generic parameters + | +LL - let _x: u8<'static>; +LL + let _x: u8; + | + +error[E0109]: lifetime arguments are not allowed on builtin type `u16` + --> $DIR/prim-with-args.rs:23:13 + | +LL | let _x: u16<'static>; + | --- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on builtin type `u16` + | +help: primitive type `u16` doesn't have generic parameters + | +LL - let _x: u16<'static>; +LL + let _x: u16; + | + +error[E0109]: lifetime arguments are not allowed on builtin type `u32` + --> $DIR/prim-with-args.rs:24:13 + | +LL | let _x: u32<'static>; + | --- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on builtin type `u32` + | +help: primitive type `u32` doesn't have generic parameters + | +LL - let _x: u32<'static>; +LL + let _x: u32; + | + +error[E0109]: lifetime arguments are not allowed on builtin type `u64` + --> $DIR/prim-with-args.rs:25:13 + | +LL | let _x: u64<'static>; + | --- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on builtin type `u64` + | +help: primitive type `u64` doesn't have generic parameters + | +LL - let _x: u64<'static>; +LL + let _x: u64; + | + +error[E0109]: lifetime arguments are not allowed on builtin type `char` + --> $DIR/prim-with-args.rs:26:14 + | +LL | let _x: char<'static>; + | ---- ^^^^^^^ lifetime argument not allowed + | | + | not allowed on builtin type `char` + | +help: primitive type `char` doesn't have generic parameters + | +LL - let _x: char<'static>; +LL + let _x: char; + | + +error: aborting due to 22 previous errors + +For more information about this error, try `rustc --explain E0109`. diff --git a/src/test/ui/typeck/project-cache-issue-37154.rs b/src/test/ui/typeck/project-cache-issue-37154.rs new file mode 100644 index 000000000..b10239c22 --- /dev/null +++ b/src/test/ui/typeck/project-cache-issue-37154.rs @@ -0,0 +1,21 @@ +// run-pass + +#![allow(dead_code)] +// Regression test for #37154: the problem here was that the cache +// results in a false error because it was caching placeholder results +// even after those placeholder regions had been popped. + +trait Foo { + fn method(&self) {} +} + +struct Wrapper<T>(T); + +impl<T> Foo for Wrapper<T> where for<'a> &'a T: IntoIterator<Item=&'a ()> {} + +fn f(x: Wrapper<Vec<()>>) { + x.method(); // This works. + x.method(); // error: no method named `method` +} + +fn main() { } diff --git a/src/test/ui/typeck/remove-extra-argument.fixed b/src/test/ui/typeck/remove-extra-argument.fixed new file mode 100644 index 000000000..a9338c76c --- /dev/null +++ b/src/test/ui/typeck/remove-extra-argument.fixed @@ -0,0 +1,9 @@ +// run-rustfix +// Check that the HELP suggestion is `l(vec![])` instead of `l($crate::vec::Vec::new())` +fn l(_a: Vec<u8>) {} + +fn main() { + l(vec![]) + //~^ ERROR this function takes 1 argument but 2 arguments were supplied + //~| HELP remove the extra argument +} diff --git a/src/test/ui/typeck/remove-extra-argument.rs b/src/test/ui/typeck/remove-extra-argument.rs new file mode 100644 index 000000000..659cb8b26 --- /dev/null +++ b/src/test/ui/typeck/remove-extra-argument.rs @@ -0,0 +1,9 @@ +// run-rustfix +// Check that the HELP suggestion is `l(vec![])` instead of `l($crate::vec::Vec::new())` +fn l(_a: Vec<u8>) {} + +fn main() { + l(vec![], vec![]) + //~^ ERROR this function takes 1 argument but 2 arguments were supplied + //~| HELP remove the extra argument +} diff --git a/src/test/ui/typeck/remove-extra-argument.stderr b/src/test/ui/typeck/remove-extra-argument.stderr new file mode 100644 index 000000000..703032a83 --- /dev/null +++ b/src/test/ui/typeck/remove-extra-argument.stderr @@ -0,0 +1,19 @@ +error[E0061]: this function takes 1 argument but 2 arguments were supplied + --> $DIR/remove-extra-argument.rs:6:5 + | +LL | l(vec![], vec![]) + | ^ ------ argument of type `Vec<_>` unexpected + | +note: function defined here + --> $DIR/remove-extra-argument.rs:3:4 + | +LL | fn l(_a: Vec<u8>) {} + | ^ ----------- +help: remove the extra argument + | +LL | l(vec![]) + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/typeck/return_type_containing_closure.rs b/src/test/ui/typeck/return_type_containing_closure.rs new file mode 100644 index 000000000..29624e08a --- /dev/null +++ b/src/test/ui/typeck/return_type_containing_closure.rs @@ -0,0 +1,10 @@ +#[allow(unused)] +fn foo() { //~ HELP a return type might be missing here + vec!['a'].iter().map(|c| c) + //~^ ERROR mismatched types [E0308] + //~| NOTE expected `()`, found struct `Map` + //~| NOTE expected unit type `()` + //~| HELP consider using a semicolon here +} + +fn main() {} diff --git a/src/test/ui/typeck/return_type_containing_closure.stderr b/src/test/ui/typeck/return_type_containing_closure.stderr new file mode 100644 index 000000000..101aee395 --- /dev/null +++ b/src/test/ui/typeck/return_type_containing_closure.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/return_type_containing_closure.rs:3:5 + | +LL | vec!['a'].iter().map(|c| c) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Map` + | + = note: expected unit type `()` + found struct `Map<std::slice::Iter<'_, char>, [closure@$DIR/return_type_containing_closure.rs:3:26: 3:29]>` +help: consider using a semicolon here + | +LL | vec!['a'].iter().map(|c| c); + | + +help: a return type might be missing here + | +LL | fn foo() -> _ { + | ++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/struct-enum-wrong-args.rs b/src/test/ui/typeck/struct-enum-wrong-args.rs new file mode 100644 index 000000000..19de4d677 --- /dev/null +++ b/src/test/ui/typeck/struct-enum-wrong-args.rs @@ -0,0 +1,14 @@ +// Regression test of #86481. +struct Wrapper(i32); +struct DoubleWrapper(i32, i32); + +fn main() { + let _ = Some(3, 2); //~ ERROR this enum variant takes + let _ = Ok(3, 6, 2); //~ ERROR this enum variant takes + let _ = Ok(); //~ ERROR this enum variant takes + let _ = Wrapper(); //~ ERROR this struct takes + let _ = Wrapper(5, 2); //~ ERROR this struct takes + let _ = DoubleWrapper(); //~ ERROR this struct takes + let _ = DoubleWrapper(5); //~ ERROR this struct takes + let _ = DoubleWrapper(5, 2, 7); //~ ERROR this struct takes +} diff --git a/src/test/ui/typeck/struct-enum-wrong-args.stderr b/src/test/ui/typeck/struct-enum-wrong-args.stderr new file mode 100644 index 000000000..f72082d53 --- /dev/null +++ b/src/test/ui/typeck/struct-enum-wrong-args.stderr @@ -0,0 +1,133 @@ +error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied + --> $DIR/struct-enum-wrong-args.rs:6:13 + | +LL | let _ = Some(3, 2); + | ^^^^ - argument of type `{integer}` unexpected + | +note: tuple variant defined here + --> $SRC_DIR/core/src/option.rs:LL:COL + | +LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T), + | ^^^^ +help: remove the extra argument + | +LL | let _ = Some(3); + | ~~~~~~~ + +error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied + --> $DIR/struct-enum-wrong-args.rs:7:13 + | +LL | let _ = Ok(3, 6, 2); + | ^^ - - argument of type `{integer}` unexpected + | | + | argument of type `{integer}` unexpected + | +note: tuple variant defined here + --> $SRC_DIR/core/src/result.rs:LL:COL + | +LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), + | ^^ +help: remove the extra arguments + | +LL | let _ = Ok(3); + | ~~~~~ + +error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied + --> $DIR/struct-enum-wrong-args.rs:8:13 + | +LL | let _ = Ok(); + | ^^-- an argument is missing + | +note: tuple variant defined here + --> $SRC_DIR/core/src/result.rs:LL:COL + | +LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T), + | ^^ +help: provide the argument + | +LL | let _ = Ok(/* value */); + | ~~~~~~~~~~~~~~~ + +error[E0061]: this struct takes 1 argument but 0 arguments were supplied + --> $DIR/struct-enum-wrong-args.rs:9:13 + | +LL | let _ = Wrapper(); + | ^^^^^^^-- an argument of type `i32` is missing + | +note: tuple struct defined here + --> $DIR/struct-enum-wrong-args.rs:2:8 + | +LL | struct Wrapper(i32); + | ^^^^^^^ +help: provide the argument + | +LL | let _ = Wrapper(/* i32 */); + | ~~~~~~~~~~~~~~~~~~ + +error[E0061]: this struct takes 1 argument but 2 arguments were supplied + --> $DIR/struct-enum-wrong-args.rs:10:13 + | +LL | let _ = Wrapper(5, 2); + | ^^^^^^^ - argument of type `{integer}` unexpected + | +note: tuple struct defined here + --> $DIR/struct-enum-wrong-args.rs:2:8 + | +LL | struct Wrapper(i32); + | ^^^^^^^ +help: remove the extra argument + | +LL | let _ = Wrapper(5); + | ~~~~~~~~~~ + +error[E0061]: this struct takes 2 arguments but 0 arguments were supplied + --> $DIR/struct-enum-wrong-args.rs:11:13 + | +LL | let _ = DoubleWrapper(); + | ^^^^^^^^^^^^^-- two arguments of type `i32` and `i32` are missing + | +note: tuple struct defined here + --> $DIR/struct-enum-wrong-args.rs:3:8 + | +LL | struct DoubleWrapper(i32, i32); + | ^^^^^^^^^^^^^ +help: provide the arguments + | +LL | let _ = DoubleWrapper(/* i32 */, /* i32 */); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this struct takes 2 arguments but 1 argument was supplied + --> $DIR/struct-enum-wrong-args.rs:12:13 + | +LL | let _ = DoubleWrapper(5); + | ^^^^^^^^^^^^^--- an argument of type `i32` is missing + | +note: tuple struct defined here + --> $DIR/struct-enum-wrong-args.rs:3:8 + | +LL | struct DoubleWrapper(i32, i32); + | ^^^^^^^^^^^^^ +help: provide the argument + | +LL | let _ = DoubleWrapper(5, /* i32 */); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this struct takes 2 arguments but 3 arguments were supplied + --> $DIR/struct-enum-wrong-args.rs:13:13 + | +LL | let _ = DoubleWrapper(5, 2, 7); + | ^^^^^^^^^^^^^ - argument of type `{integer}` unexpected + | +note: tuple struct defined here + --> $DIR/struct-enum-wrong-args.rs:3:8 + | +LL | struct DoubleWrapper(i32, i32); + | ^^^^^^^^^^^^^ +help: remove the extra argument + | +LL | let _ = DoubleWrapper(5, 2); + | ~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.fixed b/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.fixed new file mode 100644 index 000000000..ba83e7900 --- /dev/null +++ b/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.fixed @@ -0,0 +1,11 @@ +// run-rustfix + +fn main() { + 2.0e1; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields + 2.0E1; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields + 2.0f32; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields + 2.0f64; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields + 2.0e+12; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields + 2.0e-12; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields + 2.0e1f32; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields +} diff --git a/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.rs b/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.rs new file mode 100644 index 000000000..c102447f6 --- /dev/null +++ b/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.rs @@ -0,0 +1,11 @@ +// run-rustfix + +fn main() { + 2.e1; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields + 2.E1; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields + 2.f32; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields + 2.f64; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields + 2.e+12; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields + 2.e-12; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields + 2.e1f32; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields +} diff --git a/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.stderr b/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.stderr new file mode 100644 index 000000000..e8e069708 --- /dev/null +++ b/src/test/ui/typeck/suggest-adding-missing-zero-to-floating-point-number.stderr @@ -0,0 +1,80 @@ +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:4:7 + | +LL | 2.e1; + | ^^ + | +help: If the number is meant to be a floating point number, consider adding a `0` after the period + | +LL | 2.0e1; + | + + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:5:7 + | +LL | 2.E1; + | ^^ + | +help: If the number is meant to be a floating point number, consider adding a `0` after the period + | +LL | 2.0E1; + | + + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:6:7 + | +LL | 2.f32; + | ^^^ + | +help: If the number is meant to be a floating point number, consider adding a `0` after the period + | +LL | 2.0f32; + | + + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:7:7 + | +LL | 2.f64; + | ^^^ + | +help: If the number is meant to be a floating point number, consider adding a `0` after the period + | +LL | 2.0f64; + | + + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:8:7 + | +LL | 2.e+12; + | ^ + | +help: If the number is meant to be a floating point number, consider adding a `0` after the period + | +LL | 2.0e+12; + | + + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:9:7 + | +LL | 2.e-12; + | ^ + | +help: If the number is meant to be a floating point number, consider adding a `0` after the period + | +LL | 2.0e-12; + | + + +error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields + --> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:10:7 + | +LL | 2.e1f32; + | ^^^^^ + | +help: If the number is meant to be a floating point number, consider adding a `0` after the period + | +LL | 2.0e1f32; + | + + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0610`. diff --git a/src/test/ui/typeck/type-placeholder-fn-in-const.rs b/src/test/ui/typeck/type-placeholder-fn-in-const.rs new file mode 100644 index 000000000..ab2e2d8c5 --- /dev/null +++ b/src/test/ui/typeck/type-placeholder-fn-in-const.rs @@ -0,0 +1,14 @@ +struct MyStruct; + +trait Test { + const TEST: fn() -> _; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: the placeholder `_` is not allowed within types on item signatures for constants [E0121] +} + +impl Test for MyStruct { + const TEST: fn() -> _ = 42; + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121] +} + +fn main() {} diff --git a/src/test/ui/typeck/type-placeholder-fn-in-const.stderr b/src/test/ui/typeck/type-placeholder-fn-in-const.stderr new file mode 100644 index 000000000..e7b2e554a --- /dev/null +++ b/src/test/ui/typeck/type-placeholder-fn-in-const.stderr @@ -0,0 +1,21 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/type-placeholder-fn-in-const.rs:4:25 + | +LL | const TEST: fn() -> _; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/type-placeholder-fn-in-const.rs:4:25 + | +LL | const TEST: fn() -> _; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/type-placeholder-fn-in-const.rs:10:25 + | +LL | const TEST: fn() -> _ = 42; + | ^ not allowed in type signatures + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/typeck/typeck-builtin-bound-type-parameters.rs b/src/test/ui/typeck/typeck-builtin-bound-type-parameters.rs new file mode 100644 index 000000000..c463a8ad0 --- /dev/null +++ b/src/test/ui/typeck/typeck-builtin-bound-type-parameters.rs @@ -0,0 +1,17 @@ +fn foo1<T:Copy<U>, U>(x: T) {} +//~^ ERROR this trait takes 0 generic arguments but 1 generic argument was supplied + +trait Trait: Copy<dyn Send> {} +//~^ ERROR this trait takes 0 generic arguments but 1 generic argument was supplied + +struct MyStruct1<T: Copy<T>>; +//~^ ERROR this trait takes 0 generic arguments but 1 generic argument was supplied + +struct MyStruct2<'a, T: Copy<'a>>; +//~^ ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied + +fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} +//~^ ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied +//~| ERROR this trait takes 0 generic arguments but 1 generic argument was supplied + +fn main() { } diff --git a/src/test/ui/typeck/typeck-builtin-bound-type-parameters.stderr b/src/test/ui/typeck/typeck-builtin-bound-type-parameters.stderr new file mode 100644 index 000000000..bf74dd7de --- /dev/null +++ b/src/test/ui/typeck/typeck-builtin-bound-type-parameters.stderr @@ -0,0 +1,87 @@ +error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/typeck-builtin-bound-type-parameters.rs:1:11 + | +LL | fn foo1<T:Copy<U>, U>(x: T) {} + | ^^^^--- help: remove these generics + | | + | expected 0 generic arguments + | +note: trait defined here, with 0 generic parameters + --> $SRC_DIR/core/src/marker.rs:LL:COL + | +LL | pub trait Copy: Clone { + | ^^^^ + +error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/typeck-builtin-bound-type-parameters.rs:4:14 + | +LL | trait Trait: Copy<dyn Send> {} + | ^^^^---------- help: remove these generics + | | + | expected 0 generic arguments + | +note: trait defined here, with 0 generic parameters + --> $SRC_DIR/core/src/marker.rs:LL:COL + | +LL | pub trait Copy: Clone { + | ^^^^ + +error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/typeck-builtin-bound-type-parameters.rs:7:21 + | +LL | struct MyStruct1<T: Copy<T>>; + | ^^^^--- help: remove these generics + | | + | expected 0 generic arguments + | +note: trait defined here, with 0 generic parameters + --> $SRC_DIR/core/src/marker.rs:LL:COL + | +LL | pub trait Copy: Clone { + | ^^^^ + +error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/typeck-builtin-bound-type-parameters.rs:10:25 + | +LL | struct MyStruct2<'a, T: Copy<'a>>; + | ^^^^---- help: remove these generics + | | + | expected 0 lifetime arguments + | +note: trait defined here, with 0 lifetime parameters + --> $SRC_DIR/core/src/marker.rs:LL:COL + | +LL | pub trait Copy: Clone { + | ^^^^ + +error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/typeck-builtin-bound-type-parameters.rs:13:15 + | +LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} + | ^^^^ -- help: remove this lifetime argument + | | + | expected 0 lifetime arguments + | +note: trait defined here, with 0 lifetime parameters + --> $SRC_DIR/core/src/marker.rs:LL:COL + | +LL | pub trait Copy: Clone { + | ^^^^ + +error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/typeck-builtin-bound-type-parameters.rs:13:15 + | +LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} + | ^^^^ - help: remove this generic argument + | | + | expected 0 generic arguments + | +note: trait defined here, with 0 generic parameters + --> $SRC_DIR/core/src/marker.rs:LL:COL + | +LL | pub trait Copy: Clone { + | ^^^^ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/typeck/typeck-cast-pointer-to-float.rs b/src/test/ui/typeck/typeck-cast-pointer-to-float.rs new file mode 100644 index 000000000..2af7a3cf2 --- /dev/null +++ b/src/test/ui/typeck/typeck-cast-pointer-to-float.rs @@ -0,0 +1,5 @@ +fn main() { + let x : i16 = 22; + ((&x) as *const i16) as f32; + //~^ ERROR casting `*const i16` as `f32` is invalid +} diff --git a/src/test/ui/typeck/typeck-cast-pointer-to-float.stderr b/src/test/ui/typeck/typeck-cast-pointer-to-float.stderr new file mode 100644 index 000000000..81d968454 --- /dev/null +++ b/src/test/ui/typeck/typeck-cast-pointer-to-float.stderr @@ -0,0 +1,9 @@ +error[E0606]: casting `*const i16` as `f32` is invalid + --> $DIR/typeck-cast-pointer-to-float.rs:3:5 + | +LL | ((&x) as *const i16) as f32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0606`. diff --git a/src/test/ui/typeck/typeck-closure-to-unsafe-fn-ptr.rs b/src/test/ui/typeck/typeck-closure-to-unsafe-fn-ptr.rs new file mode 100644 index 000000000..2530a1e96 --- /dev/null +++ b/src/test/ui/typeck/typeck-closure-to-unsafe-fn-ptr.rs @@ -0,0 +1,9 @@ +// run-pass + +unsafe fn call_unsafe(func: unsafe fn() -> ()) -> () { + func() +} + +pub fn main() { + unsafe { call_unsafe(|| {}); } +} diff --git a/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.fixed b/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.fixed new file mode 100644 index 000000000..a9107f998 --- /dev/null +++ b/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.fixed @@ -0,0 +1,17 @@ +// run-rustfix +// Test that we do not consider associated types to be sendable without +// some applicable trait bound (and we don't ICE). +#![allow(dead_code)] + +trait Trait { + type AssocType; + fn dummy(&self) { } +} +fn bar<T:Trait+Send>() where <T as Trait>::AssocType: Send { + is_send::<T::AssocType>(); //~ ERROR E0277 +} + +fn is_send<T:Send>() { +} + +fn main() { } diff --git a/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.rs b/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.rs new file mode 100644 index 000000000..bafc16577 --- /dev/null +++ b/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.rs @@ -0,0 +1,17 @@ +// run-rustfix +// Test that we do not consider associated types to be sendable without +// some applicable trait bound (and we don't ICE). +#![allow(dead_code)] + +trait Trait { + type AssocType; + fn dummy(&self) { } +} +fn bar<T:Trait+Send>() { + is_send::<T::AssocType>(); //~ ERROR E0277 +} + +fn is_send<T:Send>() { +} + +fn main() { } diff --git a/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.stderr b/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.stderr new file mode 100644 index 000000000..468a14762 --- /dev/null +++ b/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.stderr @@ -0,0 +1,20 @@ +error[E0277]: `<T as Trait>::AssocType` cannot be sent between threads safely + --> $DIR/typeck-default-trait-impl-assoc-type.rs:11:15 + | +LL | is_send::<T::AssocType>(); + | ^^^^^^^^^^^^ `<T as Trait>::AssocType` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `<T as Trait>::AssocType` +note: required by a bound in `is_send` + --> $DIR/typeck-default-trait-impl-assoc-type.rs:14:14 + | +LL | fn is_send<T:Send>() { + | ^^^^ required by this bound in `is_send` +help: consider further restricting the associated type + | +LL | fn bar<T:Trait+Send>() where <T as Trait>::AssocType: Send { + | +++++++++++++++++++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs b/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs new file mode 100644 index 000000000..cc75cd490 --- /dev/null +++ b/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs @@ -0,0 +1,25 @@ +// aux-build:tdticc_coherence_lib.rs +#![allow(suspicious_auto_trait_impls)] + +// Test that we do not consider associated types to be sendable without +// some applicable trait bound (and we don't ICE). + +#![feature(negative_impls)] + +extern crate tdticc_coherence_lib as lib; + +use lib::DefaultedTrait; + +struct A; +impl DefaultedTrait for (A,) { } //~ ERROR E0117 + +struct B; +impl !DefaultedTrait for (B,) { } //~ ERROR E0117 + +struct C; +struct D<T>(T); +impl DefaultedTrait for Box<C> { } //~ ERROR E0321 +impl DefaultedTrait for lib::Something<C> { } //~ ERROR E0117 +impl DefaultedTrait for D<C> { } // OK + +fn main() { } diff --git a/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr b/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr new file mode 100644 index 000000000..fc3778b79 --- /dev/null +++ b/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr @@ -0,0 +1,43 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:14:1 + | +LL | impl DefaultedTrait for (A,) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^---- + | | | + | | this is not defined in the current crate because tuples are always foreign + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:17:1 + | +LL | impl !DefaultedTrait for (B,) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^---- + | | | + | | this is not defined in the current crate because tuples are always foreign + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0321]: cross-crate traits with a default impl, like `DefaultedTrait`, can only be implemented for a struct/enum type defined in the current crate + --> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:21:1 + | +LL | impl DefaultedTrait for Box<C> { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait for type in another crate + +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate + --> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:22:1 + | +LL | impl DefaultedTrait for lib::Something<C> { } + | ^^^^^^^^^^^^^^^^^^^^^^^^----------------- + | | | + | | `Something` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0117, E0321. +For more information about an error, try `rustc --explain E0117`. diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation-send.rs b/src/test/ui/typeck/typeck-default-trait-impl-negation-send.rs new file mode 100644 index 000000000..3a2fc39d4 --- /dev/null +++ b/src/test/ui/typeck/typeck-default-trait-impl-negation-send.rs @@ -0,0 +1,21 @@ +#![feature(negative_impls)] + +struct MySendable { + t: *mut u8 +} + +unsafe impl Send for MySendable {} + +struct MyNotSendable { + t: *mut u8 +} + +impl !Send for MyNotSendable {} + +fn is_send<T: Send>() {} + +fn main() { + is_send::<MySendable>(); + is_send::<MyNotSendable>(); + //~^ ERROR `MyNotSendable` cannot be sent between threads safely +} diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation-send.stderr b/src/test/ui/typeck/typeck-default-trait-impl-negation-send.stderr new file mode 100644 index 000000000..2ce32990e --- /dev/null +++ b/src/test/ui/typeck/typeck-default-trait-impl-negation-send.stderr @@ -0,0 +1,16 @@ +error[E0277]: `MyNotSendable` cannot be sent between threads safely + --> $DIR/typeck-default-trait-impl-negation-send.rs:19:15 + | +LL | is_send::<MyNotSendable>(); + | ^^^^^^^^^^^^^ `MyNotSendable` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `MyNotSendable` +note: required by a bound in `is_send` + --> $DIR/typeck-default-trait-impl-negation-send.rs:15:15 + | +LL | fn is_send<T: Send>() {} + | ^^^^ required by this bound in `is_send` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.rs b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.rs new file mode 100644 index 000000000..b9042188a --- /dev/null +++ b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.rs @@ -0,0 +1,41 @@ +#![feature(negative_impls)] + +struct Managed; +impl !Send for Managed {} +impl !Sync for Managed {} + +use std::cell::UnsafeCell; + +struct MySync { + t: *mut u8 +} + +unsafe impl Sync for MySync {} + +struct MyNotSync { + t: *mut u8 +} + +impl !Sync for MyNotSync {} + +struct MyTypeWUnsafe { + t: UnsafeCell<u8> +} + +struct MyTypeManaged { + t: Managed +} + +fn is_sync<T: Sync>() {} + +fn main() { + is_sync::<MySync>(); + is_sync::<MyNotSync>(); + //~^ ERROR `MyNotSync` cannot be shared between threads safely [E0277] + + is_sync::<MyTypeWUnsafe>(); + //~^ ERROR `UnsafeCell<u8>` cannot be shared between threads safely [E0277] + + is_sync::<MyTypeManaged>(); + //~^ ERROR `Managed` cannot be shared between threads safely [E0277] +} diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr new file mode 100644 index 000000000..6bb5e1f54 --- /dev/null +++ b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr @@ -0,0 +1,52 @@ +error[E0277]: `MyNotSync` cannot be shared between threads safely + --> $DIR/typeck-default-trait-impl-negation-sync.rs:33:15 + | +LL | is_sync::<MyNotSync>(); + | ^^^^^^^^^ `MyNotSync` cannot be shared between threads safely + | + = help: the trait `Sync` is not implemented for `MyNotSync` +note: required by a bound in `is_sync` + --> $DIR/typeck-default-trait-impl-negation-sync.rs:29:15 + | +LL | fn is_sync<T: Sync>() {} + | ^^^^ required by this bound in `is_sync` + +error[E0277]: `UnsafeCell<u8>` cannot be shared between threads safely + --> $DIR/typeck-default-trait-impl-negation-sync.rs:36:5 + | +LL | is_sync::<MyTypeWUnsafe>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<u8>` cannot be shared between threads safely + | + = help: within `MyTypeWUnsafe`, the trait `Sync` is not implemented for `UnsafeCell<u8>` +note: required because it appears within the type `MyTypeWUnsafe` + --> $DIR/typeck-default-trait-impl-negation-sync.rs:21:8 + | +LL | struct MyTypeWUnsafe { + | ^^^^^^^^^^^^^ +note: required by a bound in `is_sync` + --> $DIR/typeck-default-trait-impl-negation-sync.rs:29:15 + | +LL | fn is_sync<T: Sync>() {} + | ^^^^ required by this bound in `is_sync` + +error[E0277]: `Managed` cannot be shared between threads safely + --> $DIR/typeck-default-trait-impl-negation-sync.rs:39:5 + | +LL | is_sync::<MyTypeManaged>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ `Managed` cannot be shared between threads safely + | + = help: within `MyTypeManaged`, the trait `Sync` is not implemented for `Managed` +note: required because it appears within the type `MyTypeManaged` + --> $DIR/typeck-default-trait-impl-negation-sync.rs:25:8 + | +LL | struct MyTypeManaged { + | ^^^^^^^^^^^^^ +note: required by a bound in `is_sync` + --> $DIR/typeck-default-trait-impl-negation-sync.rs:29:15 + | +LL | fn is_sync<T: Sync>() {} + | ^^^^ required by this bound in `is_sync` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/typeck/typeck-default-trait-impl-send-param.rs b/src/test/ui/typeck/typeck-default-trait-impl-send-param.rs new file mode 100644 index 000000000..7948cd101 --- /dev/null +++ b/src/test/ui/typeck/typeck-default-trait-impl-send-param.rs @@ -0,0 +1,11 @@ +// Test that we do not consider parameter types to be sendable without +// an explicit trait bound. + +fn foo<T>() { + is_send::<T>() //~ ERROR E0277 +} + +fn is_send<T:Send>() { +} + +fn main() { } diff --git a/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr b/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr new file mode 100644 index 000000000..887a1ddbb --- /dev/null +++ b/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr @@ -0,0 +1,19 @@ +error[E0277]: `T` cannot be sent between threads safely + --> $DIR/typeck-default-trait-impl-send-param.rs:5:15 + | +LL | is_send::<T>() + | ^ `T` cannot be sent between threads safely + | +note: required by a bound in `is_send` + --> $DIR/typeck-default-trait-impl-send-param.rs:8:14 + | +LL | fn is_send<T:Send>() { + | ^^^^ required by this bound in `is_send` +help: consider restricting type parameter `T` + | +LL | fn foo<T: std::marker::Send>() { + | +++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/typeck/typeck-fn-to-unsafe-fn-ptr.rs b/src/test/ui/typeck/typeck-fn-to-unsafe-fn-ptr.rs new file mode 100644 index 000000000..1e954f569 --- /dev/null +++ b/src/test/ui/typeck/typeck-fn-to-unsafe-fn-ptr.rs @@ -0,0 +1,12 @@ +// run-pass +// This tests reification from safe function to `unsafe fn` pointer + +fn do_nothing() -> () {} + +unsafe fn call_unsafe(func: unsafe fn() -> ()) -> () { + func() +} + +pub fn main() { + unsafe { call_unsafe(do_nothing); } +} diff --git a/src/test/ui/typeck/typeck-unsafe-always-share.rs b/src/test/ui/typeck/typeck-unsafe-always-share.rs new file mode 100644 index 000000000..be87ab172 --- /dev/null +++ b/src/test/ui/typeck/typeck-unsafe-always-share.rs @@ -0,0 +1,32 @@ +// Verify that UnsafeCell is *always* !Sync regardless if `T` is sync. + +#![feature(negative_impls)] + +use std::cell::UnsafeCell; +use std::marker::Sync; + +struct MySync<T> { + u: UnsafeCell<T> +} + +struct NoSync; +impl !Sync for NoSync {} + +fn test<T: Sync>(s: T) {} + +fn main() { + let us = UnsafeCell::new(MySync{u: UnsafeCell::new(0)}); + test(us); + //~^ ERROR `UnsafeCell<MySync<{integer}>>` cannot be shared between threads safely + + let uns = UnsafeCell::new(NoSync); + test(uns); + //~^ ERROR `UnsafeCell<NoSync>` cannot be shared between threads safely [E0277] + + let ms = MySync{u: uns}; + test(ms); + //~^ ERROR `UnsafeCell<NoSync>` cannot be shared between threads safely [E0277] + + test(NoSync); + //~^ ERROR `NoSync` cannot be shared between threads safely [E0277] +} diff --git a/src/test/ui/typeck/typeck-unsafe-always-share.stderr b/src/test/ui/typeck/typeck-unsafe-always-share.stderr new file mode 100644 index 000000000..154e50499 --- /dev/null +++ b/src/test/ui/typeck/typeck-unsafe-always-share.stderr @@ -0,0 +1,68 @@ +error[E0277]: `UnsafeCell<MySync<{integer}>>` cannot be shared between threads safely + --> $DIR/typeck-unsafe-always-share.rs:19:10 + | +LL | test(us); + | ---- ^^ `UnsafeCell<MySync<{integer}>>` cannot be shared between threads safely + | | + | required by a bound introduced by this call + | + = help: the trait `Sync` is not implemented for `UnsafeCell<MySync<{integer}>>` +note: required by a bound in `test` + --> $DIR/typeck-unsafe-always-share.rs:15:12 + | +LL | fn test<T: Sync>(s: T) {} + | ^^^^ required by this bound in `test` + +error[E0277]: `UnsafeCell<NoSync>` cannot be shared between threads safely + --> $DIR/typeck-unsafe-always-share.rs:23:10 + | +LL | test(uns); + | ---- ^^^ `UnsafeCell<NoSync>` cannot be shared between threads safely + | | + | required by a bound introduced by this call + | + = help: the trait `Sync` is not implemented for `UnsafeCell<NoSync>` +note: required by a bound in `test` + --> $DIR/typeck-unsafe-always-share.rs:15:12 + | +LL | fn test<T: Sync>(s: T) {} + | ^^^^ required by this bound in `test` + +error[E0277]: `UnsafeCell<NoSync>` cannot be shared between threads safely + --> $DIR/typeck-unsafe-always-share.rs:27:10 + | +LL | test(ms); + | ---- ^^ `UnsafeCell<NoSync>` cannot be shared between threads safely + | | + | required by a bound introduced by this call + | + = help: within `MySync<NoSync>`, the trait `Sync` is not implemented for `UnsafeCell<NoSync>` +note: required because it appears within the type `MySync<NoSync>` + --> $DIR/typeck-unsafe-always-share.rs:8:8 + | +LL | struct MySync<T> { + | ^^^^^^ +note: required by a bound in `test` + --> $DIR/typeck-unsafe-always-share.rs:15:12 + | +LL | fn test<T: Sync>(s: T) {} + | ^^^^ required by this bound in `test` + +error[E0277]: `NoSync` cannot be shared between threads safely + --> $DIR/typeck-unsafe-always-share.rs:30:10 + | +LL | test(NoSync); + | ---- ^^^^^^ `NoSync` cannot be shared between threads safely + | | + | required by a bound introduced by this call + | + = help: the trait `Sync` is not implemented for `NoSync` +note: required by a bound in `test` + --> $DIR/typeck-unsafe-always-share.rs:15:12 + | +LL | fn test<T: Sync>(s: T) {} + | ^^^^ required by this bound in `test` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/typeck/typeck_type_placeholder_1.rs b/src/test/ui/typeck/typeck_type_placeholder_1.rs new file mode 100644 index 000000000..ea7aa5285 --- /dev/null +++ b/src/test/ui/typeck/typeck_type_placeholder_1.rs @@ -0,0 +1,32 @@ +// run-pass + +#![allow(dead_code)] +// This test checks that the `_` type placeholder works +// correctly for enabling type inference. + + +struct TestStruct { + x: *const isize +} + +unsafe impl Sync for TestStruct {} + +static CONSTEXPR: TestStruct = TestStruct{ x: &413 }; + + +pub fn main() { + let x: Vec<_> = (0..5).collect(); + let expected: &[usize] = &[0,1,2,3,4]; + assert_eq!(x, expected); + + let x = (0..5).collect::<Vec<_>>(); + assert_eq!(x, expected); + + let y: _ = "hello"; + assert_eq!(y.len(), 5); + + let ptr: &usize = &5; + let ptr2 = ptr as *const _; + + assert_eq!(ptr as *const usize as usize, ptr2 as usize); +} diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs new file mode 100644 index 000000000..22fedb22d --- /dev/null +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -0,0 +1,222 @@ +// Needed for `type Y = impl Trait<_>` and `type B = _;` +#![feature(associated_type_defaults)] +#![feature(type_alias_impl_trait)] +// This test checks that it is not possible to enable global type +// inference by using the `_` type placeholder. + +fn test() -> _ { 5 } +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + +fn test2() -> (_, _) { (5, 5) } +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + +static TEST3: _ = "test"; +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables + +static TEST4: _ = 145; +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables + +static TEST5: (_, _) = (1, 2); +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables + +fn test6(_: _) { } +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + +fn test6_b<T>(_: _, _: T) { } +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + +fn test6_c<T, K, L, A, B>(_: _, _: (T, K, L, A, B)) { } +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + +fn test7(x: _) { let _x: usize = x; } +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + +fn test8(_f: fn() -> _) { } +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions +//~^^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + +struct Test9; + +impl Test9 { + fn test9(&self) -> _ { () } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + + fn test10(&self, _x : _) { } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions +} + +fn test11(x: &usize) -> &_ { +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + &x +} + +unsafe fn test12(x: *const usize) -> *const *const _ { +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + &x +} + +impl Clone for Test9 { + fn clone(&self) -> _ { Test9 } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + + fn clone_from(&mut self, other: _) { *self = Test9; } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions +} + +struct Test10 { + a: _, + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for structs + b: (_, _), +} + +pub fn main() { + static A = 42; + //~^ ERROR missing type for `static` item + static B: _ = 42; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables + static C: Option<_> = Some(42); + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables + fn fn_test() -> _ { 5 } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + + fn fn_test2() -> (_, _) { (5, 5) } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + + static FN_TEST3: _ = "test"; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables + + static FN_TEST4: _ = 145; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables + + static FN_TEST5: (_, _) = (1, 2); + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables + + fn fn_test6(_: _) { } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + + fn fn_test7(x: _) { let _x: usize = x; } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + + fn fn_test8(_f: fn() -> _) { } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + //~^^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + + struct FnTest9; + + impl FnTest9 { + fn fn_test9(&self) -> _ { () } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + + fn fn_test10(&self, _x : _) { } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + } + + impl Clone for FnTest9 { + fn clone(&self) -> _ { FnTest9 } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + + fn clone_from(&mut self, other: _) { *self = FnTest9; } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + } + + struct FnTest10 { + a: _, + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for structs + b: (_, _), + } + + fn fn_test11(_: _) -> (_, _) { panic!() } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~| ERROR type annotations needed + + fn fn_test12(x: i32) -> (_, _) { (x, x) } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + + fn fn_test13(x: _) -> (i32, _) { (x, x) } + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types +} + +trait T { + fn method_test1(&self, x: _); + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + fn method_test2(&self, x: _) -> _; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + fn method_test3(&self) -> _; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + fn assoc_fn_test1(x: _); + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + fn assoc_fn_test2(x: _) -> _; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + fn assoc_fn_test3() -> _; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions +} + +struct BadStruct<_>(_); +//~^ ERROR expected identifier, found reserved identifier `_` +//~| ERROR the placeholder `_` is not allowed within types on item signatures for structs +trait BadTrait<_> {} +//~^ ERROR expected identifier, found reserved identifier `_` +impl BadTrait<_> for BadStruct<_> {} +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for implementations + +fn impl_trait() -> impl BadTrait<_> { +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for opaque types + unimplemented!() +} + +struct BadStruct1<_, _>(_); +//~^ ERROR expected identifier, found reserved identifier `_` +//~| ERROR expected identifier, found reserved identifier `_` +//~| ERROR the name `_` is already used +//~| ERROR the placeholder `_` is not allowed within types on item signatures for structs +struct BadStruct2<_, T>(_, T); +//~^ ERROR expected identifier, found reserved identifier `_` +//~| ERROR the placeholder `_` is not allowed within types on item signatures for structs + +type X = Box<_>; +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for type aliases + +struct Struct; +trait Trait<T> {} +impl Trait<usize> for Struct {} +type Y = impl Trait<_>; +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for opaque types +fn foo() -> Y { + Struct +} + +trait Qux { + type A; + type B = _; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types + const C: _; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + const D: _ = 42; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + // type E: _; // FIXME: make the parser propagate the existence of `B` + type F: std::ops::Fn(_); + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types +} +impl Qux for Struct { + type A = _; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types + type B = _; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types + const C: _; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + //~| ERROR associated constant in `impl` without body + const D: _ = 42; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants +} + +fn map<T>(_: fn() -> Option<&'static T>) -> Option<T> { + None +} + +fn value() -> Option<&'static _> { +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + Option::<&'static u8>::None +} + +const _: Option<_> = map(value); +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr new file mode 100644 index 000000000..3ea317dfb --- /dev/null +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -0,0 +1,642 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/typeck_type_placeholder_item.rs:154:18 + | +LL | struct BadStruct<_>(_); + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/typeck_type_placeholder_item.rs:157:16 + | +LL | trait BadTrait<_> {} + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/typeck_type_placeholder_item.rs:167:19 + | +LL | struct BadStruct1<_, _>(_); + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/typeck_type_placeholder_item.rs:167:22 + | +LL | struct BadStruct1<_, _>(_); + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/typeck_type_placeholder_item.rs:172:19 + | +LL | struct BadStruct2<_, T>(_, T); + | ^ expected identifier, found reserved identifier + +error: associated constant in `impl` without body + --> $DIR/typeck_type_placeholder_item.rs:205:5 + | +LL | const C: _; + | ^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= <expr>;` + +error[E0403]: the name `_` is already used for a generic parameter in this item's generic parameters + --> $DIR/typeck_type_placeholder_item.rs:167:22 + | +LL | struct BadStruct1<_, _>(_); + | - ^ already used + | | + | first use of `_` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:7:14 + | +LL | fn test() -> _ { 5 } + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `i32` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:10:16 + | +LL | fn test2() -> (_, _) { (5, 5) } + | -^--^- + | || | + | || not allowed in type signatures + | |not allowed in type signatures + | help: replace with the correct return type: `(i32, i32)` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/typeck_type_placeholder_item.rs:13:15 + | +LL | static TEST3: _ = "test"; + | ^ + | | + | not allowed in type signatures + | help: replace with the correct type: `&str` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/typeck_type_placeholder_item.rs:16:15 + | +LL | static TEST4: _ = 145; + | ^ + | | + | not allowed in type signatures + | help: replace with the correct type: `i32` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/typeck_type_placeholder_item.rs:19:15 + | +LL | static TEST5: (_, _) = (1, 2); + | ^^^^^^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:22:13 + | +LL | fn test6(_: _) { } + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn test6<T>(_: T) { } + | +++ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:25:18 + | +LL | fn test6_b<T>(_: _, _: T) { } + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn test6_b<T, U>(_: U, _: T) { } + | +++ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:28:30 + | +LL | fn test6_c<T, K, L, A, B>(_: _, _: (T, K, L, A, B)) { } + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn test6_c<T, K, L, A, B, U>(_: U, _: (T, K, L, A, B)) { } + | +++ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:31:13 + | +LL | fn test7(x: _) { let _x: usize = x; } + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn test7<T>(x: T) { let _x: usize = x; } + | +++ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:34:22 + | +LL | fn test8(_f: fn() -> _) { } + | ^ + | | + | not allowed in type signatures + | help: use type parameters instead: `T` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:34:22 + | +LL | fn test8(_f: fn() -> _) { } + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn test8<T>(_f: fn() -> T) { } + | +++ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:48:26 + | +LL | fn test11(x: &usize) -> &_ { + | -^ + | || + | |not allowed in type signatures + | help: replace with the correct return type: `&'static &'static usize` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:53:52 + | +LL | unsafe fn test12(x: *const usize) -> *const *const _ { + | --------------^ + | | | + | | not allowed in type signatures + | help: replace with the correct return type: `*const *const usize` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:67:8 + | +LL | a: _, + | ^ not allowed in type signatures +LL | +LL | b: (_, _), + | ^ ^ not allowed in type signatures + | | + | not allowed in type signatures + | +help: use type parameters instead + | +LL ~ struct Test10<T> { +LL ~ a: T, +LL | +LL ~ b: (T, T), + | + +error: missing type for `static` item + --> $DIR/typeck_type_placeholder_item.rs:73:12 + | +LL | static A = 42; + | ^ help: provide a type for the static variable: `A: i32` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/typeck_type_placeholder_item.rs:75:15 + | +LL | static B: _ = 42; + | ^ + | | + | not allowed in type signatures + | help: replace with the correct type: `i32` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/typeck_type_placeholder_item.rs:77:15 + | +LL | static C: Option<_> = Some(42); + | ^^^^^^^^^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:79:21 + | +LL | fn fn_test() -> _ { 5 } + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `i32` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:82:23 + | +LL | fn fn_test2() -> (_, _) { (5, 5) } + | -^--^- + | || | + | || not allowed in type signatures + | |not allowed in type signatures + | help: replace with the correct return type: `(i32, i32)` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/typeck_type_placeholder_item.rs:85:22 + | +LL | static FN_TEST3: _ = "test"; + | ^ + | | + | not allowed in type signatures + | help: replace with the correct type: `&str` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/typeck_type_placeholder_item.rs:88:22 + | +LL | static FN_TEST4: _ = 145; + | ^ + | | + | not allowed in type signatures + | help: replace with the correct type: `i32` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/typeck_type_placeholder_item.rs:91:22 + | +LL | static FN_TEST5: (_, _) = (1, 2); + | ^^^^^^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:94:20 + | +LL | fn fn_test6(_: _) { } + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn fn_test6<T>(_: T) { } + | +++ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:97:20 + | +LL | fn fn_test7(x: _) { let _x: usize = x; } + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn fn_test7<T>(x: T) { let _x: usize = x; } + | +++ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:100:29 + | +LL | fn fn_test8(_f: fn() -> _) { } + | ^ + | | + | not allowed in type signatures + | help: use type parameters instead: `T` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:100:29 + | +LL | fn fn_test8(_f: fn() -> _) { } + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn fn_test8<T>(_f: fn() -> T) { } + | +++ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:123:12 + | +LL | a: _, + | ^ not allowed in type signatures +LL | +LL | b: (_, _), + | ^ ^ not allowed in type signatures + | | + | not allowed in type signatures + | +help: use type parameters instead + | +LL ~ struct FnTest10<T> { +LL ~ a: T, +LL | +LL ~ b: (T, T), + | + +error[E0282]: type annotations needed + --> $DIR/typeck_type_placeholder_item.rs:128:18 + | +LL | fn fn_test11(_: _) -> (_, _) { panic!() } + | ^ cannot infer type + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:128:28 + | +LL | fn fn_test11(_: _) -> (_, _) { panic!() } + | ^ ^ not allowed in type signatures + | | + | not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:132:30 + | +LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } + | -^--^- + | || | + | || not allowed in type signatures + | |not allowed in type signatures + | help: replace with the correct return type: `(i32, i32)` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:135:33 + | +LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } + | ------^- + | | | + | | not allowed in type signatures + | help: replace with the correct return type: `(i32, i32)` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:154:21 + | +LL | struct BadStruct<_>(_); + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | struct BadStruct<T>(T); + | ~ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for implementations + --> $DIR/typeck_type_placeholder_item.rs:159:15 + | +LL | impl BadTrait<_> for BadStruct<_> {} + | ^ ^ not allowed in type signatures + | | + | not allowed in type signatures + | +help: use type parameters instead + | +LL | impl<T> BadTrait<T> for BadStruct<T> {} + | +++ ~ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for opaque types + --> $DIR/typeck_type_placeholder_item.rs:162:34 + | +LL | fn impl_trait() -> impl BadTrait<_> { + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:167:25 + | +LL | struct BadStruct1<_, _>(_); + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | struct BadStruct1<T, _>(T); + | ~ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:172:25 + | +LL | struct BadStruct2<_, T>(_, T); + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | struct BadStruct2<U, T>(U, T); + | ~ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for type aliases + --> $DIR/typeck_type_placeholder_item.rs:176:14 + | +LL | type X = Box<_>; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for opaque types + --> $DIR/typeck_type_placeholder_item.rs:182:21 + | +LL | type Y = impl Trait<_>; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:216:31 + | +LL | fn value() -> Option<&'static _> { + | ----------------^- + | | | + | | not allowed in type signatures + | help: replace with the correct return type: `Option<&'static u8>` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:221:10 + | +LL | const _: Option<_> = map(value); + | ^^^^^^^^^ + | | + | not allowed in type signatures + | help: replace with the correct type: `Option<u8>` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:140:31 + | +LL | fn method_test1(&self, x: _); + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn method_test1<T>(&self, x: T); + | +++ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:142:31 + | +LL | fn method_test2(&self, x: _) -> _; + | ^ ^ not allowed in type signatures + | | + | not allowed in type signatures + | +help: use type parameters instead + | +LL | fn method_test2<T>(&self, x: T) -> T; + | +++ ~ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:144:31 + | +LL | fn method_test3(&self) -> _; + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn method_test3<T>(&self) -> T; + | +++ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:146:26 + | +LL | fn assoc_fn_test1(x: _); + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn assoc_fn_test1<T>(x: T); + | +++ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:148:26 + | +LL | fn assoc_fn_test2(x: _) -> _; + | ^ ^ not allowed in type signatures + | | + | not allowed in type signatures + | +help: use type parameters instead + | +LL | fn assoc_fn_test2<T>(x: T) -> T; + | +++ ~ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:150:28 + | +LL | fn assoc_fn_test3() -> _; + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn assoc_fn_test3<T>() -> T; + | +++ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/typeck_type_placeholder_item.rs:190:14 + | +LL | type B = _; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:192:14 + | +LL | const C: _; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:194:14 + | +LL | const D: _ = 42; + | ^ + | | + | not allowed in type signatures + | help: replace with the correct type: `i32` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/typeck_type_placeholder_item.rs:197:26 + | +LL | type F: std::ops::Fn(_); + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:41:24 + | +LL | fn test9(&self) -> _ { () } + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `()` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:44:27 + | +LL | fn test10(&self, _x : _) { } + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn test10<T>(&self, _x : T) { } + | +++ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:59:24 + | +LL | fn clone(&self) -> _ { Test9 } + | ^ not allowed in type signatures + | +help: try replacing `_` with the type in the corresponding trait method signature + | +LL | fn clone(&self) -> Test9 { Test9 } + | ~~~~~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:62:37 + | +LL | fn clone_from(&mut self, other: _) { *self = Test9; } + | ^ not allowed in type signatures + | +help: try replacing `_` with the type in the corresponding trait method signature + | +LL | fn clone_from(&mut self, other: &Test9) { *self = Test9; } + | ~~~~~~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:107:31 + | +LL | fn fn_test9(&self) -> _ { () } + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `()` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:110:34 + | +LL | fn fn_test10(&self, _x : _) { } + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn fn_test10<T>(&self, _x : T) { } + | +++ ~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:115:28 + | +LL | fn clone(&self) -> _ { FnTest9 } + | ^ not allowed in type signatures + | +help: try replacing `_` with the type in the corresponding trait method signature + | +LL | fn clone(&self) -> FnTest9 { FnTest9 } + | ~~~~~~~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:118:41 + | +LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } + | ^ not allowed in type signatures + | +help: try replacing `_` with the type in the corresponding trait method signature + | +LL | fn clone_from(&mut self, other: &FnTest9) { *self = FnTest9; } + | ~~~~~~~~ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/typeck_type_placeholder_item.rs:201:14 + | +LL | type A = _; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/typeck_type_placeholder_item.rs:203:14 + | +LL | type B = _; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:205:14 + | +LL | const C: _; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:208:14 + | +LL | const D: _ = 42; + | ^ + | | + | not allowed in type signatures + | help: replace with the correct type: `i32` + +error: aborting due to 69 previous errors + +Some errors have detailed explanations: E0121, E0282, E0403. +For more information about an error, try `rustc --explain E0121`. diff --git a/src/test/ui/typeck/typeck_type_placeholder_item_help.rs b/src/test/ui/typeck/typeck_type_placeholder_item_help.rs new file mode 100644 index 000000000..c459d8c3c --- /dev/null +++ b/src/test/ui/typeck/typeck_type_placeholder_item_help.rs @@ -0,0 +1,33 @@ +// This test checks that it proper item type will be suggested when +// using the `_` type placeholder. + +fn test1() -> _ { Some(42) } +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + +const TEST2: _ = 42u32; +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + +const TEST3: _ = Some(42); +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants + +const TEST4: fn() -> _ = 42; +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions +//~| ERROR the placeholder `_` is not allowed within types on item signatures for constant items + +trait Test5 { + const TEST5: _ = 42; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants +} + +struct Test6; + +impl Test6 { + const TEST6: _ = 13; + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants +} + +pub fn main() { + let _: Option<usize> = test1(); + let _: f64 = test1(); + let _: Option<i32> = test1(); +} diff --git a/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr b/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr new file mode 100644 index 000000000..07a5dbd93 --- /dev/null +++ b/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr @@ -0,0 +1,60 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item_help.rs:4:15 + | +LL | fn test1() -> _ { Some(42) } + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `Option<i32>` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item_help.rs:7:14 + | +LL | const TEST2: _ = 42u32; + | ^ + | | + | not allowed in type signatures + | help: replace with the correct type: `u32` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item_help.rs:10:14 + | +LL | const TEST3: _ = Some(42); + | ^ + | | + | not allowed in type signatures + | help: replace with the correct type: `Option<i32>` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item_help.rs:13:22 + | +LL | const TEST4: fn() -> _ = 42; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constant items + --> $DIR/typeck_type_placeholder_item_help.rs:13:22 + | +LL | const TEST4: fn() -> _ = 42; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item_help.rs:18:18 + | +LL | const TEST5: _ = 42; + | ^ + | | + | not allowed in type signatures + | help: replace with the correct type: `i32` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item_help.rs:25:18 + | +LL | const TEST6: _ = 13; + | ^ + | | + | not allowed in type signatures + | help: replace with the correct type: `i32` + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/typeck/typeck_type_placeholder_lifetime_1.rs b/src/test/ui/typeck/typeck_type_placeholder_lifetime_1.rs new file mode 100644 index 000000000..43e46c5b6 --- /dev/null +++ b/src/test/ui/typeck/typeck_type_placeholder_lifetime_1.rs @@ -0,0 +1,11 @@ +// This test checks that the `_` type placeholder does not react +// badly if put as a lifetime parameter. + +struct Foo<'a, T:'a> { + r: &'a T +} + +pub fn main() { + let c: Foo<_, _> = Foo { r: &5 }; + //~^ ERROR this struct takes 1 generic argument but 2 generic arguments were supplied +} diff --git a/src/test/ui/typeck/typeck_type_placeholder_lifetime_1.stderr b/src/test/ui/typeck/typeck_type_placeholder_lifetime_1.stderr new file mode 100644 index 000000000..a89c6b85c --- /dev/null +++ b/src/test/ui/typeck/typeck_type_placeholder_lifetime_1.stderr @@ -0,0 +1,17 @@ +error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied + --> $DIR/typeck_type_placeholder_lifetime_1.rs:9:12 + | +LL | let c: Foo<_, _> = Foo { r: &5 }; + | ^^^ - help: remove this generic argument + | | + | expected 1 generic argument + | +note: struct defined here, with 1 generic parameter: `T` + --> $DIR/typeck_type_placeholder_lifetime_1.rs:4:8 + | +LL | struct Foo<'a, T:'a> { + | ^^^ - + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/typeck/typeck_type_placeholder_lifetime_2.rs b/src/test/ui/typeck/typeck_type_placeholder_lifetime_2.rs new file mode 100644 index 000000000..178b8b122 --- /dev/null +++ b/src/test/ui/typeck/typeck_type_placeholder_lifetime_2.rs @@ -0,0 +1,11 @@ +// This test checks that the `_` type placeholder does not react +// badly if put as a lifetime parameter. + +struct Foo<'a, T:'a> { + r: &'a T +} + +pub fn main() { + let c: Foo<_, usize> = Foo { r: &5 }; + //~^ ERROR this struct takes 1 generic argument but 2 generic arguments were supplied +} diff --git a/src/test/ui/typeck/typeck_type_placeholder_lifetime_2.stderr b/src/test/ui/typeck/typeck_type_placeholder_lifetime_2.stderr new file mode 100644 index 000000000..f30766bdf --- /dev/null +++ b/src/test/ui/typeck/typeck_type_placeholder_lifetime_2.stderr @@ -0,0 +1,17 @@ +error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied + --> $DIR/typeck_type_placeholder_lifetime_2.rs:9:12 + | +LL | let c: Foo<_, usize> = Foo { r: &5 }; + | ^^^ ----- help: remove this generic argument + | | + | expected 1 generic argument + | +note: struct defined here, with 1 generic parameter: `T` + --> $DIR/typeck_type_placeholder_lifetime_2.rs:4:8 + | +LL | struct Foo<'a, T:'a> { + | ^^^ - + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/typeck/typeck_type_placeholder_mismatch.rs b/src/test/ui/typeck/typeck_type_placeholder_mismatch.rs new file mode 100644 index 000000000..2f9cfcf8d --- /dev/null +++ b/src/test/ui/typeck/typeck_type_placeholder_mismatch.rs @@ -0,0 +1,27 @@ +// This test checks that genuine type errors with partial +// type hints are understandable. + +use std::marker::PhantomData; + +struct Foo<T>(PhantomData<T>); +struct Bar<U>(PhantomData<U>); + +pub fn main() { +} + +fn test1() { + let x: Foo<_> = Bar::<usize>(PhantomData); + //~^ ERROR mismatched types + //~| expected struct `Foo<_>` + //~| found struct `Bar<usize>` + //~| expected struct `Foo`, found struct `Bar` + let y: Foo<usize> = x; +} + +fn test2() { + let x: Foo<_> = Bar::<usize>(PhantomData); + //~^ ERROR mismatched types + //~| expected struct `Foo<_>` + //~| found struct `Bar<usize>` + //~| expected struct `Foo`, found struct `Bar` +} diff --git a/src/test/ui/typeck/typeck_type_placeholder_mismatch.stderr b/src/test/ui/typeck/typeck_type_placeholder_mismatch.stderr new file mode 100644 index 000000000..867412a24 --- /dev/null +++ b/src/test/ui/typeck/typeck_type_placeholder_mismatch.stderr @@ -0,0 +1,25 @@ +error[E0308]: mismatched types + --> $DIR/typeck_type_placeholder_mismatch.rs:13:21 + | +LL | let x: Foo<_> = Bar::<usize>(PhantomData); + | ------ ^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Foo`, found struct `Bar` + | | + | expected due to this + | + = note: expected struct `Foo<_>` + found struct `Bar<usize>` + +error[E0308]: mismatched types + --> $DIR/typeck_type_placeholder_mismatch.rs:22:21 + | +LL | let x: Foo<_> = Bar::<usize>(PhantomData); + | ------ ^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Foo`, found struct `Bar` + | | + | expected due to this + | + = note: expected struct `Foo<_>` + found struct `Bar<usize>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeck/ufcs-type-params.rs b/src/test/ui/typeck/ufcs-type-params.rs new file mode 100644 index 000000000..eee2b55b2 --- /dev/null +++ b/src/test/ui/typeck/ufcs-type-params.rs @@ -0,0 +1,15 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait Foo<T> { + fn get(&self) -> T; +} + +impl Foo<i32> for i32 { + fn get(&self) -> i32 { *self } +} + +fn main() { + let x: i32 = 1; + Foo::<i32>::get(&x); +} diff --git a/src/test/ui/typeck/unify-return-ty.rs b/src/test/ui/typeck/unify-return-ty.rs new file mode 100644 index 000000000..da1d82e89 --- /dev/null +++ b/src/test/ui/typeck/unify-return-ty.rs @@ -0,0 +1,16 @@ +// run-pass +// Tests that the tail expr in null() has its type +// unified with the type *T, and so the type variable +// in that type gets resolved. + +// pretty-expanded FIXME #23616 + +use std::mem; + +fn null<T>() -> *const T { + unsafe { + mem::transmute(0_usize) + } +} + +pub fn main() { null::<isize>(); } diff --git a/src/test/ui/typeck/while-loop-block-cond.rs b/src/test/ui/typeck/while-loop-block-cond.rs new file mode 100644 index 000000000..929759766 --- /dev/null +++ b/src/test/ui/typeck/while-loop-block-cond.rs @@ -0,0 +1,4 @@ +fn main() { + while {} {} + //~^ ERROR mismatched types [E0308] +} diff --git a/src/test/ui/typeck/while-loop-block-cond.stderr b/src/test/ui/typeck/while-loop-block-cond.stderr new file mode 100644 index 000000000..598273af9 --- /dev/null +++ b/src/test/ui/typeck/while-loop-block-cond.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/while-loop-block-cond.rs:2:11 + | +LL | while {} {} + | ^^ expected `bool`, found `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/typeid-intrinsic.rs b/src/test/ui/typeid-intrinsic.rs new file mode 100644 index 000000000..5bc4e0c21 --- /dev/null +++ b/src/test/ui/typeid-intrinsic.rs @@ -0,0 +1,97 @@ +// run-pass + +#![allow(deprecated)] +// aux-build:typeid-intrinsic-aux1.rs +// aux-build:typeid-intrinsic-aux2.rs + +#![feature(core_intrinsics)] + +extern crate typeid_intrinsic_aux1 as other1; +extern crate typeid_intrinsic_aux2 as other2; + +use std::hash::{SipHasher, Hasher, Hash}; +use std::any::TypeId; + +struct A; +struct Test; + +pub fn main() { + assert_eq!(TypeId::of::<other1::A>(), other1::id_A()); + assert_eq!(TypeId::of::<other1::B>(), other1::id_B()); + assert_eq!(TypeId::of::<other1::C>(), other1::id_C()); + assert_eq!(TypeId::of::<other1::D>(), other1::id_D()); + assert_eq!(TypeId::of::<other1::E>(), other1::id_E()); + assert_eq!(TypeId::of::<other1::F>(), other1::id_F()); + assert_eq!(TypeId::of::<other1::G>(), other1::id_G()); + assert_eq!(TypeId::of::<other1::H>(), other1::id_H()); + assert_eq!(TypeId::of::<other1::I>(), other1::id_I()); + + assert_eq!(TypeId::of::<other2::A>(), other2::id_A()); + assert_eq!(TypeId::of::<other2::B>(), other2::id_B()); + assert_eq!(TypeId::of::<other2::C>(), other2::id_C()); + assert_eq!(TypeId::of::<other2::D>(), other2::id_D()); + assert_eq!(TypeId::of::<other2::E>(), other2::id_E()); + assert_eq!(TypeId::of::<other2::F>(), other2::id_F()); + assert_eq!(TypeId::of::<other2::G>(), other2::id_G()); + assert_eq!(TypeId::of::<other2::H>(), other2::id_H()); + assert_eq!(TypeId::of::<other1::I>(), other2::id_I()); + + assert_eq!(other1::id_F(), other2::id_F()); + assert_eq!(other1::id_G(), other2::id_G()); + assert_eq!(other1::id_H(), other2::id_H()); + assert_eq!(other1::id_I(), other2::id_I()); + + assert_eq!(TypeId::of::<isize>(), other2::foo::<isize>()); + assert_eq!(TypeId::of::<isize>(), other1::foo::<isize>()); + assert_eq!(other2::foo::<isize>(), other1::foo::<isize>()); + assert_eq!(TypeId::of::<A>(), other2::foo::<A>()); + assert_eq!(TypeId::of::<A>(), other1::foo::<A>()); + assert_eq!(other2::foo::<A>(), other1::foo::<A>()); + + // sanity test of TypeId + let (a, b, c) = (TypeId::of::<usize>(), TypeId::of::<&'static str>(), + TypeId::of::<Test>()); + let (d, e, f) = (TypeId::of::<usize>(), TypeId::of::<&'static str>(), + TypeId::of::<Test>()); + + assert!(a != b); + assert!(a != c); + assert!(b != c); + + assert_eq!(a, d); + assert_eq!(b, e); + assert_eq!(c, f); + + // check it has a hash + let (a, b) = (TypeId::of::<usize>(), TypeId::of::<usize>()); + + let mut s1 = SipHasher::new(); + a.hash(&mut s1); + let mut s2 = SipHasher::new(); + b.hash(&mut s2); + + assert_eq!(s1.finish(), s2.finish()); + + // Check projections + + assert_eq!(TypeId::of::<other1::I32Iterator>(), other1::id_i32_iterator()); + assert_eq!(TypeId::of::<other1::U32Iterator>(), other1::id_u32_iterator()); + assert_eq!(other1::id_i32_iterator(), other2::id_i32_iterator()); + assert_eq!(other1::id_u32_iterator(), other2::id_u32_iterator()); + assert_ne!(other1::id_i32_iterator(), other1::id_u32_iterator()); + assert_ne!(TypeId::of::<other1::I32Iterator>(), TypeId::of::<other1::U32Iterator>()); + + // Check fn pointer against collisions + assert_ne!( + TypeId::of::<fn(fn(A) -> A) -> A>(), + TypeId::of::<fn(fn() -> A, A) -> A>() + ); + assert_ne!( + TypeId::of::<for<'a> fn(&'a i32) -> &'a i32>(), + TypeId::of::<for<'a> fn(&'a i32) -> &'static i32>() + ); + assert_ne!( + TypeId::of::<for<'a, 'b> fn(&'a i32, &'b i32) -> &'a i32>(), + TypeId::of::<for<'a, 'b> fn(&'b i32, &'a i32) -> &'a i32>() + ); +} diff --git a/src/test/ui/typeof/type_mismatch.rs b/src/test/ui/typeof/type_mismatch.rs new file mode 100644 index 000000000..3f8339fa5 --- /dev/null +++ b/src/test/ui/typeof/type_mismatch.rs @@ -0,0 +1,9 @@ +// Test that using typeof results in the correct type mismatch errors instead of always assuming +// `usize`, in addition to the pre-existing "typeof is reserved and unimplemented" error +fn main() { + const a: u8 = 1; + let b: typeof(a) = 1i8; + //~^ ERROR `typeof` is a reserved keyword but unimplemented + //~| ERROR mismatched types + //~| expected `u8`, found `i8` +} diff --git a/src/test/ui/typeof/type_mismatch.stderr b/src/test/ui/typeof/type_mismatch.stderr new file mode 100644 index 000000000..e75214cd3 --- /dev/null +++ b/src/test/ui/typeof/type_mismatch.stderr @@ -0,0 +1,28 @@ +error[E0516]: `typeof` is a reserved keyword but unimplemented + --> $DIR/type_mismatch.rs:5:12 + | +LL | let b: typeof(a) = 1i8; + | ^^^^^^^^^ reserved keyword + | +help: consider replacing `typeof(...)` with an actual type + | +LL | let b: u8 = 1i8; + | ~~ + +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:5:24 + | +LL | let b: typeof(a) = 1i8; + | --------- ^^^ expected `u8`, found `i8` + | | + | expected due to this + | +help: change the type of the numeric literal from `i8` to `u8` + | +LL | let b: typeof(a) = 1u8; + | ~~ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0308, E0516. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/typestate-multi-decl.rs b/src/test/ui/typestate-multi-decl.rs new file mode 100644 index 000000000..9f9416205 --- /dev/null +++ b/src/test/ui/typestate-multi-decl.rs @@ -0,0 +1,7 @@ +// run-pass + +pub fn main() { + let (x, y) = (10, 20); + let z = x + y; + assert_eq!(z, 30); +} |