-
Notifications
You must be signed in to change notification settings - Fork 208
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
Conversation
Was originally at: dart-lang/sdk#29624
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 |
There was a problem hiding this 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. |
There was a problem hiding this comment.
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
}
}
There was a problem hiding this comment.
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!
}
}
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
Landing this, if for nothing else, then as background material. |
Was originally at: dart-lang/sdk#29624