Sdk: Infer generics in `is` check for type promotion

Created on 28 Jul 2018  路  4Comments  路  Source: dart-lang/sdk

Consider following code:

abstract class A<T> {}
abstract class B<T> implements A<T> {
  b();
}

void foo<T>(A<T> a) {
  if (a is B) {
    return a.b();
  }
}

It gives error message:

// The method 'b' isn't defined for the class 'A'.

so it seems the type promotion on a didn't happen inside the if block. To fix this I can change the condition to be: if (a is B<T>).

This somewhat makes sense, but it seems to me that in this case compiler could infer that B must be B<T>, if it's casted from A<T>. I guess it could be some subclass of T, but that would still be substitutable for B. Or maybe there are some other edge cases in general. If this is not possible then maybe compiler could give some hint why type promotion didn't happen?

area-language core-l type-enhancement

Most helpful comment

Interesting idea, worth considering in for future type promotion improvements.

All 4 comments

Interesting idea, worth considering in for future type promotion improvements.

I don't think this belongs to core-l; it's a language request, correct?

I just ran into a similar issue:

abstract class I {
    int get value;
}

class X extends Route<dynamic> implements I {
  final value = 3;
}

void foo(Route a) {
    if (a is I) {
        print('${a.value}'); // Error: undefined_getter
    }
}

It also seem to be related to the fact that Route (from Flutter) has a generic type argument.

Is this the same underlying issue or should I file a new one?

Sorry, @tp I think this is unrelated.

In your example, Route is unrelated to I, so you the programmer know that the type of a, inside your if body, is Route & I, but there is no concrete type that represents that intersection, so no type promotion is performed. I think https://github.com/dart-lang/sdk/issues/35314 is related to your request.

Was this page helpful?
0 / 5 - 0 ratings