summaryrefslogtreecommitdiffstats
path: root/src/test/ui/const-generics/type-dependent
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/const-generics/type-dependent')
-rw-r--r--src/test/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs33
-rw-r--r--src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs26
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-61936.rs47
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-63695.rs15
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-67144-1.rs25
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-67144-2.rs19
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-69816.rs17
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-70217.rs14
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-70507.rs45
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-70586.rs30
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71348.min.stderr20
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71348.rs38
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71382.rs21
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71382.stderr8
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-71805.rs38
-rw-r--r--src/test/ui/const-generics/type-dependent/issue-73730.rs14
-rw-r--r--src/test/ui/const-generics/type-dependent/non-local.rs21
-rw-r--r--src/test/ui/const-generics/type-dependent/qpath.rs9
-rw-r--r--src/test/ui/const-generics/type-dependent/simple.rs9
-rw-r--r--src/test/ui/const-generics/type-dependent/type-mismatch.full.stderr14
-rw-r--r--src/test/ui/const-generics/type-dependent/type-mismatch.min.stderr14
-rw-r--r--src/test/ui/const-generics/type-dependent/type-mismatch.rs10
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
+}