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

passing generic function literals #426

Closed
Andersmholmgren opened this issue Jan 24, 2016 · 3 comments
Closed

passing generic function literals #426

Andersmholmgren opened this issue Jan 24, 2016 · 3 comments

Comments

@Andersmholmgren
Copy link

I have the following

typedef BuiltListProperty<T> BuiltListPropertyFactory<T>(
    Stream<ListMutation<T>> mutations);

BuiltListProperty<Object /*=T*/ > _defaultBuiltListPropertyFactory /*<T>*/ (
        Stream<ListMutation /*<T>*/ > mutations) =>
    new BuiltListProperty<Object /*=T*/ >(mutations);

class BuiltListProperty<E> {
  BuiltListProperty /*<R>*/ map /*<R>*/ (/*=R*/ f(E element),
          [BuiltListPropertyFactory /*<R>*/ builtListFactory =
              _defaultBuiltListPropertyFactory /*<R>*/]) => ...
}

The analyzer complains with

ERROR: Type check failed: _defaultBuiltListPropertyFactory ((Stream<ListMutation>) → BuiltListProperty) is not of type (Stream<ListMutation>) → BuiltListProperty ([frentity] lib/src/list_property/built_list_property.dart:64)

@jmesserly
Copy link
Contributor

Nice example! A few things could be going on here:

  • we don't have instantiated tear-off support, so _defaultBuiltListPropertyFactory /*<R>*/ doesn't parse the <R>
  • we're not doing downward inference for instantiated tear-offs. Otherwise we'd push the <R> down to _defaultBuiltListPropertyFactory.

The error I'm seeing makes a little more sense:

[error] Type check failed: _defaultBuiltListPropertyFactory (<T>(dynamic) → BuiltListProperty<T>) is not of type (dynamic) → BuiltListProperty<R>

Basically it ends up with the uninstantiated generic function type. So the error message itself is correct, but, it's no good that you can't express what you're trying to express here. I'll see if I can find the bug about instantiated tear-offs & if not, open a new one.

@jmesserly
Copy link
Contributor

The other bug is dart-lang/sdk#25175. We thought perhaps we could wait to implement instantiated tear-offs, but this example is a good one for why that doesn't work. :)

It's ugly, but a workaround in the short term might be:

typedef BuiltListProperty<T> BuiltListPropertyFactory<T>(
    Stream<ListMutation<T>> mutations);

class BuiltListProperty<E> {
  BuiltListProperty /*<R>*/ map /*<R>*/ (/*=R*/ f(E element),
          [BuiltListPropertyFactory /*<R>*/ builtListFactory]) {
    if (builtListFactory == null) {
      builtListFactory = (Stream<ListMutation /*<R>*/ > mutations) =>
          new BuiltListProperty<Object /*=R*/ >(mutations);
    }
  }
}

@jmesserly
Copy link
Contributor

believe this should be fixed now. Strong mode will infer it.

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

2 participants