Skip to content

Instantly share code, notes, and snippets.

@jackd
Created March 4, 2026 22:53
Show Gist options
  • Select an option

  • Save jackd/b0246ef9dedf843d34efed873ff8b8fc to your computer and use it in GitHub Desktop.

Select an option

Save jackd/b0246ef9dedf843d34efed873ff8b8fc to your computer and use it in GitHub Desktop.
Generic type inference bug report: cast type parameters reversed, type inference fails
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