diff options
Diffstat (limited to '')
51 files changed, 983 insertions, 0 deletions
diff --git a/src/test/ui/const-generics/defaults/auxiliary/const_defaulty.rs b/src/test/ui/const-generics/defaults/auxiliary/const_defaulty.rs new file mode 100644 index 000000000..eed982534 --- /dev/null +++ b/src/test/ui/const-generics/defaults/auxiliary/const_defaulty.rs @@ -0,0 +1,11 @@ +pub struct Defaulted<const N: usize=3>; +impl Defaulted { + pub fn new() -> Self { + Defaulted + } +} +impl<const N: usize> Defaulted<N> { + pub fn value(&self) -> usize { + N + } +} diff --git a/src/test/ui/const-generics/defaults/auxiliary/trait_object_lt_defaults_lib.rs b/src/test/ui/const-generics/defaults/auxiliary/trait_object_lt_defaults_lib.rs new file mode 100644 index 000000000..26a2c47ff --- /dev/null +++ b/src/test/ui/const-generics/defaults/auxiliary/trait_object_lt_defaults_lib.rs @@ -0,0 +1 @@ +pub struct Foo<'a, const N: usize, T: 'a + ?Sized>(pub &'a T, [(); N]); diff --git a/src/test/ui/const-generics/defaults/complex-generic-default-expr.min.stderr b/src/test/ui/const-generics/defaults/complex-generic-default-expr.min.stderr new file mode 100644 index 000000000..b836cfeae --- /dev/null +++ b/src/test/ui/const-generics/defaults/complex-generic-default-expr.min.stderr @@ -0,0 +1,20 @@ +error: generic parameters may not be used in const operations + --> $DIR/complex-generic-default-expr.rs:6:47 + | +LL | struct Foo<const N: usize, const M: usize = { N + 1 }>; + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments, i.e. `N` + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/complex-generic-default-expr.rs:9:62 + | +LL | struct Bar<T, const TYPE_SIZE: usize = { std::mem::size_of::<T>() }>(T); + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-generics/defaults/complex-generic-default-expr.rs b/src/test/ui/const-generics/defaults/complex-generic-default-expr.rs new file mode 100644 index 000000000..7f50d4c9f --- /dev/null +++ b/src/test/ui/const-generics/defaults/complex-generic-default-expr.rs @@ -0,0 +1,12 @@ +// revisions: full min +//[full] check-pass +#![cfg_attr(full, feature(generic_const_exprs))] +#![cfg_attr(full, allow(incomplete_features))] + +struct Foo<const N: usize, const M: usize = { N + 1 }>; +//[min]~^ ERROR generic parameters may not be used in const operations + +struct Bar<T, const TYPE_SIZE: usize = { std::mem::size_of::<T>() }>(T); +//[min]~^ ERROR generic parameters may not be used in const operations + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/complex-unord-param.min.stderr b/src/test/ui/const-generics/defaults/complex-unord-param.min.stderr new file mode 100644 index 000000000..8e8d26a00 --- /dev/null +++ b/src/test/ui/const-generics/defaults/complex-unord-param.min.stderr @@ -0,0 +1,8 @@ +error: type parameters must be declared prior to const parameters + --> $DIR/complex-unord-param.rs:8:41 + | +LL | struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> { + | ---------------------^----------------------^--------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, A: 'a, T: 'a = u32, const N: usize, const M: usize>` + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/defaults/complex-unord-param.rs b/src/test/ui/const-generics/defaults/complex-unord-param.rs new file mode 100644 index 000000000..aebc5975a --- /dev/null +++ b/src/test/ui/const-generics/defaults/complex-unord-param.rs @@ -0,0 +1,17 @@ +// run-pass +// Checks a complicated usage of unordered params +#![allow(dead_code)] + +struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> { + args: &'a [&'a [T; M]; N], + specifier: A, +} + +fn main() { + let array = [1, 2, 3]; + let nest = [&array]; + let _ = NestedArrays { + args: &nest, + specifier: true, + }; +} diff --git a/src/test/ui/const-generics/defaults/const-default.rs b/src/test/ui/const-generics/defaults/const-default.rs new file mode 100644 index 000000000..65cb0eb14 --- /dev/null +++ b/src/test/ui/const-generics/defaults/const-default.rs @@ -0,0 +1,24 @@ +// run-pass +pub struct ConstDefault<const N: usize = 3>; + +impl<const N: usize> ConstDefault<N> { + fn foo(self) -> usize { + N + } +} + +impl ConstDefault { + fn new() -> Self { + ConstDefault + } + + fn bar(self) {} +} + +pub fn main() { + let s = ConstDefault::new(); + assert_eq!(s.foo(), 3); + + let w = ConstDefault::<3>; + w.bar(); +} diff --git a/src/test/ui/const-generics/defaults/const-param-as-default-value.rs b/src/test/ui/const-generics/defaults/const-param-as-default-value.rs new file mode 100644 index 000000000..c1c955d87 --- /dev/null +++ b/src/test/ui/const-generics/defaults/const-param-as-default-value.rs @@ -0,0 +1,21 @@ +// run-pass +struct Foo<const N: usize, const M: usize = N>([u8; N], [u8; M]); + +fn foo<const N: usize>() -> Foo<N> { + let x = [0; N]; + Foo(x, x) +} + +// To check that we actually apply the correct substs for const param defaults. +fn concrete_foo() -> Foo<13> { + Foo(Default::default(), Default::default()) +} + + +fn main() { + let val = foo::<13>(); + assert_eq!(val.0, val.1); + + let val = concrete_foo(); + assert_eq!(val.0, val.1); +} diff --git a/src/test/ui/const-generics/defaults/const-param-in-ty-defaults.rs b/src/test/ui/const-generics/defaults/const-param-in-ty-defaults.rs new file mode 100644 index 000000000..5f0cafe2e --- /dev/null +++ b/src/test/ui/const-generics/defaults/const-param-in-ty-defaults.rs @@ -0,0 +1,12 @@ +// run-pass +struct Foo<const N: usize, T = [u8; N]>(T); + +impl<const N: usize> Foo<N> { + fn new() -> Self { + Foo([0; N]) + } +} + +fn main() { + assert_eq!(Foo::new().0, [0; 10]); +} diff --git a/src/test/ui/const-generics/defaults/default-annotation.rs b/src/test/ui/const-generics/defaults/default-annotation.rs new file mode 100644 index 000000000..7a9f5732f --- /dev/null +++ b/src/test/ui/const-generics/defaults/default-annotation.rs @@ -0,0 +1,17 @@ +// run-pass +#![feature(staged_api)] +#![allow(incomplete_features)] +// FIXME(const_generics_defaults): It seems like we aren't testing the right thing here, +// I would assume that we want the attributes to apply to the const parameter defaults +// themselves. +#![stable(feature = "const_default_test", since="none")] + +#[unstable(feature = "const_default_stable", issue="none")] +pub struct ConstDefaultUnstable<const N: usize = 3>; + +#[stable(feature = "const_default_unstable", since="none")] +pub struct ConstDefaultStable<const N: usize = { + 3 +}>; + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/default-const-param-cannot-reference-self.rs b/src/test/ui/const-generics/defaults/default-const-param-cannot-reference-self.rs new file mode 100644 index 000000000..45275e609 --- /dev/null +++ b/src/test/ui/const-generics/defaults/default-const-param-cannot-reference-self.rs @@ -0,0 +1,14 @@ +struct Struct<const N: usize = { Self; 10 }>; +//~^ ERROR generic parameters cannot use `Self` in their defaults [E0735] + +enum Enum<const N: usize = { Self; 10 }> { } +//~^ ERROR generic parameters cannot use `Self` in their defaults [E0735] + +union Union<const N: usize = { Self; 10 }> { not_empty: () } +//~^ ERROR generic parameters cannot use `Self` in their defaults [E0735] + +fn main() { + let _: Struct; + let _: Enum; + let _: Union; +} diff --git a/src/test/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr b/src/test/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr new file mode 100644 index 000000000..72d7001fd --- /dev/null +++ b/src/test/ui/const-generics/defaults/default-const-param-cannot-reference-self.stderr @@ -0,0 +1,21 @@ +error[E0735]: generic parameters cannot use `Self` in their defaults + --> $DIR/default-const-param-cannot-reference-self.rs:1:34 + | +LL | struct Struct<const N: usize = { Self; 10 }>; + | ^^^^ `Self` in generic parameter default + +error[E0735]: generic parameters cannot use `Self` in their defaults + --> $DIR/default-const-param-cannot-reference-self.rs:4:30 + | +LL | enum Enum<const N: usize = { Self; 10 }> { } + | ^^^^ `Self` in generic parameter default + +error[E0735]: generic parameters cannot use `Self` in their defaults + --> $DIR/default-const-param-cannot-reference-self.rs:7:32 + | +LL | union Union<const N: usize = { Self; 10 }> { not_empty: () } + | ^^^^ `Self` in generic parameter default + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0735`. diff --git a/src/test/ui/const-generics/defaults/default-on-impl.rs b/src/test/ui/const-generics/defaults/default-on-impl.rs new file mode 100644 index 000000000..9ce46aa09 --- /dev/null +++ b/src/test/ui/const-generics/defaults/default-on-impl.rs @@ -0,0 +1,6 @@ +struct Foo<const N: usize>; + +impl<const N: usize = 1> Foo<N> {} +//~^ ERROR defaults for const parameters are only allowed + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/default-on-impl.stderr b/src/test/ui/const-generics/defaults/default-on-impl.stderr new file mode 100644 index 000000000..4b2b05742 --- /dev/null +++ b/src/test/ui/const-generics/defaults/default-on-impl.stderr @@ -0,0 +1,8 @@ +error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + --> $DIR/default-on-impl.rs:3:6 + | +LL | impl<const N: usize = 1> Foo<N> {} + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/defaults/default-param-wf-concrete.rs b/src/test/ui/const-generics/defaults/default-param-wf-concrete.rs new file mode 100644 index 000000000..41a52c7eb --- /dev/null +++ b/src/test/ui/const-generics/defaults/default-param-wf-concrete.rs @@ -0,0 +1,3 @@ +struct Foo<const N: u8 = { 255 + 1 }>; +//~^ ERROR evaluation of constant value failed +fn main() {} diff --git a/src/test/ui/const-generics/defaults/default-param-wf-concrete.stderr b/src/test/ui/const-generics/defaults/default-param-wf-concrete.stderr new file mode 100644 index 000000000..e8ebddade --- /dev/null +++ b/src/test/ui/const-generics/defaults/default-param-wf-concrete.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/default-param-wf-concrete.rs:1:28 + | +LL | struct Foo<const N: u8 = { 255 + 1 }>; + | ^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-generics/defaults/doesnt_infer.rs b/src/test/ui/const-generics/defaults/doesnt_infer.rs new file mode 100644 index 000000000..9c59e672d --- /dev/null +++ b/src/test/ui/const-generics/defaults/doesnt_infer.rs @@ -0,0 +1,13 @@ +// test that defaulted const params are not used to help type inference + +struct Foo<const N: u32 = 2>; + +impl<const N: u32> Foo<N> { + fn foo() -> Self { loop {} } +} + +fn main() { + let foo = Foo::<1>::foo(); + let foo = Foo::foo(); + //~^ error: type annotations needed for `Foo<N>` +} diff --git a/src/test/ui/const-generics/defaults/doesnt_infer.stderr b/src/test/ui/const-generics/defaults/doesnt_infer.stderr new file mode 100644 index 000000000..227b2f402 --- /dev/null +++ b/src/test/ui/const-generics/defaults/doesnt_infer.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed for `Foo<N>` + --> $DIR/doesnt_infer.rs:11:9 + | +LL | let foo = Foo::foo(); + | ^^^ + | +help: consider giving `foo` an explicit type, where the the value of const parameter `N` is specified + | +LL | let foo: Foo<N> = Foo::foo(); + | ++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/const-generics/defaults/external.rs b/src/test/ui/const-generics/defaults/external.rs new file mode 100644 index 000000000..25ec523cb --- /dev/null +++ b/src/test/ui/const-generics/defaults/external.rs @@ -0,0 +1,24 @@ +// aux-build:const_defaulty.rs +// check-pass +extern crate const_defaulty; +use const_defaulty::Defaulted; + +struct Local<const N: usize=4>; +impl Local { + fn new() -> Self { + Local + } +} +impl<const N: usize>Local<N> { + fn value(&self) -> usize { + N + } +} + +fn main() { + let v = Defaulted::new(); + assert_eq!(v.value(), 3); + + let l = Local::new(); + assert_eq!(l.value(), 4); +} diff --git a/src/test/ui/const-generics/defaults/forward-declared.rs b/src/test/ui/const-generics/defaults/forward-declared.rs new file mode 100644 index 000000000..ede3d873b --- /dev/null +++ b/src/test/ui/const-generics/defaults/forward-declared.rs @@ -0,0 +1,13 @@ +struct Foo<const N: usize = M, const M: usize = 10>; +//~^ ERROR generic parameters with a default cannot use forward declared identifiers + +enum Bar<const N: usize = M, const M: usize = 10> {} +//~^ ERROR generic parameters with a default cannot use forward declared identifiers + +struct Foo2<const N: usize = N>; +//~^ ERROR generic parameters with a default cannot use forward declared identifiers + +enum Bar2<const N: usize = N> {} +//~^ ERROR generic parameters with a default cannot use forward declared identifiers + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/forward-declared.stderr b/src/test/ui/const-generics/defaults/forward-declared.stderr new file mode 100644 index 000000000..4856c7a1f --- /dev/null +++ b/src/test/ui/const-generics/defaults/forward-declared.stderr @@ -0,0 +1,27 @@ +error[E0128]: generic parameters with a default cannot use forward declared identifiers + --> $DIR/forward-declared.rs:1:29 + | +LL | struct Foo<const N: usize = M, const M: usize = 10>; + | ^ defaulted generic parameters cannot be forward declared + +error[E0128]: generic parameters with a default cannot use forward declared identifiers + --> $DIR/forward-declared.rs:4:27 + | +LL | enum Bar<const N: usize = M, const M: usize = 10> {} + | ^ defaulted generic parameters cannot be forward declared + +error[E0128]: generic parameters with a default cannot use forward declared identifiers + --> $DIR/forward-declared.rs:7:30 + | +LL | struct Foo2<const N: usize = N>; + | ^ defaulted generic parameters cannot be forward declared + +error[E0128]: generic parameters with a default cannot use forward declared identifiers + --> $DIR/forward-declared.rs:10:28 + | +LL | enum Bar2<const N: usize = N> {} + | ^ defaulted generic parameters cannot be forward declared + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0128`. diff --git a/src/test/ui/const-generics/defaults/generic-expr-default-concrete.rs b/src/test/ui/const-generics/defaults/generic-expr-default-concrete.rs new file mode 100644 index 000000000..f082bd8d2 --- /dev/null +++ b/src/test/ui/const-generics/defaults/generic-expr-default-concrete.rs @@ -0,0 +1,14 @@ +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +struct Foo<const N: usize, const M: usize = { N + 1 }>; +fn no_constraining() -> Foo<10> { + Foo::<10, 11> +} + +pub fn different_than_default() -> Foo<10> { + Foo::<10, 12> + //~^ error: mismatched types +} + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr b/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr new file mode 100644 index 000000000..e8826ce43 --- /dev/null +++ b/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/generic-expr-default-concrete.rs:10:5 + | +LL | Foo::<10, 12> + | ^^^^^^^^^^^^^ expected `11`, found `12` + | + = note: expected type `11` + found type `12` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.rs b/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.rs new file mode 100644 index 000000000..777865d1c --- /dev/null +++ b/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.rs @@ -0,0 +1,16 @@ +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +struct Foo<const N: usize, const M: usize = { N + 1 }>; +fn should_unify<const N: usize>() -> Foo<N> where [(); { N + 1 }]: { + Foo::<N, { N + 1 }> +} +pub fn shouldnt_unify<const N: usize>() -> Foo<N> +where + [(); { N + 1 }]:, + [(); { N + 2 }]:, { + Foo::<N, { N + 2 }> + //~^ error: mismatched types +} + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr b/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr new file mode 100644 index 000000000..d5a3071b7 --- /dev/null +++ b/src/test/ui/const-generics/defaults/generic-expr-default-mismatched-types.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/generic-expr-default-mismatched-types.rs:12:5 + | +LL | Foo::<N, { N + 2 }> + | ^^^^^^^^^^^^^^^^^^^ expected `{ N + 1 }`, found `{ N + 2 }` + | + = note: expected type `{ N + 1 }` + found type `{ N + 2 }` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/defaults/generic-expr-default.rs b/src/test/ui/const-generics/defaults/generic-expr-default.rs new file mode 100644 index 000000000..8fe43feb7 --- /dev/null +++ b/src/test/ui/const-generics/defaults/generic-expr-default.rs @@ -0,0 +1,24 @@ +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +pub struct Foo<const N: usize, const M: usize = { N + 1 }>; +pub fn needs_evaluatable_bound<const N1: usize>() -> Foo<N1> { + //~^ error: unconstrained generic constant + loop {} +} +pub fn has_evaluatable_bound<const N1: usize>() -> Foo<N1> where [(); N1 + 1]: { + loop {} +} + +type FooAlias<const N: usize, const NP: usize = { N + 1 }> = [(); NP]; +fn needs_evaluatable_bound_alias<T, const N: usize>() -> FooAlias<N> +{ + //~^^ error: unconstrained generic constant + todo!() +} +fn has_evaluatable_bound_alias<const N: usize>() -> FooAlias<N> +where [(); N + 1]: { + todo!() +} + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/generic-expr-default.stderr b/src/test/ui/const-generics/defaults/generic-expr-default.stderr new file mode 100644 index 000000000..ada1498d1 --- /dev/null +++ b/src/test/ui/const-generics/defaults/generic-expr-default.stderr @@ -0,0 +1,18 @@ +error: unconstrained generic constant + --> $DIR/generic-expr-default.rs:5:54 + | +LL | pub fn needs_evaluatable_bound<const N1: usize>() -> Foo<N1> { + | ^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); { N + 1 }]:` + +error: unconstrained generic constant + --> $DIR/generic-expr-default.rs:14:58 + | +LL | fn needs_evaluatable_bound_alias<T, const N: usize>() -> FooAlias<N> + | ^^^^^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); { N + 1 }]:` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.rs b/src/test/ui/const-generics/defaults/intermixed-lifetime.rs new file mode 100644 index 000000000..578938db4 --- /dev/null +++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.rs @@ -0,0 +1,9 @@ +// Checks that lifetimes cannot be interspersed between consts and types. + +struct Foo<const N: usize, 'a, T = u32>(&'a (), T); +//~^ Error lifetime parameters must be declared prior to const parameters + +struct Bar<const N: usize, T = u32, 'a>(&'a (), T); +//~^ Error lifetime parameters must be declared prior to type parameters + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.stderr b/src/test/ui/const-generics/defaults/intermixed-lifetime.stderr new file mode 100644 index 000000000..e27976deb --- /dev/null +++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.stderr @@ -0,0 +1,14 @@ +error: lifetime parameters must be declared prior to const parameters + --> $DIR/intermixed-lifetime.rs:3:28 + | +LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T); + | -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T = u32>` + +error: lifetime parameters must be declared prior to type parameters + --> $DIR/intermixed-lifetime.rs:6:37 + | +LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T); + | --------------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T = u32>` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-generics/defaults/mismatch.rs b/src/test/ui/const-generics/defaults/mismatch.rs new file mode 100644 index 000000000..ec131505e --- /dev/null +++ b/src/test/ui/const-generics/defaults/mismatch.rs @@ -0,0 +1,22 @@ +pub struct Example<const N: usize = 13>; +pub struct Example2<T = u32, const N: usize = 13>(T); +pub struct Example3<const N: usize = 13, T = u32>(T); +pub struct Example4<const N: usize = 13, const M: usize = 4>; + +fn main() { + let e: Example<13> = (); + //~^ Error: mismatched types + //~| expected struct `Example` + let e: Example2<u32, 13> = (); + //~^ Error: mismatched types + //~| expected struct `Example2` + let e: Example3<13, u32> = (); + //~^ Error: mismatched types + //~| expected struct `Example3` + let e: Example3<7> = (); + //~^ Error: mismatched types + //~| expected struct `Example3<7>` + let e: Example4<7> = (); + //~^ Error: mismatched types + //~| expected struct `Example4<7>` +} diff --git a/src/test/ui/const-generics/defaults/mismatch.stderr b/src/test/ui/const-generics/defaults/mismatch.stderr new file mode 100644 index 000000000..52c54aace --- /dev/null +++ b/src/test/ui/const-generics/defaults/mismatch.stderr @@ -0,0 +1,58 @@ +error[E0308]: mismatched types + --> $DIR/mismatch.rs:7:26 + | +LL | let e: Example<13> = (); + | ----------- ^^ expected struct `Example`, found `()` + | | + | expected due to this + | + = note: expected struct `Example` + found unit type `()` + +error[E0308]: mismatched types + --> $DIR/mismatch.rs:10:32 + | +LL | let e: Example2<u32, 13> = (); + | ----------------- ^^ expected struct `Example2`, found `()` + | | + | expected due to this + | + = note: expected struct `Example2` + found unit type `()` + +error[E0308]: mismatched types + --> $DIR/mismatch.rs:13:32 + | +LL | let e: Example3<13, u32> = (); + | ----------------- ^^ expected struct `Example3`, found `()` + | | + | expected due to this + | + = note: expected struct `Example3` + found unit type `()` + +error[E0308]: mismatched types + --> $DIR/mismatch.rs:16:26 + | +LL | let e: Example3<7> = (); + | ----------- ^^ expected struct `Example3`, found `()` + | | + | expected due to this + | + = note: expected struct `Example3<7>` + found unit type `()` + +error[E0308]: mismatched types + --> $DIR/mismatch.rs:19:26 + | +LL | let e: Example4<7> = (); + | ----------- ^^ expected struct `Example4`, found `()` + | | + | expected due to this + | + = note: expected struct `Example4<7>` + found unit type `()` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.rs b/src/test/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.rs new file mode 100644 index 000000000..5c9323261 --- /dev/null +++ b/src/test/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.rs @@ -0,0 +1,41 @@ +trait Trait { + fn foo<U>() {} +} +impl Trait for () { + fn foo<const M: u64>() {} + //~^ error: method `foo` has an incompatible generic parameter for trait +} + +trait Other { + fn bar<const M: u8>() {} +} +impl Other for () { + fn bar<T>() {} + //~^ error: method `bar` has an incompatible generic parameter for trait +} + +trait Uwu { + fn baz<const N: u32>() {} +} +impl Uwu for () { + fn baz<const N: i32>() {} + //~^ error: method `baz` has an incompatible generic parameter for trait +} + +trait Aaaaaa { + fn bbbb<const N: u32, T>() {} +} +impl Aaaaaa for () { + fn bbbb<T, const N: u32>() {} + //~^ error: method `bbbb` has an incompatible generic parameter for trait +} + +trait Names { + fn abcd<T, const N: u32>() {} +} +impl Names for () { + fn abcd<const N: u32, T>() {} + //~^ error: method `abcd` has an incompatible generic parameter for trait +} + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.stderr b/src/test/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.stderr new file mode 100644 index 000000000..3455f2c8e --- /dev/null +++ b/src/test/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.stderr @@ -0,0 +1,68 @@ +error[E0053]: method `foo` has an incompatible generic parameter for trait `Trait` + --> $DIR/mismatched_ty_const_in_trait_impl.rs:5:12 + | +LL | trait Trait { + | ----- +LL | fn foo<U>() {} + | - expected type parameter +LL | } +LL | impl Trait for () { + | ----------------- +LL | fn foo<const M: u64>() {} + | ^^^^^^^^^^^^ found const parameter of type `u64` + +error[E0053]: method `bar` has an incompatible generic parameter for trait `Other` + --> $DIR/mismatched_ty_const_in_trait_impl.rs:13:12 + | +LL | trait Other { + | ----- +LL | fn bar<const M: u8>() {} + | ----------- expected const parameter of type `u8` +LL | } +LL | impl Other for () { + | ----------------- +LL | fn bar<T>() {} + | ^ found type parameter + +error[E0053]: method `baz` has an incompatible generic parameter for trait `Uwu` + --> $DIR/mismatched_ty_const_in_trait_impl.rs:21:12 + | +LL | trait Uwu { + | --- +LL | fn baz<const N: u32>() {} + | ------------ expected const parameter of type `u32` +LL | } +LL | impl Uwu for () { + | --------------- +LL | fn baz<const N: i32>() {} + | ^^^^^^^^^^^^ found const parameter of type `i32` + +error[E0053]: method `bbbb` has an incompatible generic parameter for trait `Aaaaaa` + --> $DIR/mismatched_ty_const_in_trait_impl.rs:29:13 + | +LL | trait Aaaaaa { + | ------ +LL | fn bbbb<const N: u32, T>() {} + | ------------ expected const parameter of type `u32` +LL | } +LL | impl Aaaaaa for () { + | ------------------ +LL | fn bbbb<T, const N: u32>() {} + | ^ found type parameter + +error[E0053]: method `abcd` has an incompatible generic parameter for trait `Names` + --> $DIR/mismatched_ty_const_in_trait_impl.rs:37:13 + | +LL | trait Names { + | ----- +LL | fn abcd<T, const N: u32>() {} + | - expected type parameter +LL | } +LL | impl Names for () { + | ----------------- +LL | fn abcd<const N: u32, T>() {} + | ^^^^^^^^^^^^ found const parameter of type `u32` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0053`. diff --git a/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.rs b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.rs new file mode 100644 index 000000000..da087ffc3 --- /dev/null +++ b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.rs @@ -0,0 +1,4 @@ +struct Foo<const M: usize = 10, 'a>(&'a u32); +//~^ Error lifetime parameters must be declared prior to const parameters + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.stderr b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.stderr new file mode 100644 index 000000000..55f5a5353 --- /dev/null +++ b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.stderr @@ -0,0 +1,8 @@ +error: lifetime parameters must be declared prior to const parameters + --> $DIR/param-order-err-pretty-prints-default.rs:1:33 + | +LL | struct Foo<const M: usize = 10, 'a>(&'a u32); + | ----------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const M: usize = 10>` + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/defaults/pretty-printing-ast.rs b/src/test/ui/const-generics/defaults/pretty-printing-ast.rs new file mode 100644 index 000000000..e202d4e86 --- /dev/null +++ b/src/test/ui/const-generics/defaults/pretty-printing-ast.rs @@ -0,0 +1,11 @@ +// Test the AST pretty printer correctly handles default values for const generics +// check-pass +// compile-flags: -Z unpretty=expanded + +#![crate_type = "lib"] + +trait Foo<const KIND: bool = true> {} + +fn foo<const SIZE: usize = 5>() {} + +struct Range<const FROM: usize = 0, const LEN: usize = 0, const TO: usize = FROM>; diff --git a/src/test/ui/const-generics/defaults/pretty-printing-ast.stdout b/src/test/ui/const-generics/defaults/pretty-printing-ast.stdout new file mode 100644 index 000000000..121138605 --- /dev/null +++ b/src/test/ui/const-generics/defaults/pretty-printing-ast.stdout @@ -0,0 +1,18 @@ +#![feature(prelude_import)] +#![no_std] +// Test the AST pretty printer correctly handles default values for const generics +// check-pass +// compile-flags: -Z unpretty=expanded + +#![crate_type = "lib"] +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; + +trait Foo<const KIND : bool = true> {} + +fn foo<const SIZE : usize = 5>() {} + +struct Range<const FROM : usize = 0, const LEN : usize = 0, const TO : usize = + FROM>; diff --git a/src/test/ui/const-generics/defaults/repr-c-issue-82792.rs b/src/test/ui/const-generics/defaults/repr-c-issue-82792.rs new file mode 100644 index 000000000..118da2723 --- /dev/null +++ b/src/test/ui/const-generics/defaults/repr-c-issue-82792.rs @@ -0,0 +1,11 @@ +// Regression test for #82792. + +// run-pass + +#[repr(C)] +pub struct Loaf<T: Sized, const N: usize = 1> { + head: [T; N], + slice: [T], +} + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait.rs b/src/test/ui/const-generics/defaults/rp_impl_trait.rs new file mode 100644 index 000000000..dde8eea45 --- /dev/null +++ b/src/test/ui/const-generics/defaults/rp_impl_trait.rs @@ -0,0 +1,29 @@ +// run-pass +struct Uwu<const N: u32 = 1, const M: u32 = N>; + +trait Trait {} +impl<const N: u32> Trait for Uwu<N> {} + +fn rawr<const N: u32>() -> impl Trait { + Uwu::<N> +} + +trait Traitor<const N: u8 = 1, const M: u8 = N> { } + +impl<const N: u8> Traitor<N> for u32 {} +impl Traitor<1, 1> for u64 {} + +fn uwu<const N: u8>() -> impl Traitor<N> { + 1_u32 +} + +fn owo() -> impl Traitor { + 1_u64 +} + +fn main() { + rawr::<3>(); + rawr::<7>(); + uwu::<{ u8::MAX }>(); + owo(); +} diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs new file mode 100644 index 000000000..80013e7b4 --- /dev/null +++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs @@ -0,0 +1,30 @@ +struct Uwu<const N: u32 = 1, const M: u32 = N>; + +trait Trait {} +impl<const N: u32> Trait for Uwu<N> {} + +fn rawr() -> impl Trait { + //~^ error: the trait bound `Uwu<10, 12>: Trait` is not satisfied + Uwu::<10, 12> +} + +trait Traitor<const N: u8 = 1, const M: u8 = N> {} + +impl<const N: u8> Traitor<N, 2> for u32 {} +impl Traitor<1, 2> for u64 {} + +fn uwu<const N: u8>() -> impl Traitor<N> { + //~^ error: the trait bound `u32: Traitor<N>` is not satisfied + 1_u32 +} + +fn owo() -> impl Traitor { + //~^ error: the trait bound `u64: Traitor` is not satisfied + 1_u64 +} + +fn main() { + rawr(); + uwu(); + owo(); +} diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr new file mode 100644 index 000000000..f2e7777ce --- /dev/null +++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr @@ -0,0 +1,40 @@ +error[E0277]: the trait bound `Uwu<10, 12>: Trait` is not satisfied + --> $DIR/rp_impl_trait_fail.rs:6:14 + | +LL | fn rawr() -> impl Trait { + | ^^^^^^^^^^ the trait `Trait` is not implemented for `Uwu<10, 12>` +LL | +LL | Uwu::<10, 12> + | ------------- return type was inferred to be `Uwu<10, 12>` here + | + = help: the trait `Trait` is implemented for `Uwu<N>` + +error[E0277]: the trait bound `u32: Traitor<N>` is not satisfied + --> $DIR/rp_impl_trait_fail.rs:16:26 + | +LL | fn uwu<const N: u8>() -> impl Traitor<N> { + | ^^^^^^^^^^^^^^^ the trait `Traitor<N>` is not implemented for `u32` +LL | +LL | 1_u32 + | ----- return type was inferred to be `u32` here + | + = help: the following other types implement trait `Traitor<N, M>`: + <u32 as Traitor<N, 2>> + <u64 as Traitor<1, 2>> + +error[E0277]: the trait bound `u64: Traitor` is not satisfied + --> $DIR/rp_impl_trait_fail.rs:21:13 + | +LL | fn owo() -> impl Traitor { + | ^^^^^^^^^^^^ the trait `Traitor` is not implemented for `u64` +LL | +LL | 1_u64 + | ----- return type was inferred to be `u64` here + | + = help: the following other types implement trait `Traitor<N, M>`: + <u32 as Traitor<N, 2>> + <u64 as Traitor<1, 2>> + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/defaults/simple-defaults.rs b/src/test/ui/const-generics/defaults/simple-defaults.rs new file mode 100644 index 000000000..6a782d223 --- /dev/null +++ b/src/test/ui/const-generics/defaults/simple-defaults.rs @@ -0,0 +1,13 @@ +// run-pass +// Checks that type param defaults are allowed after const params. +#![allow(dead_code)] + +struct FixedOutput<'a, const N: usize, T=u32> { + out: &'a [T; N], +} + +trait FixedOutputter { + fn out(&self) -> FixedOutput<'_, 10>; +} + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/trait_object_lt_defaults.rs b/src/test/ui/const-generics/defaults/trait_object_lt_defaults.rs new file mode 100644 index 000000000..a1828727e --- /dev/null +++ b/src/test/ui/const-generics/defaults/trait_object_lt_defaults.rs @@ -0,0 +1,24 @@ +// aux-build:trait_object_lt_defaults_lib.rs +// run-pass +#![allow(dead_code)] +extern crate trait_object_lt_defaults_lib; + +// Tests that `A<'a, 3, dyn Test>` is short for `A<'a, 3, dyn Test + 'a>` +// and `Foo<'a, 3, dyn Test>` is short for `Foo<'a, 3, dyn Test + 'a>` +// Test is in `const-generics/defaults` because it relies on param ordering + +trait Test {} + +struct A<'a, const N: usize, T: ?Sized + 'a>(&'a T, [(); N]); +fn blah<'a>(mut a: A<'a, 3, dyn Test>, arg: &'a (dyn Test + 'a)) { + a.0 = arg; +} + +fn other_blah<'a>( + mut a: trait_object_lt_defaults_lib::Foo<'a, 3, dyn Test>, + arg: &'a (dyn Test + 'a), +) { + a.0 = arg; +} + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/trait_objects.rs b/src/test/ui/const-generics/defaults/trait_objects.rs new file mode 100644 index 000000000..750e40313 --- /dev/null +++ b/src/test/ui/const-generics/defaults/trait_objects.rs @@ -0,0 +1,43 @@ +// run-pass +trait Trait<const N: u8 = 12> { + fn uwu(&self) -> u8 { + N + } +} + +impl Trait for u32 {} + +impl Trait<12> for u64 { + fn uwu(&self) -> u8 { + *self as u8 + } +} + +fn foo(arg: &dyn Trait) -> u8 { + arg.uwu() +} + +trait Traitor<const N: u8 = 1, const M: u8 = N> { + fn owo(&self) -> u8 { + M + } +} + +impl Traitor<2> for bool { } +impl Traitor for u8 { + fn owo(&self) -> u8 { + *self + } +} + +fn bar<const N: u8>(arg: &dyn Traitor<N>) -> u8 { + arg.owo() +} + +fn main() { + assert_eq!(foo(&10_u32), 12); + assert_eq!(foo(&3_u64), 3); + + assert_eq!(bar(&true), 2); + assert_eq!(bar(&1_u8), 1); +} diff --git a/src/test/ui/const-generics/defaults/trait_objects_fail.rs b/src/test/ui/const-generics/defaults/trait_objects_fail.rs new file mode 100644 index 000000000..6ab803f99 --- /dev/null +++ b/src/test/ui/const-generics/defaults/trait_objects_fail.rs @@ -0,0 +1,30 @@ +trait Trait<const N: u8 = 12> { + fn uwu(&self) -> u8 { + N + } +} + +impl Trait<2> for u32 {} + +fn foo(arg: &dyn Trait) -> u8 { + arg.uwu() +} + +trait Traitor<const N: u8 = 1, const M: u8 = N> { + fn owo(&self) -> u8 { + M + } +} + +impl Traitor<2, 3> for bool {} + +fn bar<const N: u8>(arg: &dyn Traitor<N>) -> u8 { + arg.owo() +} + +fn main() { + foo(&10_u32); + //~^ error: the trait bound `u32: Trait` is not satisfied + bar(&true); + //~^ error: the trait bound `bool: Traitor<_>` is not satisfied +} diff --git a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr new file mode 100644 index 000000000..a9c185e5f --- /dev/null +++ b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr @@ -0,0 +1,25 @@ +error[E0277]: the trait bound `u32: Trait` is not satisfied + --> $DIR/trait_objects_fail.rs:26:9 + | +LL | foo(&10_u32); + | --- ^^^^^^^ the trait `Trait` is not implemented for `u32` + | | + | required by a bound introduced by this call + | + = help: the trait `Trait<2>` is implemented for `u32` + = note: required for the cast from `u32` to the object type `dyn Trait` + +error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied + --> $DIR/trait_objects_fail.rs:28:9 + | +LL | bar(&true); + | --- ^^^^^ the trait `Traitor<_>` is not implemented for `bool` + | | + | required by a bound introduced by this call + | + = help: the trait `Traitor<2, 3>` is implemented for `bool` + = note: required for the cast from `bool` to the object type `dyn Traitor<_>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/defaults/type-default-const-param-name.rs b/src/test/ui/const-generics/defaults/type-default-const-param-name.rs new file mode 100644 index 000000000..405664ded --- /dev/null +++ b/src/test/ui/const-generics/defaults/type-default-const-param-name.rs @@ -0,0 +1,14 @@ +// check-pass +struct N; + +struct Foo<const N: usize = 1, T = N>(T); + +impl Foo { + fn new() -> Self { + Foo(N) + } +} + +fn main() { + let Foo::<1, N>(N) = Foo::new(); +} diff --git a/src/test/ui/const-generics/defaults/wfness.rs b/src/test/ui/const-generics/defaults/wfness.rs new file mode 100644 index 000000000..a93f67081 --- /dev/null +++ b/src/test/ui/const-generics/defaults/wfness.rs @@ -0,0 +1,23 @@ +struct Ooopsies<const N: u8 = { u8::MAX + 1 }>; +//~^ error: evaluation of constant value failed + +trait Trait<const N: u8> {} +impl Trait<3> for () {} +struct WhereClause<const N: u8 = 2> +where + (): Trait<N>; +//~^ error: the trait bound `(): Trait<2>` is not satisfied + +trait Traitor<T, const N: u8> {} +struct WhereClauseTooGeneric<T = u32, const N: u8 = 2>(T) +where + (): Traitor<T, N>; + +// no error on struct def +struct DependentDefaultWfness<const N: u8 = 1, T = WhereClause<N>>(T); +fn foo() -> DependentDefaultWfness { + //~^ error: the trait bound `(): Trait<1>` is not satisfied + loop {} +} + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/wfness.stderr b/src/test/ui/const-generics/defaults/wfness.stderr new file mode 100644 index 000000000..25038f830 --- /dev/null +++ b/src/test/ui/const-generics/defaults/wfness.stderr @@ -0,0 +1,34 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/wfness.rs:1:33 + | +LL | struct Ooopsies<const N: u8 = { u8::MAX + 1 }>; + | ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow + +error[E0277]: the trait bound `(): Trait<2>` is not satisfied + --> $DIR/wfness.rs:8:9 + | +LL | (): Trait<N>; + | ^^^^^^^^ the trait `Trait<2>` is not implemented for `()` + | + = help: the trait `Trait<3>` is implemented for `()` + +error[E0277]: the trait bound `(): Trait<1>` is not satisfied + --> $DIR/wfness.rs:18:13 + | +LL | fn foo() -> DependentDefaultWfness { + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<1>` is not implemented for `()` + | + = help: the trait `Trait<3>` is implemented for `()` +note: required by a bound in `WhereClause` + --> $DIR/wfness.rs:8:9 + | +LL | struct WhereClause<const N: u8 = 2> + | ----------- required by a bound in this +LL | where +LL | (): Trait<N>; + | ^^^^^^^^ required by this bound in `WhereClause` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0080, E0277. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-generics/defaults/wrong-order.rs b/src/test/ui/const-generics/defaults/wrong-order.rs new file mode 100644 index 000000000..d53d56f41 --- /dev/null +++ b/src/test/ui/const-generics/defaults/wrong-order.rs @@ -0,0 +1,9 @@ +struct A<T = u32, const N: usize> { + //~^ ERROR generic parameters with a default must be trailing + arg: T, +} + +struct Foo<const N: u8 = 3, T>(T); +//~^ error: generic parameters with a default must be trailing + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/wrong-order.stderr b/src/test/ui/const-generics/defaults/wrong-order.stderr new file mode 100644 index 000000000..4d2628d03 --- /dev/null +++ b/src/test/ui/const-generics/defaults/wrong-order.stderr @@ -0,0 +1,14 @@ +error: generic parameters with a default must be trailing + --> $DIR/wrong-order.rs:1:10 + | +LL | struct A<T = u32, const N: usize> { + | ^ + +error: generic parameters with a default must be trailing + --> $DIR/wrong-order.rs:6:18 + | +LL | struct Foo<const N: u8 = 3, T>(T); + | ^ + +error: aborting due to 2 previous errors + |