Skip to content

Conversation

@eernstg
Copy link
Member

@eernstg eernstg commented Jun 17, 2021

This PR adds a couple of paragraphs to the language specification, specifying that constant expressions whose evaluation is a function closurization or a generic function instantiation are canonicalized.

@eernstg eernstg requested a review from lrhn June 17, 2021 14:28
@eernstg
Copy link
Member Author

eernstg commented Jun 17, 2021

@johnniwinther, @mraleph, do you think this change could be a front-end only thing? Would it potentially be a substantial effort?

@johnniwinther
Copy link
Member

What is a "function closurization"? Can you give an example of what this change should support?

@eernstg
Copy link
Member Author

eernstg commented Jun 18, 2021

A function closurization is a tearoff when the denoted function is a top-level function, a static method, or a local function, so it's a tearoff of anything-not-an-instance-method.

The best example is probably the tests: https://dart-review.googlesource.com/c/sdk/+/202243.

The current failures in those tests are mentioned in a comment from me. Here's a copy of the ones that are related to constants, for convenient access:

    103:  checkIdentical(cIntTopLevelFunction1, vIntTopLevelFunction2);
    104:  checkIdentical(cIntStaticMethod1, vIntStaticMethod2);
    105:  checkIdentical(vIntTopLevelFunction1, vIntTopLevelFunction2);
    106:  checkIdentical(vIntStaticMethod1, vIntStaticMethod2);

A complete example could be the following:

class CheckIdentical {
  const CheckIdentical(Object? o1, Object? o2): assert(identical(o1, o2));
}

X f<X>(X x) => x;

void main() {
  const int Function(int) g = f; // Generic function instantiation, "f<int>".
  const int Function(int) g2 = f; // Ditto.
  print(identical(g, g2)); // 'true' on the vm and dart2js.
  CheckIdentical(g, g2); // Succeeds on the analyzer, and elsewhere.

  // But canonicalization fails to occur when the constant
  // expression is not in a constant context.
  int Function(int) g3 = f;
  print(identical(g, g3)); // 'false' with `dart`, true with `dart2js`.
}

@johnniwinther
Copy link
Member

Ah. We currently eagerly constantify static tearoffs - regardless of static context. We could just extend this to instantiations of those tearoffs when the type arguments are constant. We probably even need this for the constructor tearoffs.

So yes, this can be done in the cfe.

@eernstg
Copy link
Member Author

eernstg commented Jun 20, 2021

Sounds good, thanks!

@eernstg
Copy link
Member Author

eernstg commented Jun 28, 2021

@lrhn, given that the language team decided at the meeting June 23rd that function objects should be canonicalized, the basic question raised by this PR has been resolved. Do you have further comments on the PR?

Copy link
Member

@lrhn lrhn left a comment

Choose a reason for hiding this comment

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

LGTM.
Do we need to address equality too?

@eernstg
Copy link
Member Author

eernstg commented Jun 28, 2021

Thanks! Equality is specified, and the question is whether we'd want to ask for the specified behavior to be fully implemented, or we'd rather change the specification, cf. #1712. So we'll change the specification about equality in another PR, or we'll keep the current rules and ask for an implementation, and this PR should is separate from those efforts.

@eernstg eernstg merged commit f86568f into master Jun 28, 2021
@eernstg eernstg deleted the specify_function_canonicalization_jun21 branch June 28, 2021 11:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants