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

Move over "Enhanced Type Promotion" proposal. #79

Merged
merged 1 commit into from
Nov 7, 2018

Conversation

munificent
Copy link
Member

Was originally at: dart-lang/sdk#29624

@mdebbar
Copy link

mdebbar commented Nov 3, 2018

Do we expect types to be promoted into closures?

class Foo {
  void foo() => print('foo');
}

var action;
if (x is Foo) {
  action = () {
    x.foo(); // Is this ok?
  }
} else {
  action = () => null;
}
scheduleMicrotask(action);

Type promotion in the above scenario is safe if x is final, but is dangerous otherwise because x could be reassigned another value before action is invoked.

Copy link

@mdebbar mdebbar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it's worth explicitly mentioning in the proposal that it doesn't cover members? Like the following:

if (foo.bar is String) {
  print(foo.bar.length); // Unsafe because `.bar` could be a getter.
}


At the point where `.length` is accessed, `o` may be a String, or it may be
an int if `callClosure` was true. To avoid cases like this, the spec defines
certain variables to be off limits for type promotion.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to elaborate a bit here. Under what conditions do we consider a variable safe to type-promote?

void foo(x) async {
  closure() {
    x = 123;
  }

  if (x is String) {
    print(x.length); // Safe
  }

  if (x is String) {
    if (something) closure();
    print(x.length); // Unsafe
  }

  if (x is String) {
    await something;
    print(x.length); // Unsafe
  }
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another example, a bit contrived:

var x = 'abc';

class A {
  bool get foo {
    x = 123;
    return true;
  }
}

void main() {
  var a = A();
  if (x is String && a.foo) {
    print(x.length); // Unsafe!
  }
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, these are good points. This proposal isn't quite active right now and I'm not the author, so I don't think we'll tweak it right now. But if we summon it back to life, I think we should be more explicit about the things you bring up.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 120 says that the definition of which variables are safe to type promote is unchanged by this proposal, so it's what the spec says:

The static type system ascribes a static type to every expression. In some cases, the type of a local variable (which can be a formal parameter) may be promoted from the declared type, based on control flow.

With the following caveat added in many places:

... then the type of v is known to be T in s2, unless any of the following are true

  • v is potentially mutated in s1,
  • v is potentially mutated within a function other than the one where v is declared, or
  • v is accessed by a function defined in s1 and v is potentially mutated anywhere in the scope of v.

@lrhn lrhn merged commit 981b6f8 into master Nov 7, 2018
@lrhn
Copy link
Member

lrhn commented Nov 7, 2018

Landing this, if for nothing else, then as background material.

@lrhn lrhn deleted the enhanced-type-promotion branch November 7, 2018 13:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants