Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type inference from parameter type #37247

Open
derolf opened this issue Jun 13, 2019 · 2 comments
Open

Type inference from parameter type #37247

derolf opened this issue Jun 13, 2019 · 2 comments
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language).

Comments

@derolf
Copy link

derolf commented Jun 13, 2019

The problem

Consider the following example:

    typedef Action<T> = void Function(T arg);
    
    void execute<T>(T arg, Action<T> action) => action(arg);
    
    void main() {
      execute(42, (value) => print(value.bar));
    }

I would expect the Dart Analyzer to fail at value.bar since T could be inferred to number. Instead, Dart does not infer T to number, but falls back to dynamic.

What are other languages doing?

Equivalent example in TypeScript:

    type Action<T> = (arg: T) => void;
    
    function execute<T>(arg: T, action: Action<T>) {
        return action(arg);
    }
    
    function main() {
      execute(42, (value) => console.log(value.bar));
    }

yields error

Property 'bar' does not exist on type 'number'.

Equivalent example in Kotlin:

    typealias Action<T> = (arg: T) -> Unit;
    
    fun<T> execute(arg: T, action: Action<T>) = action(arg);
    
    fun main() {
      execute(42) { value -> print(value.bar) };
    }

yields error

Unresolved reference: bar

https://stackoverflow.com/questions/56540905/type-inference-from-parameter-type

@eernstg
Copy link
Member

eernstg commented Jun 13, 2019

This is a good example of a case where it would have been very useful for inference to choose int as the parameter type for the function literal, like in Kotlin and TypeScript.

However, when inference has chosen the type argument int for the given invocation of execute then the first parameter is type correct, and so is the second one with parameter type dynamic (because void Function(dynamic) is a subtype of void Function(int)).

In order to address the immediate problem, you could use dartanalyzer --no-implicit-dynamic, which you might prefer anyway. (Just guessing ;-)

For the broader question of why inference did not give the parameter value the type int, I believe this is an instance of https://github.com/dart-lang/sdk/issues/25490, which is concerned with information flow from one argument to another one during type inference.

That kind of information flow arises automatically when type inference is done using algorithm W or similar mechanisms based on unification, but type inference using unification in a language with subtyping isn't tractable, so there's a need to go into heuristics, and that hasn't been done yet for Dart.

@eernstg
Copy link
Member

eernstg commented Jun 13, 2019

@leafpetersen, do you have further comments on this? I added a reference to this issue on #25490, because it's a good example to keep in mind. This issue could then be closed, marking it as a duplicate of #25490.

@mit-mit mit-mit added the area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). label Jun 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language).
Projects
None yet
Development

No branches or pull requests

3 participants