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

[extension types] Specify that a method shadows an "inherited" setter, and vice versa #3470

Merged
merged 8 commits into from
Nov 19, 2023

Conversation

eernstg
Copy link
Member

@eernstg eernstg commented Nov 14, 2023

Background: See dart-lang/sdk#53717, dart-lang/sdk#53719, dart-lang/sdk#53720.

This PR changes the extension types feature specification such that a method declaration in an extension type will shadow an "inherited" setter, and vice versa. This eliminates a setter/method conflict which couldn't otherwise be resolved.

For example:

extension type E1(int i) {
  set m1(_) {}
  void m2() {} 
  get m3 => 1;
  set m4(_) {}
}

extension type E2(int i) implements E1 {
  void m1() {} // OK, and `E2` does not have a setter named `m1=`.
  set m2(_) {} // OK, and `E2` does not have a method named `m2`.
  set m3(_) {} // OK, and `E2` has the full getter/setter pair.
  get m4 => 1; // OK, and `E2` has the full getter/setter pair.
}

void main() {
  var e2 = E2(1);
  e2.m1(); // OK.
  e2.m1 = 10; // Compile-time error.
  e2.m2 = 10; // OK.
  e2.m2(); // Compile-time error.
}

This PR has been accepted, so we need to reconsider dart-lang/sdk#53717 and its subtasks. They have been repurposed to get this spec change implemented:

@eernstg eernstg requested a review from lrhn November 14, 2023 15:17
@eernstg eernstg changed the title [extension types] Specify that a method shadows an "inherited" setter and vice versa [extension types] Specify that a method shadows an "inherited" setter, and vice versa Nov 14, 2023
@eernstg
Copy link
Member Author

eernstg commented Nov 15, 2023

I think the text has been clarified substantially, PTAL.

@eernstg
Copy link
Member Author

eernstg commented Nov 19, 2023

Thanks!

@eernstg eernstg merged commit 299d20b into main Nov 19, 2023
3 checks passed
@eernstg eernstg deleted the spec_extension_type_shadow_nov23 branch November 19, 2023 14:21
@eernstg
Copy link
Member Author

eernstg commented Nov 24, 2023

@johnniwinther, this spec change is being implemented in the analyzer as tracked by dart-lang/sdk#53719 and done in https://dart-review.googlesource.com/c/sdk/+/337641. Is there a need for an implementation issue and an implementation effort for the CFE as well, or is this already on track?

Just a quick check: The current version of the CFE (2534859b418898024576014b2ca99d379c3ccc3a) does not seem to have been updated to use the new 'precludes' rule, it still reports the method/setter conflicts.

@eernstg
Copy link
Member Author

eernstg commented Nov 24, 2023

@johnniwinther, I just learned that the CFE implementation issue for this task could be dart-lang/sdk#53720 (OK, I forgot about that and then rediscovered it ;-). I added a comment there about the fact that the specification changed, and hence the issue is about implementing 'precludes' as specified in this PR, not about changing a confusing CFE error message.

copybara-service bot pushed a commit to dart-lang/sdk that referenced this pull request Nov 28, 2023
See dart-lang/language#3470

Bug: #53719
Change-Id: Iab840870a4d5be18a591f8fcef81bacb4a5d22cc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/337641
Commit-Queue: Konstantin Shcheglov <[email protected]>
Reviewed-by: Phil Quitslund <[email protected]>
eernstg added a commit that referenced this pull request Dec 1, 2023
Adjust the rules about extension type member conflicts: precluded members do not create conflicts.

This PR changes the rule about member conflicts such that a member which is precluded does not conflict with any other members. It is an adjustment of the rules added by #3470.

For example, if an extension type `E1` declares a method named `m` and an extension type `E2` declares a setter named `m=` and has `implements E1`, then `E2` does not "inherit" the method named `m` (it is precluded because it would conflict with the setter).

In this PR we add an extra rule which says that it is not a conflict if `E2` has two superinterfaces `E1a` and `E1b`, and `E1a` declares a method named `m` and `E1b` declares a getter named `m`, and `E2` again declares a setter named `m=` and has `implements E1a, E1b`. The point as that `E2` will "inherit" the getter (so it has a full setter/getter pair), but not the method (because it is precluded by the setter), and (here comes the new thing) the method is ignored during conflict checks because it is precluded, so we avoid the useless error about `m` being ambiguous that we'd otherwise have because of `implements E1a, E1b`.
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.

2 participants