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/const-generics/type-dependent | |
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 'src/test/ui/const-generics/type-dependent')
22 files changed, 487 insertions, 0 deletions
diff --git a/src/test/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs b/src/test/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs new file mode 100644 index 000000000..5dfcbba0e --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs @@ -0,0 +1,33 @@ +pub struct Struct<const N: usize>(()); + +impl<const N: usize> Struct<N> { + pub fn new() -> Self { + Struct(()) + } + + pub fn same_ty<const M: usize>(&self) -> (usize, usize) { + (N, M) + } + + pub fn different_ty<const M: u8>(&self) -> (usize, u8) { + (N, M) + } + + pub fn containing_ty<T, const M: u8>(&self) -> (usize, u8) { + (std::mem::size_of::<T>() + N, M) + } + + pub fn we_have_to_go_deeper<const M: usize>(&self) -> Struct<M> { + Struct(()) + } +} + +pub trait Foo { + fn foo<const M: usize>(&self) -> usize; +} + +impl Foo for Struct<7> { + fn foo<const M: usize>(&self) -> usize { + M + } +} diff --git a/src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs b/src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs new file mode 100644 index 000000000..e84414834 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs @@ -0,0 +1,26 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, feature(generic_const_exprs))] +#![allow(incomplete_features)] + +struct Foo; + +impl Foo { + fn foo<const N: usize>(&self) -> usize { + let f = self; + f.bar::<{ + let f = Foo; + f.bar::<7>() + }>() + N + } + + const fn bar<const M: usize>(&self) -> usize { + M + } +} + +fn main() { + let f = Foo; + + assert_eq!(f.foo::<13>(), 20) +} diff --git a/src/test/ui/const-generics/type-dependent/issue-61936.rs b/src/test/ui/const-generics/type-dependent/issue-61936.rs new file mode 100644 index 000000000..7216b25f0 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-61936.rs @@ -0,0 +1,47 @@ +// run-pass + +trait SliceExt<T: Clone> { + fn array_windows_example<'a, const N: usize>(&'a self) -> ArrayWindowsExample<'a, T, N>; +} + +impl <T: Clone> SliceExt<T> for [T] { + fn array_windows_example<'a, const N: usize>(&'a self) -> ArrayWindowsExample<'a, T, N> { + ArrayWindowsExample{ idx: 0, slice: &self } + } +} + +struct ArrayWindowsExample<'a, T, const N: usize> { + slice: &'a [T], + idx: usize, +} + +impl <'a, T: Clone, const N: usize> Iterator for ArrayWindowsExample<'a, T, N> { + type Item = [T; N]; + fn next(&mut self) -> Option<Self::Item> { + // Note: this is unsound for some `T` and not meant as an example + // on how to implement `ArrayWindows`. + let mut res = unsafe{ std::mem::zeroed() }; + let mut ptr = &mut res as *mut [T; N] as *mut T; + + for i in 0..N { + match self.slice[self.idx..].get(i) { + None => return None, + Some(elem) => unsafe { std::ptr::write_volatile(ptr, elem.clone())}, + }; + ptr = ptr.wrapping_add(1); + self.idx += 1; + } + + Some(res) + } +} + +const FOUR: usize = 4; + +fn main() { + let v: Vec<usize> = vec![0; 100]; + + for array in v.as_slice().array_windows_example::<FOUR>() { + assert_eq!(array, [0, 0, 0, 0]) + } +} diff --git a/src/test/ui/const-generics/type-dependent/issue-63695.rs b/src/test/ui/const-generics/type-dependent/issue-63695.rs new file mode 100644 index 000000000..08b6d4bf5 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-63695.rs @@ -0,0 +1,15 @@ +// run-pass + +trait T { + fn test<const A: i32>(&self) -> i32 { A } +} + +struct S(); + +impl T for S {} + +fn main() { + let foo = S(); + assert_eq!(foo.test::<8i32>(), 8); + assert_eq!(foo.test::<16i32>(), 16); +} diff --git a/src/test/ui/const-generics/type-dependent/issue-67144-1.rs b/src/test/ui/const-generics/type-dependent/issue-67144-1.rs new file mode 100644 index 000000000..27dd51de2 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-67144-1.rs @@ -0,0 +1,25 @@ +// check-pass +struct X; + +impl X { + pub fn getn<const N: usize>(&self) -> [u8; N] { + getn::<N>() + } +} + +fn getn<const N: usize>() -> [u8; N] { + unsafe { + std::mem::zeroed() + } +} + +fn main() { + // works + let [a,b,c] = getn::<3>(); + + // cannot pattern-match on an array without a fixed length + let [a,b,c] = X.getn::<3>(); + + // mismatched types, expected array `[u8; 3]` found array `[u8; _]` + let arr: [u8; 3] = X.getn::<3>(); +} diff --git a/src/test/ui/const-generics/type-dependent/issue-67144-2.rs b/src/test/ui/const-generics/type-dependent/issue-67144-2.rs new file mode 100644 index 000000000..b26f551eb --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-67144-2.rs @@ -0,0 +1,19 @@ +// check-pass +struct A<const N: usize>; + +struct X; + +impl X { + fn inner<const N: usize>() -> A<N> { + outer::<N>() + } +} + +fn outer<const N: usize>() -> A<N> { + A +} + +fn main() { + let i: A<3usize> = outer::<3usize>(); + let o: A<3usize> = X::inner::<3usize>(); +} diff --git a/src/test/ui/const-generics/type-dependent/issue-69816.rs b/src/test/ui/const-generics/type-dependent/issue-69816.rs new file mode 100644 index 000000000..cbb6b398e --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-69816.rs @@ -0,0 +1,17 @@ +// run-pass +trait IterExt: Sized + Iterator { + fn default_for_size<const N: usize>(self) -> [Self::Item; N] + where + [Self::Item; N]: Default, + { + Default::default() + } +} + +impl<T: Iterator> IterExt for T {} + +fn main(){ + const N: usize = 10; + let arr = (0u32..10).default_for_size::<N>(); + assert_eq!(arr, [0; 10]); +} diff --git a/src/test/ui/const-generics/type-dependent/issue-70217.rs b/src/test/ui/const-generics/type-dependent/issue-70217.rs new file mode 100644 index 000000000..933ca0276 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-70217.rs @@ -0,0 +1,14 @@ +// check-pass + +struct Struct<const N: usize>; + +impl<const N: usize> Struct<N> { + fn method<const M: usize>(&self) {} +} + +fn test<const N: usize, const M: usize>(x: Struct<N>) { + Struct::<N>::method::<M>(&x); + x.method::<N>(); +} + +fn main() {} diff --git a/src/test/ui/const-generics/type-dependent/issue-70507.rs b/src/test/ui/const-generics/type-dependent/issue-70507.rs new file mode 100644 index 000000000..c72d9fbec --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-70507.rs @@ -0,0 +1,45 @@ +// run-pass + +trait ConstChunksExactTrait<T> { + fn const_chunks_exact<const N: usize>(&self) -> ConstChunksExact<'_, T, {N}>; +} + +impl <T> ConstChunksExactTrait<T> for [T] { + fn const_chunks_exact<const N: usize>(&self) -> ConstChunksExact<'_, T, {N}> { + assert!(N != 0); + let rem = self.len() % N; + let len = self.len() - rem; + let (fst, _) = self.split_at(len); + ConstChunksExact { v: fst, } + } +} + +struct ConstChunksExact<'a, T: 'a, const N: usize> { + v: &'a [T], +} + +impl <'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {N}> { + type Item = &'a [T; N]; + + fn next(&mut self) -> Option<Self::Item> { + if self.v.len() < N { + None + } else { + let (fst, snd) = self.v.split_at(N); + + self.v = snd; + let ptr = fst.as_ptr() as *const _; + Some(unsafe { &*ptr}) + } + } +} + +fn main() { + let slice = &[1i32, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + let mut iter = [[1, 2, 3], [4, 5, 6], [7, 8, 9]].iter(); + + for a in slice.const_chunks_exact::<3>() { + assert_eq!(a, iter.next().unwrap()); + } +} diff --git a/src/test/ui/const-generics/type-dependent/issue-70586.rs b/src/test/ui/const-generics/type-dependent/issue-70586.rs new file mode 100644 index 000000000..346ac4b72 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-70586.rs @@ -0,0 +1,30 @@ +// check-pass +use std::marker::PhantomData; + +// This namespace is necessary for the ICE to trigger +struct Namespace; + +impl Namespace { + pub fn const_chunks_exact<T, const N: usize>() -> ConstChunksExact<'static, T, N> { + ConstChunksExact { inner: PhantomData } + } +} + + +#[derive(Debug)] +pub struct ConstChunksExact<'a, T, const N: usize> { + inner: PhantomData<&'a T> +} + +impl <'a, T, const N: usize> Iterator for ConstChunksExact<'a, T, { N }> { + type Item = &'a [T; N]; + + fn next(&mut self) -> Option<Self::Item> { + unreachable!() + } +} + +fn main() { + let mut chunks = Namespace::const_chunks_exact::<i32, 3usize>(); + let _next: &[i32; 3] = chunks.next().unwrap(); +} diff --git a/src/test/ui/const-generics/type-dependent/issue-71348.min.stderr b/src/test/ui/const-generics/type-dependent/issue-71348.min.stderr new file mode 100644 index 000000000..b8fbb3979 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-71348.min.stderr @@ -0,0 +1,20 @@ +error: `&'static str` is forbidden as the type of a const generic parameter + --> $DIR/issue-71348.rs:10:24 + | +LL | trait Get<'a, const N: &'static str> { + | ^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: more complex types are supported with `#![feature(adt_const_params)]` + +error: `&'static str` is forbidden as the type of a const generic parameter + --> $DIR/issue-71348.rs:18:25 + | +LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target + | ^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: more complex types are supported with `#![feature(adt_const_params)]` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-generics/type-dependent/issue-71348.rs b/src/test/ui/const-generics/type-dependent/issue-71348.rs new file mode 100644 index 000000000..2ef2f066a --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-71348.rs @@ -0,0 +1,38 @@ +// [full] run-pass +// revisions: full min +#![cfg_attr(full, feature(adt_const_params))] +#![cfg_attr(full, allow(incomplete_features))] + +struct Foo { + i: i32, +} + +trait Get<'a, const N: &'static str> { + //[min]~^ ERROR `&'static str` is forbidden as the type of a const generic parameter + type Target: 'a; + + fn get(&'a self) -> &'a Self::Target; +} + +impl Foo { + fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target + //[min]~^ ERROR `&'static str` is forbidden as the type of a const generic parameter + where + Self: Get<'a, N>, + { + self.get() + } +} + +impl<'a> Get<'a, "int"> for Foo { + type Target = i32; + + fn get(&'a self) -> &'a Self::Target { + &self.i + } +} + +fn main() { + let foo = Foo { i: 123 }; + assert_eq!(foo.ask::<"int">(), &123); +} diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.rs b/src/test/ui/const-generics/type-dependent/issue-71382.rs new file mode 100644 index 000000000..1c4073e36 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-71382.rs @@ -0,0 +1,21 @@ +struct Test; + +fn pass() -> u8 { + 42 +} + +impl Test { + pub fn call_me(&self) -> u8 { + self.test::<pass>() + } + + fn test<const FN: fn() -> u8>(&self) -> u8 { + //~^ ERROR using function pointers as const generic parameters is forbidden + FN() + } +} + +fn main() { + let x = Test; + assert_eq!(x.call_me(), 42); +} diff --git a/src/test/ui/const-generics/type-dependent/issue-71382.stderr b/src/test/ui/const-generics/type-dependent/issue-71382.stderr new file mode 100644 index 000000000..ad522aead --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-71382.stderr @@ -0,0 +1,8 @@ +error: using function pointers as const generic parameters is forbidden + --> $DIR/issue-71382.rs:12:23 + | +LL | fn test<const FN: fn() -> u8>(&self) -> u8 { + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/type-dependent/issue-71805.rs b/src/test/ui/const-generics/type-dependent/issue-71805.rs new file mode 100644 index 000000000..060b89964 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-71805.rs @@ -0,0 +1,38 @@ +// run-pass +use std::mem::MaybeUninit; + +trait CollectSlice<'a>: Iterator { + fn inner_array<const N: usize>(&mut self) -> [Self::Item; N]; + + fn collect_array<const N: usize>(&mut self) -> [Self::Item; N] { + let result = self.inner_array(); + assert!(self.next().is_none()); + result + } +} + +impl<'a, I: ?Sized> CollectSlice<'a> for I +where + I: Iterator, +{ + fn inner_array<const N: usize>(&mut self) -> [Self::Item; N] { + let mut result: [MaybeUninit<Self::Item>; N] = + unsafe { MaybeUninit::uninit().assume_init() }; + + let mut count = 0; + for (dest, item) in result.iter_mut().zip(self) { + *dest = MaybeUninit::new(item); + count += 1; + } + + assert_eq!(N, count); + + let temp_ptr: *const [MaybeUninit<Self::Item>; N] = &result; + unsafe { std::ptr::read(temp_ptr as *const [Self::Item; N]) } + } +} + +fn main() { + let mut foos = [0u64; 9].iter().cloned(); + let _bar: [u64; 9] = foos.collect_array::<9_usize>(); +} diff --git a/src/test/ui/const-generics/type-dependent/issue-73730.rs b/src/test/ui/const-generics/type-dependent/issue-73730.rs new file mode 100644 index 000000000..5e1b8c635 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/issue-73730.rs @@ -0,0 +1,14 @@ +// check-pass +trait Foo<'a, A>: Iterator<Item=A> { + fn bar<const N: usize>(&mut self) -> *const [A; N]; +} + +impl<'a, A, I: ?Sized> Foo<'a, A> for I where I: Iterator<Item=A> { + fn bar<const N: usize>(&mut self) -> *const [A; N] { + std::ptr::null() + } +} + +fn main() { + (0_u8 .. 10).bar::<10_usize>(); +} diff --git a/src/test/ui/const-generics/type-dependent/non-local.rs b/src/test/ui/const-generics/type-dependent/non-local.rs new file mode 100644 index 000000000..b755de30b --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/non-local.rs @@ -0,0 +1,21 @@ +// aux-build:type_dependent_lib.rs +// run-pass +extern crate type_dependent_lib; + +use type_dependent_lib::*; + +fn main() { + let s = Struct::<42>::new(); + assert_eq!(s.same_ty::<7>(), (42, 7)); + assert_eq!(s.different_ty::<19>(), (42, 19)); + assert_eq!(Struct::<1337>::new().different_ty::<96>(), (1337, 96)); + assert_eq!( + Struct::<18>::new() + .we_have_to_go_deeper::<19>() + .containing_ty::<Option<u32>, 3>(), + (27, 3), + ); + + let s = Struct::<7>::new(); + assert_eq!(s.foo::<18>(), 18); +} diff --git a/src/test/ui/const-generics/type-dependent/qpath.rs b/src/test/ui/const-generics/type-dependent/qpath.rs new file mode 100644 index 000000000..2d678d0ac --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/qpath.rs @@ -0,0 +1,9 @@ +// run-pass +struct A; +impl A { + fn foo<const N: usize>() -> usize { N + 1 } +} + +fn main() { + assert_eq!(A::foo::<7>(), 8); +} diff --git a/src/test/ui/const-generics/type-dependent/simple.rs b/src/test/ui/const-generics/type-dependent/simple.rs new file mode 100644 index 000000000..1b13133b5 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/simple.rs @@ -0,0 +1,9 @@ +// run-pass +struct R; + +impl R { + fn method<const N: u8>(&self) -> u8 { N } +} +fn main() { + assert_eq!(R.method::<1u8>(), 1); +} diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr b/src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr new file mode 100644 index 000000000..70bc64057 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:8:27 + | +LL | assert_eq!(R.method::<1u16>(), 1); + | ^^^^ expected `u8`, found `u16` + | +help: change the type of the numeric literal from `u16` to `u8` + | +LL | assert_eq!(R.method::<1u8>(), 1); + | ~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr b/src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr new file mode 100644 index 000000000..70bc64057 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:8:27 + | +LL | assert_eq!(R.method::<1u16>(), 1); + | ^^^^ expected `u8`, found `u16` + | +help: change the type of the numeric literal from `u16` to `u8` + | +LL | assert_eq!(R.method::<1u8>(), 1); + | ~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/type-dependent/type-mismatch.rs b/src/test/ui/const-generics/type-dependent/type-mismatch.rs new file mode 100644 index 000000000..3335ab870 --- /dev/null +++ b/src/test/ui/const-generics/type-dependent/type-mismatch.rs @@ -0,0 +1,10 @@ +// revisions: full min +struct R; + +impl R { + fn method<const N: u8>(&self) -> u8 { N } +} +fn main() { + assert_eq!(R.method::<1u16>(), 1); + //~^ ERROR mismatched types +} |