]> git.proxmox.com Git - rustc.git/blob - tests/ui/const-generics/issues/issue-83765.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / tests / ui / const-generics / issues / issue-83765.rs
1 #![feature(generic_const_exprs)]
2 #![allow(incomplete_features)]
3
4 trait TensorDimension {
5 const DIM: usize;
6 //~^ ERROR cycle detected when resolving instance
7 // FIXME Given the current state of the compiler its expected that we cycle here,
8 // but the cycle is still wrong.
9 const ISSCALAR: bool = Self::DIM == 0;
10 fn is_scalar(&self) -> bool {
11 Self::ISSCALAR
12 }
13 }
14
15 trait TensorSize: TensorDimension {
16 fn size(&self) -> [usize; Self::DIM];
17 fn inbounds(&self, index: [usize; Self::DIM]) -> bool {
18 index.iter().zip(self.size().iter()).all(|(i, s)| i < s)
19 }
20 }
21
22 trait Broadcastable: TensorSize + Sized {
23 type Element;
24 fn bget(&self, index: [usize; Self::DIM]) -> Option<Self::Element>;
25 fn lazy_updim<const NEWDIM: usize>(
26 &self,
27 size: [usize; NEWDIM],
28 ) -> LazyUpdim<Self, { Self::DIM }, NEWDIM> {
29 assert!(
30 NEWDIM >= Self::DIM,
31 "Updimmed tensor cannot have fewer indices than the initial one."
32 );
33 LazyUpdim { size, reference: &self }
34 }
35 fn bmap<T, F: Fn(Self::Element) -> T>(&self, foo: F) -> BMap<T, Self, F, { Self::DIM }> {
36 BMap { reference: self, closure: foo }
37 }
38 }
39
40 struct LazyUpdim<'a, T: Broadcastable, const OLDDIM: usize, const DIM: usize> {
41 size: [usize; DIM],
42 reference: &'a T,
43 }
44
45 impl<'a, T: Broadcastable, const DIM: usize> TensorDimension for LazyUpdim<'a, T, { T::DIM }, DIM> {
46 const DIM: usize = DIM;
47 }
48
49 impl<'a, T: Broadcastable, const DIM: usize> TensorSize for LazyUpdim<'a, T, { T::DIM }, DIM> {
50 fn size(&self) -> [usize; DIM] {
51 self.size
52 }
53 }
54
55 impl<'a, T: Broadcastable, const DIM: usize> Broadcastable for LazyUpdim<'a, T, { T::DIM }, DIM> {
56 type Element = T::Element;
57 fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
58 assert!(DIM >= T::DIM);
59 if !self.inbounds(index) {
60 return None;
61 }
62 let size = self.size();
63 let newindex: [usize; T::DIM] = Default::default();
64 self.reference.bget(newindex)
65 }
66 }
67
68 struct BMap<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> {
69 reference: &'a T,
70 closure: F,
71 }
72
73 impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> TensorDimension
74 for BMap<'a, R, T, F, DIM>
75 {
76 const DIM: usize = DIM;
77 }
78 impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> TensorSize
79 for BMap<'a, R, T, F, DIM>
80 {
81 fn size(&self) -> [usize; DIM] {
82 self.reference.size()
83 }
84 }
85
86 impl<'a, R, T: Broadcastable, F: Fn(T::Element) -> R, const DIM: usize> Broadcastable
87 for BMap<'a, R, T, F, DIM>
88 {
89 type Element = R;
90 fn bget(&self, index: [usize; DIM]) -> Option<Self::Element> {
91 self.reference.bget(index).map(&self.closure)
92 }
93 }
94
95 impl<T> TensorDimension for Vec<T> {
96 const DIM: usize = 1;
97 }
98 impl<T> TensorSize for Vec<T> {
99 fn size(&self) -> [usize; 1] {
100 [self.len()]
101 }
102 }
103 impl<T: Clone> Broadcastable for Vec<T> {
104 type Element = T;
105 fn bget(&self, index: [usize; 1]) -> Option<T> {
106 self.get(index[0]).cloned()
107 }
108 }
109
110 fn main() {
111 let v = vec![1, 2, 3];
112 let bv = v.lazy_updim([3, 4]);
113 let bbv = bv.bmap(|x| x * x);
114
115 println!("The size of v is {:?}", bbv.bget([0, 2]).expect("Out of bounds."));
116 }