Created
March 4, 2026 22:53
-
-
Save jackd/b0246ef9dedf843d34efed873ff8b8fc to your computer and use it in GitHub Desktop.
Generic type inference bug report: cast type parameters reversed, type inference fails
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| enum DType<T extends num> { int64<int>(), float64<double>() } | |
| class Tensor<DT extends DType<T>, T extends num> { | |
| final List<T> values; | |
| final DT dtype; | |
| final Object shape; | |
| const Tensor(this.values, this.dtype, this.shape); | |
| Tensor<DT2, T2> castSwitchedFunc<T2 extends num, DT2 extends DType<T2>>( | |
| DT2 dtype2, | |
| ) { | |
| final converter = | |
| switch (dtype2) { | |
| DType.int64 => (num v) => v.toInt(), | |
| DType.float64 => (num v) => v.toDouble(), | |
| } | |
| as T2 Function(num); | |
| return Tensor(values.map(converter).toList(), dtype2, shape); | |
| } | |
| Tensor<DT2, T2> castSwitchedList<T2 extends num, DT2 extends DType<T2>>( | |
| DT2 dtype2, | |
| ) { | |
| final vs = | |
| switch (dtype2) { | |
| DType.int64 => values.map((num v) => v.toInt()).toList(), | |
| DType.float64 => values.map((num v) => v.toDouble()).toList(), | |
| } | |
| as List<T2>; | |
| return Tensor(vs, dtype2, shape); | |
| } | |
| Tensor<DT2, T2> castSwitchedRecord<T2 extends num, DT2 extends DType<T2>>( | |
| DT2 dtype2, | |
| ) { | |
| final ( | |
| vs, | |
| dt2, | |
| ) = switch (dtype2) { | |
| DType.int64 => (values.map((v) => v.toInt()).toList(), DType.int64), | |
| DType.float64 => ( | |
| values.map((v) => v.toDouble()).toList(), | |
| DType.float64, | |
| ), | |
| } | |
| as (List<T2>, DT2); | |
| return Tensor(vs, dtype2, shape); | |
| } | |
| Tensor<DT2, T2> castSwitchedTensor<T2 extends num, DT2 extends DType<T2>>( | |
| DT2 dtype2, | |
| ) { | |
| return switch (dtype2) { | |
| DType.int64 => Tensor( | |
| values.map((v) => v.toInt()).toList(), | |
| DType.int64, | |
| shape, | |
| ), | |
| DType.float64 => Tensor( | |
| values.map((v) => v.toDouble()).toList(), | |
| DType.float64, | |
| shape, | |
| ), | |
| } | |
| as Tensor<DT2, T2>; | |
| } | |
| } | |
| void main() { | |
| const i64 = Tensor([0], DType.int64, 'square'); | |
| for (final (result, name) in [ | |
| (i64.castSwitchedFunc(DType.float64), 'castSwitchedFunc'), | |
| (i64.castSwitchedList(DType.float64), 'castSwitchedList'), | |
| (i64.castSwitchedRecord(DType.float64), 'castSwitchedRecord'), | |
| (i64.castSwitchedTensor(DType.float64), 'castSwitchedTensor'), | |
| ]) { | |
| if (result is Tensor<DType<double>, double>) { | |
| print('$name passed'); | |
| } else { | |
| print('$name FAILED'); | |
| } | |
| final Tensor<DType<double>, double> r = i64.castSwitchedFunc( | |
| DType.float64, | |
| ); | |
| print('Assignment successful'); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment