Skip to content
This repository has been archived by the owner on Feb 22, 2018. It is now read-only.

Error typing Stream.fromIterable #309

Closed
nex3 opened this issue Sep 1, 2015 · 4 comments
Closed

Error typing Stream.fromIterable #309

nex3 opened this issue Sep 1, 2015 · 4 comments

Comments

@nex3
Copy link

nex3 commented Sep 1, 2015

When I analyze the following code in strong mode:

import 'dart:async';

Stream<int> getStream() {
  return new Stream.fromIterable([1, 2, 3].map((i) => i));
}

I see this error:

[error] Type check failed: new Stream.fromIterable([1, 2, 3].map((i) => i)) (Stream<dynamic>) is not of type Stream<int> because [1, 2, 3].map((i) => i) cannot be typed as Iterable<int>

Is this to do with the in-progress generic method support?

@jmesserly
Copy link
Contributor

Is this to do with the in-progress generic method support?

Hmmm, I think we might need more powerful inference, e.g. parameter inference (#203).

Inference correctly pushed <int> into the new Stream.fromIterable but it failed to push <int> into .map((i) => i). map is a generic method that takes a function of T -> R, so it needs to see the return type R is int, push that to the parameter type T, which lets it conclude the target of the method is an Iterable<int> and then push that type to the list literal [1, 2, 3].

One interesting thing to try would be .where((i) => true) instead of map, because it's easier to infer where because the target and return type are both Iterable<T>, so you don't need to understand that (i) => i is the identity function

@vsmenon
Copy link
Contributor

vsmenon commented Sep 1, 2015

That's a nice example. For now, you'll need to type i in the closure as int.

@leafpetersen 's planning on downward inference for generic methods, which might make that unnecessary.

@leafpetersen
Copy link
Contributor

Right. map needs to be made a generic method, otherwise the return type of the map is List<dynamic>, which can't be typed as Iterable<int> as required by the context there. Vijay added some ad-hoc inference for map and company, but I think it runs separately from (and before) the downwards inference, and so I don't think it will fire here, since at the time that it runs the type of the closure is still dynamic->dynamic. With generic methods and downwards inference, this should work just fine. I think Vijay is correct that if you type the parameter as int, the static type of the closure will be int -> int, which will allow his special case inference for map to fire.

@vsmenon
Copy link
Contributor

vsmenon commented Oct 13, 2015

Merging this into #300

@vsmenon vsmenon closed this as completed Oct 13, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

4 participants