Skip to content

Promotion by assignment seems to use a supertype of interest #60622

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

Open
eernstg opened this issue Apr 25, 2025 · 3 comments
Open

Promotion by assignment seems to use a supertype of interest #60622

eernstg opened this issue Apr 25, 2025 · 3 comments
Labels
area-dart-model For issues related to conformance to the language spec in the parser, compilers or the CLI analyzer. model-flow Implementation of flow analysis in analyzer/cfe

Comments

@eernstg
Copy link
Member

eernstg commented Apr 25, 2025

Consider the following program:

import 'dart:async';

void main() {
  FutureOr<Pattern> s = "Some string";
  s.expectStaticType<Exactly<FutureOr<Pattern>>>();
  if (s is Pattern) {} // Make `Pattern` a type of interest for `s`.
  s = "";
  s.expectStaticType<Exactly<Pattern>>(); // Promoted to `Pattern`, apparently!
  s.allMatches('foo');
}

typedef Exactly<X> = X Function(X);

extension<X> on X {
  X expectStaticType<Y extends Exactly<X>>() => this;
}

The flow-analysis feature specification talks about a variable being

promotable via assignment of an expression of type T

and it requires T to be a type of interest for that variable. However, in this case the type of the expression is String (which is not a type of interest for s), and the implementation seems to use a more flexible approach where s is actually promoted to a type which is of interest for s, and sound (because it's a supertype of the type of object that we just assigned to it).

This might be fine (and useful!), but the specification should then be adjusted to specify this more flexible approach.

@eernstg eernstg added the area-devexp For issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages. label Apr 25, 2025
@lrhn
Copy link
Member

lrhn commented Apr 28, 2025

Agree, spec should probably be updated.

However, then it also needs to account for a diamond type pattern, like D<:(B,C)\<:A``

void foo(A a, D d){
  if (a is B || a is C) {}
  // Both B and C are yours off interest. 
  a = d;
  // What is `a` now?
}

@srawlins srawlins added area-dart-model For issues related to conformance to the language spec in the parser, compilers or the CLI analyzer. and removed area-devexp For issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages. labels Apr 28, 2025
@johnniwinther johnniwinther added the model-flow Implementation of flow analysis in analyzer/cfe label Apr 29, 2025
@johnniwinther
Copy link
Member

cc @stereotype441

@eernstg
Copy link
Member Author

eernstg commented May 6, 2025

Here's the analysis from @stereotype441: #60646 (comment).

The approach to the diamond is to not promote a because the set of types of interest that are subtypes of the chosen suffix of the promoted types and supertypes of the assigned value (of type D) does not have a minimal element:

class A {}
class B extends A {}
class C extends A {}
class D implements B, C {}

void foo(Object a, D d){
  a as A;
  if (a is B || a is C) {}
  a = d; // Not promoted: Neither `B` nor `C` is minimal in `{A, B, C}`.
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-dart-model For issues related to conformance to the language spec in the parser, compilers or the CLI analyzer. model-flow Implementation of flow analysis in analyzer/cfe
Projects
None yet
Development

No branches or pull requests

4 participants