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

Unclear definition of self-referencing typedef #9592

Closed
johnniwinther opened this issue Apr 2, 2013 · 6 comments
Closed

Unclear definition of self-referencing typedef #9592

johnniwinther opened this issue Apr 2, 2013 · 6 comments
Assignees
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@johnniwinther
Copy link
Member

According to §15.3 it is 'a compile-time error if a typedef refers to itself via a chain of references that does not include a class declaration.'

What 'include' means in this context is unclear. For instance, is this a valid typedef?

typedef F(List<F> list);

@gbracha
Copy link
Contributor

gbracha commented Apr 2, 2013

Yes it is. The wording does need work, especially given all the other changes that have occurred since it was put in place.


Added Accepted label.

@johnniwinther
Copy link
Member Author

That is disturbing.

Since we use structural equality on function types, such a typedef introduces a recursive type which is just as difficult to handle as the invalid 'typedef F F()'.

For instance the typedefs

  typedef F(List<F> list);
  typedef G(List<G> list);

define the same function type and

  F foo(G g) => g;

should therefore be valid in checked mode.

Worse is that we can make even more complex structures like

  typedef H(List<I> list);
  typedef I(List<J> list);
  typedef J(List<H> list);

all of which are equivalent to F and G.

@johnniwinther
Copy link
Member Author

Note that the VM currently crashes on recursive types (http://dartbug.com/9611). Dart2js fails gracefully by just ignoring the structure of typedefs, currently.

I think that we should restrict typedefs to avoid recursive types completely. This means that all of the following typedefs are illegal:

typedef A1 A1(); // Cyclic through return type.
typedef A2(A2 a); // Cyclic through parameter type.
typedef A3([A3 a]); // Cyclic through optional parameter type.
typedef A4({A4 a}); // Cyclic through named parameter type.
typedef A5(List<A5> a); // Cyclic through generic parameter type.
typedef A6(A6 f()); // Cyclic through return type of function typed parameter.
typedef A7(f(A7 a)); // Cyclic through parameter type of function typed parameter.

typedef void A(B b); // Cyclic through another typedef.
typedef void B(List<A> a);

typedef void C(D d); // Cyclic through more typedefs.
typedef E D();
typedef void E(List<C> c);

typedef F<T extends F>(T t); // Cyclic through type variable bound.

@johnniwinther johnniwinther added Type-Defect area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). labels Apr 8, 2013
@sgrekhov
Copy link
Contributor

All of the cases listed the above works now (produce compile-time erorrs). Tested on Dart VM version: 1.14.0-dev.1.0 (Wed Nov 18 18:17:16 2015) on "windows_x64"

@sgrekhov
Copy link
Contributor

sgrekhov commented Dec 1, 2015

typedef F1<F1>(F1 f);
typedef F2<F2>([F2 f]);
typedef F3<F3>({F3 f});

The code above doesn't produce compile errors. I believe that it's according the spec but... Does it makes sense to allow typedefs like those above?

@kevmoo kevmoo added P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) and removed accepted labels Feb 29, 2016
@munificent munificent changed the title Unclear definition of self-rerencing typedef Unclear definition of self-referencing typedef Dec 16, 2016
@munificent
Copy link
Member

typedef F1<F1>(F1 f);
typedef F2<F2>([F2 f]);
typedef F3<F3>({F3 f});

These are OK, though confusing. They are declaring type parameters that shadow the name of the typedef itself.

Looks like the spec wording was tweaking and the implementations are doing the right thing, so I'm going to close this.

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). P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

5 participants