| 
 | 1 | +// Regression test for #66768.  | 
 | 2 | +// check-pass  | 
 | 3 | +#![allow(dead_code)]  | 
 | 4 | +//-^ "dead code" is needed to reproduce the issue.  | 
 | 5 | + | 
 | 6 | +use std::marker::PhantomData;  | 
 | 7 | +use std::ops::{Add, Mul};  | 
 | 8 | + | 
 | 9 | +fn problematic_function<Space>(material_surface_element: Edge2dElement)  | 
 | 10 | +where  | 
 | 11 | +    DefaultAllocator: FiniteElementAllocator<DimU1, Space>,  | 
 | 12 | +{  | 
 | 13 | +    let _: Point2<f64> = material_surface_element.map_reference_coords().into();  | 
 | 14 | +}  | 
 | 15 | + | 
 | 16 | +impl<T> ArrayLength<T> for UTerm {  | 
 | 17 | +    type ArrayType = ();  | 
 | 18 | +}  | 
 | 19 | +impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {  | 
 | 20 | +    type ArrayType = GenericArrayImplEven<T, N>;  | 
 | 21 | +}  | 
 | 22 | +impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {  | 
 | 23 | +    type ArrayType = GenericArrayImplOdd<T, N>;  | 
 | 24 | +}  | 
 | 25 | +impl<U> Add<U> for UTerm {  | 
 | 26 | +    type Output = U;  | 
 | 27 | +    fn add(self, _: U) -> Self::Output {  | 
 | 28 | +        unimplemented!()  | 
 | 29 | +    }  | 
 | 30 | +}  | 
 | 31 | +impl<Ul, Ur> Add<UInt<Ur, B1>> for UInt<Ul, B0>  | 
 | 32 | +where  | 
 | 33 | +    Ul: Add<Ur>,  | 
 | 34 | +{  | 
 | 35 | +    type Output = UInt<Sum<Ul, Ur>, B1>;  | 
 | 36 | +    fn add(self, _: UInt<Ur, B1>) -> Self::Output {  | 
 | 37 | +        unimplemented!()  | 
 | 38 | +    }  | 
 | 39 | +}  | 
 | 40 | +impl<U> Mul<U> for UTerm {  | 
 | 41 | +    type Output = UTerm;  | 
 | 42 | +    fn mul(self, _: U) -> Self {  | 
 | 43 | +        unimplemented!()  | 
 | 44 | +    }  | 
 | 45 | +}  | 
 | 46 | +impl<Ul, B, Ur> Mul<UInt<Ur, B>> for UInt<Ul, B0>  | 
 | 47 | +where  | 
 | 48 | +    Ul: Mul<UInt<Ur, B>>,  | 
 | 49 | +{  | 
 | 50 | +    type Output = UInt<Prod<Ul, UInt<Ur, B>>, B0>;  | 
 | 51 | +    fn mul(self, _: UInt<Ur, B>) -> Self::Output {  | 
 | 52 | +        unimplemented!()  | 
 | 53 | +    }  | 
 | 54 | +}  | 
 | 55 | +impl<Ul, B, Ur> Mul<UInt<Ur, B>> for UInt<Ul, B1>  | 
 | 56 | +where  | 
 | 57 | +    Ul: Mul<UInt<Ur, B>>,  | 
 | 58 | +    UInt<Prod<Ul, UInt<Ur, B>>, B0>: Add<UInt<Ur, B>>,  | 
 | 59 | +{  | 
 | 60 | +    type Output = Sum<UInt<Prod<Ul, UInt<Ur, B>>, B0>, UInt<Ur, B>>;  | 
 | 61 | +    fn mul(self, _: UInt<Ur, B>) -> Self::Output {  | 
 | 62 | +        unimplemented!()  | 
 | 63 | +    }  | 
 | 64 | +}  | 
 | 65 | +impl<N, R, C> Allocator<N, R, C> for DefaultAllocator  | 
 | 66 | +where  | 
 | 67 | +    R: DimName,  | 
 | 68 | +    C: DimName,  | 
 | 69 | +    R::Value: Mul<C::Value>,  | 
 | 70 | +    Prod<R::Value, C::Value>: ArrayLength<N>,  | 
 | 71 | +{  | 
 | 72 | +    type Buffer = ArrayStorage<N, R, C>;  | 
 | 73 | +    fn allocate_uninitialized(_: R, _: C) -> Self::Buffer {  | 
 | 74 | +        unimplemented!()  | 
 | 75 | +    }  | 
 | 76 | +    fn allocate_from_iterator<I>(_: R, _: C, _: I) -> Self::Buffer {  | 
 | 77 | +        unimplemented!()  | 
 | 78 | +    }  | 
 | 79 | +}  | 
 | 80 | +impl<N, C> Allocator<N, Dynamic, C> for DefaultAllocator {  | 
 | 81 | +    type Buffer = VecStorage<N, Dynamic, C>;  | 
 | 82 | +    fn allocate_uninitialized(_: Dynamic, _: C) -> Self::Buffer {  | 
 | 83 | +        unimplemented!()  | 
 | 84 | +    }  | 
 | 85 | +    fn allocate_from_iterator<I>(_: Dynamic, _: C, _: I) -> Self::Buffer {  | 
 | 86 | +        unimplemented!()  | 
 | 87 | +    }  | 
 | 88 | +}  | 
 | 89 | +impl DimName for DimU1 {  | 
 | 90 | +    type Value = U1;  | 
 | 91 | +    fn name() -> Self {  | 
 | 92 | +        unimplemented!()  | 
 | 93 | +    }  | 
 | 94 | +}  | 
 | 95 | +impl DimName for DimU2 {  | 
 | 96 | +    type Value = U2;  | 
 | 97 | +    fn name() -> Self {  | 
 | 98 | +        unimplemented!()  | 
 | 99 | +    }  | 
 | 100 | +}  | 
 | 101 | +impl<N, D> From<VectorN<N, D>> for Point<N, D>  | 
 | 102 | +where  | 
 | 103 | +    DefaultAllocator: Allocator<N, D>,  | 
 | 104 | +{  | 
 | 105 | +    fn from(_: VectorN<N, D>) -> Self {  | 
 | 106 | +        unimplemented!()  | 
 | 107 | +    }  | 
 | 108 | +}  | 
 | 109 | +impl<GeometryDim, NodalDim> FiniteElementAllocator<GeometryDim, NodalDim> for DefaultAllocator where  | 
 | 110 | +    DefaultAllocator: Allocator<f64, GeometryDim> + Allocator<f64, NodalDim>  | 
 | 111 | +{  | 
 | 112 | +}  | 
 | 113 | +impl ReferenceFiniteElement for Edge2dElement {  | 
 | 114 | +    type NodalDim = DimU1;  | 
 | 115 | +}  | 
 | 116 | +impl FiniteElement<DimU2> for Edge2dElement {  | 
 | 117 | +    fn map_reference_coords(&self) -> Vector2<f64> {  | 
 | 118 | +        unimplemented!()  | 
 | 119 | +    }  | 
 | 120 | +}  | 
 | 121 | + | 
 | 122 | +type Owned<N, R, C> = <DefaultAllocator as Allocator<N, R, C>>::Buffer;  | 
 | 123 | +type MatrixMN<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;  | 
 | 124 | +type VectorN<N, D> = MatrixMN<N, D, DimU1>;  | 
 | 125 | +type Vector2<N> = VectorN<N, DimU2>;  | 
 | 126 | +type Point2<N> = Point<N, DimU2>;  | 
 | 127 | +type U1 = UInt<UTerm, B1>;  | 
 | 128 | +type U2 = UInt<UInt<UTerm, B1>, B0>;  | 
 | 129 | +type Sum<A, B> = <A as Add<B>>::Output;  | 
 | 130 | +type Prod<A, B> = <A as Mul<B>>::Output;  | 
 | 131 | + | 
 | 132 | +struct GenericArray<T, U: ArrayLength<T>> {  | 
 | 133 | +    _data: U::ArrayType,  | 
 | 134 | +}  | 
 | 135 | +struct GenericArrayImplEven<T, U> {  | 
 | 136 | +    _parent2: U,  | 
 | 137 | +    _marker: T,  | 
 | 138 | +}  | 
 | 139 | +struct GenericArrayImplOdd<T, U> {  | 
 | 140 | +    _parent2: U,  | 
 | 141 | +    _data: T,  | 
 | 142 | +}  | 
 | 143 | +struct B0;  | 
 | 144 | +struct B1;  | 
 | 145 | +struct UTerm;  | 
 | 146 | +struct UInt<U, B> {  | 
 | 147 | +    _marker: PhantomData<(U, B)>,  | 
 | 148 | +}  | 
 | 149 | +struct DefaultAllocator;  | 
 | 150 | +struct Dynamic;  | 
 | 151 | +struct DimU1;  | 
 | 152 | +struct DimU2;  | 
 | 153 | +struct Matrix<N, R, C, S> {  | 
 | 154 | +    _data: S,  | 
 | 155 | +    _phantoms: PhantomData<(N, R, C)>,  | 
 | 156 | +}  | 
 | 157 | +struct ArrayStorage<N, R, C>  | 
 | 158 | +where  | 
 | 159 | +    R: DimName,  | 
 | 160 | +    C: DimName,  | 
 | 161 | +    R::Value: Mul<C::Value>,  | 
 | 162 | +    Prod<R::Value, C::Value>: ArrayLength<N>,  | 
 | 163 | +{  | 
 | 164 | +    _data: GenericArray<N, Prod<R::Value, C::Value>>,  | 
 | 165 | +}  | 
 | 166 | +struct VecStorage<N, R, C> {  | 
 | 167 | +    _data: N,  | 
 | 168 | +    _nrows: R,  | 
 | 169 | +    _ncols: C,  | 
 | 170 | +}  | 
 | 171 | +struct Point<N, D>  | 
 | 172 | +where  | 
 | 173 | +    DefaultAllocator: Allocator<N, D>,  | 
 | 174 | +{  | 
 | 175 | +    _coords: VectorN<N, D>,  | 
 | 176 | +}  | 
 | 177 | +struct Edge2dElement;  | 
 | 178 | + | 
 | 179 | +trait ArrayLength<T> {  | 
 | 180 | +    type ArrayType;  | 
 | 181 | +}  | 
 | 182 | +trait Allocator<Scalar, R, C = DimU1> {  | 
 | 183 | +    type Buffer;  | 
 | 184 | +    fn allocate_uninitialized(nrows: R, ncols: C) -> Self::Buffer;  | 
 | 185 | +    fn allocate_from_iterator<I>(nrows: R, ncols: C, iter: I) -> Self::Buffer;  | 
 | 186 | +}  | 
 | 187 | +trait DimName {  | 
 | 188 | +    type Value;  | 
 | 189 | +    fn name() -> Self;  | 
 | 190 | +}  | 
 | 191 | +trait FiniteElementAllocator<GeometryDim, NodalDim>:  | 
 | 192 | +    Allocator<f64, GeometryDim> + Allocator<f64, NodalDim>  | 
 | 193 | +{  | 
 | 194 | +}  | 
 | 195 | +trait ReferenceFiniteElement {  | 
 | 196 | +    type NodalDim;  | 
 | 197 | +}  | 
 | 198 | +trait FiniteElement<GeometryDim>: ReferenceFiniteElement  | 
 | 199 | +where  | 
 | 200 | +    DefaultAllocator: FiniteElementAllocator<GeometryDim, Self::NodalDim>,  | 
 | 201 | +{  | 
 | 202 | +    fn map_reference_coords(&self) -> VectorN<f64, GeometryDim>;  | 
 | 203 | +}  | 
 | 204 | + | 
 | 205 | +fn main() {}  | 
0 commit comments