Skip to content

Analyzer summaries do not encode inferred args for constant constructor invocations #32290

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
stereotype441 opened this issue Feb 23, 2018 · 11 comments
Assignees
Labels
area-dart-model For issues related to conformance to the language spec in the parser, compilers or the CLI analyzer. customer-google3 dart-model-analyzer-spec Issues with the analyzer's implementation of the language spec P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Milestone

Comments

@stereotype441
Copy link
Member

Consider the following code:

class C<T> {
  final T t;
  const C(this.t);
}
const Object x = const C(0);

Type inference infers that the constant constructor invocation is const C<int>(0). But this information is not recorded in the summary. Therefore, if x is reconstituted from a summary and constant evaluated, and the type of x's constant value is queried, the result will be C<dynamic>.

@stereotype441 stereotype441 added the legacy-area-analyzer Use area-devexp instead. label Feb 23, 2018
@stereotype441
Copy link
Member Author

To fix this, we need to make the following modifications:

  • The summary IDL needs a place to store an optional type inference slot associated with each const constructor invocation (maybe do it for non-const constructor invocations as well, just in case).*
  • The unlinked summary builder needs to allocate a type inference slot whenever it sees a const constructor invocation that doesn't have explicit type parameters.
  • The linker needs to store the inferred type of each a const constructor invocation in the type inference slot, if present.
  • The resynthesizer needs to detect if there is an inferred type stored in the type inference slot; if there is, it needs to point the resynthesized constant AST to the appropriate ConstructorMember. Then the ConstantEvaluationEngine should do the right thing automatically.

*Note that this will need to be done carefully to avoid backward compatibility problems. E.g. you can't just add the slot to the UnlinkedExpr.ints list, because then old and new analyzers will disagree about where they are in the ints array when evaluating a constant. Probably we should just add a new field, UnlinkedExpr.constructorInvocationTypeSlots.

@matanlurey
Copy link
Contributor

@stereotype441 @devoncarew Should I assume this will never get fixed due to summaries not sticking around long-term?

The hacks I have in to "pretend" to do inference are pretty scary, and I'd hate to have to rely on them longer than we have to.

@matanlurey
Copy link
Contributor

Ping @stereotype441 @devoncarew

@stereotype441
Copy link
Member Author

Yeah, I think it's safe to assume this won't get fixed until we switch over to using the common front end. :(

@matanlurey
Copy link
Contributor

Thanks!

@matanlurey matanlurey added the P2 A bug or feature request we're likely to work on label Aug 27, 2018
@bwilkerson bwilkerson added the type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) label Sep 2, 2018
@bwilkerson bwilkerson added this to the Dart2.1 milestone Sep 2, 2018
@bwilkerson bwilkerson modified the milestones: Dart2.1, PostDart2.1 Sep 4, 2018
@MichaelRFairhurst MichaelRFairhurst self-assigned this Dec 7, 2018
@aadilmaan aadilmaan modified the milestones: Future, D25 Release Jun 4, 2019
@srawlins srawlins added the dart-model-analyzer-spec Issues with the analyzer's implementation of the language spec label Jun 17, 2020
@leonsenft
Copy link

Yeah, I think it's safe to assume this won't get fixed until we switch over to using the common front end. :(

@bwilkerson @stereotype441 This issue recently came up for a customer during the null safety migration. Considering that the analyzer didn't end up using the CFE, could we look into this again?

@stereotype441
Copy link
Member Author

@scheglov, who has taken over the analyzer summary work.

@scheglov scheglov self-assigned this Aug 29, 2023
@scheglov
Copy link
Contributor

The test case in the first message already works, probably since about 2020.
I will add a couple of tests for it https://dart-review.googlesource.com/c/sdk/+/323228, mostly to show that it works.

copybara-service bot pushed a commit that referenced this issue Aug 29, 2023
Bug: #32290
Change-Id: Ic4581f0a531a9460f8764e8dd190cc50a19de0f9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/323228
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Konstantin Shcheglov <[email protected]>
@leonsenft
Copy link

Perhaps the test case here was fixed, but I believe we're still able to reproduce the issue with a more complex example. Please see the internal issue for a reproduction.

@leonsenft leonsenft reopened this Aug 30, 2023
@scheglov
Copy link
Contributor

What makes you think that there is still an issue in the analyzer?

@leonsenft
Copy link

I think I figured out the issue.

The code in question looked like:

const tokenA = OpaqueToken<List<A>>();
const tokenB = OpaqueToken<List<B>>();

List<A> createListA() => ...;
List<B> createListB() => ...;

const provider = [
  FactoryProvider.forToken(tokenA, createListA),
  FactoryProvider.forToken(tokenB, createListB),
];

It's important to note the type signature of FactoryProvider.forToken:

class FactoryProvider<T extends Object> implements Provider<T> {
  FactoryProvider.forToken(OpaqueToken<T> token, Function useFactory) { ... }
}

In our compiler, we were first trying to infer the type of each provider its type T. The type we were getting back in this case is List<Object>. I think this makes sense, because the inferred type of providers would be List<FactoryProvider<List<Object>>().

In practice we should probably be preferring the type of the token itself, over the type returned from inference.

If this sounds like it's working as expected then feel free to close.

@bwilkerson bwilkerson added area-dart-model For issues related to conformance to the language spec in the parser, compilers or the CLI analyzer. and removed legacy-area-analyzer Use area-devexp instead. labels Feb 21, 2025
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. customer-google3 dart-model-analyzer-spec Issues with the analyzer's implementation of the language spec 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

9 participants