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

State that special-case num typing rules do not apply to extension type members #3396

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 26 additions & 0 deletions accepted/future-releases/extension-types/feature-specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ information about the process, including in their change logs.
[1]: https://github.com/dart-lang/language/blob/master/working/1426-extension-types/feature-specification-views.md
[2]: https://github.com/dart-lang/language/blob/master/working/extension_structs/overview.md

2023.10.12
- State that special-case `num` typing only applies to non-extension members
invocations.

2023.09.11
- Add missing rule about getter/setter signature correspondence.

Expand Down Expand Up @@ -601,6 +605,28 @@ If _Dm_ is a method with function type `F`, and `args` exists, the static
analysis of the extension type member invocation is the same as that of an
invocation with argument part `args` of a function with the given type.

### Special-case Typing Rules for `num` Members

The language specification contains special typing rules for invocations
of `+`, `-`, `*`, `%`, `remainder` and `clamp` methods on
subtypes of `num`, `int` and `double`.
Copy link
Member

Choose a reason for hiding this comment

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

The subtypes of num is the same set of types (ignoring JavaScript numbers and other special number types that the language doesn't know about and implementations carefully try to hide) as the subtypes of num, int, and double.

On the other hand, the rules seem to apply to num, int, and double, and not to any other types.

Perhaps the least confusing wording would simply be '... methods on num, int, and double'?

Or perhaps type variables like X extends num justify saying 'subtypes' in any case? But even in that case we should be able to say 'subtypes of num'.

Copy link
Member Author

Choose a reason for hiding this comment

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

Or just say "on instances of"...

Copy link
Member

Choose a reason for hiding this comment

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

I think this thread can just be settled by using one of the suggested wordings.


Those rules do *not* apply to invocations of extension or extension type
members.
The rules are otherwise unchanged when applied to non-extension type
member invocations, which will necessarily invoke the corresponding members
of an instance of `int` or `double`.
Comment on lines +616 to +618
Copy link
Member

Choose a reason for hiding this comment

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

It is slightly confusing that we're talking about non-extension type member invocations. The extension type feature specification talks about 'non-extension types', and about the 'extension type members' and 'non-extension type members' that an extension type may have, but in this case we'd like to cover plain extensions as well. We could repeat and negate 'extension or extension type members', but that's a lot of duplication just very few words apart.

So perhaps the following will suffice:

Suggested change
The rules are otherwise unchanged when applied to non-extension type
member invocations, which will necessarily invoke the corresponding members
of an instance of `int` or `double`.
The rules are unchanged when applied to invocations of other members, which will
necessarily invoke the corresponding members of an instance of `int` or `double`.

Copy link
Member

Choose a reason for hiding this comment

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

I was just worried about using the phrase "non-extension type member" with a slightly different meaning than that which is used in the extension type feature specification. Would you be OK using the suggested edit?


_It's not currently possible to have a subtype of `num` which has
an extension member for those member names, but if it ever becomes possible,
eernstg marked this conversation as resolved.
Show resolved Hide resolved
the rules will still not apply to such an invocation._

_It's currently also not possible to introduce a subtype of `num`, `int` or
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
_It's currently also not possible to introduce a subtype of `num`, `int` or
_It's currently also not possible to introduce a non-extension type which is a subtype of `num`, `int` or

`double`, which does not have the same member signatures for the special-cased
members as the type that it subtypes, so the special-case rules are safe to
assume that signature. If we introduce the ability to narrow or change the
signatures of non-extension-type members of extension types,
the special-case typing rules will have to be re-visited._
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps:

Suggested change
the special-case typing rules will have to be re-visited._
the special-case typing rules may have to be re-visited._

We could claim that this case has already been covered: An extension type subtype of int, say, can certainly declare an extension type operator + with a different signature and implement it.

It would be a new thing if we allow, for example, an abstract declaration with the given name in an extension type declaration to modify the static analysis of a member whose implementation is provided by a non-extension superinterface. However, I'd suggest that we treat this case as an implicitly induced forwarding method; for instance, it would be confusing if such a member is torn off and the resulting function object doesn't have the function type of the member as declared.


### Dynamic Semantics of an Extension Type Member Invocation

Expand Down