-
Notifications
You must be signed in to change notification settings - Fork 424
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
init= and = with different-type rhs #15838
Comments
I lean towards A, personally, though I'm not up to date on what's standing between us and |
I am thinking about a case with a record that allows copy-initialization from In that event, would an var x: int = myRecordWrappedInt; Some of the alternatives (e.g. Option 3 in this comment #15806 (comment) ) would generalize smoothly to non-record types even if That leads to two general directions for the case that the LHS is not a record:
Let's consider what these imply if in #16576 we decide that
What about the impact on
|
I'd generally be open to extending I was going to write that approach 1 might also have value in terms of simplicity in the sense that the distinction between initializing a scalar value and assigning it is pretty minimal compared to other types (e.g., there's no need to distinguish between creating vs. replacing some existing dynamically allocated state in the two cases). However, I feel nervous about your observation that supplying a |
At the moment, I am not thinking that As a result I think that approach 1 in the previous comment is reasonable. |
I am currently thinking that the compiler would be allowed to implement split-init with a cast function of some kind rather than just |
I am looking at implementing A1 and additionally requiring a Some things I observed in initial testing: I added casts for these cases:
I adjusted the checking to work around these cases:
|
PR #17092 is close to passing testing and demonstrates the changes that were required to module/test code. |
PR #17092 now passes testing. |
Add compilation error for missing implied conversions This is philisophically a continuation of PR #14956. Issue #15838 contains design discussion. This PR adds compilation errors according to an idea that conversions between types come in 4 levels. The idea is that a programmer should be able to access any of these 4 levels, but the higher levels imply the lower ones. * level 4 (implicit conversion) implies 3,2,1 (assign, initialize, cast) * level 3 (assign) implies 2,1 (initialize, cast) * level 2 (initialize) implies 1 (cast) * level 1 (cast) doesn't imply any of the others To support that idea, this PR adds errors for * no `init=` between two types when `=` is present * no cast between two types when `init=` is present. For now this PR uses the existing `proc _cast(type t: toType, other: fromType)` syntax to declare the casts. That is so that it does not interfere ongoing changes to operators. Additionally, because it's not currently possible to declare tertiary initializers or initializers on `extern` types, this PR leaves out the missing `init=` error for these types for now. For Cray/chapel-private#1626 Reviewed by @lydia-duncan - thanks! - [x] full local futures testing
Update spec to describe cast operator, requirements on other conversions This PR updates the conversions chapter of the language specification and makes related changes. For Cray/chapel-private#1751 and Cray/chapel-private#1752. Follow-up to #15838 #17092 #17146. Future work: * It might not be the clearest to describe assignment or `init=` between types as a kind of conversion. Maybe we should just call these assignment between different types or copy initialization between different types. * The division in the exposition between subtype conversions, generic type conversions, and class conversions is not a very satisfying division and seems to have a lot of overlap. Perhaps the subtype concept could be described separately, as a concept, and then the sections can consider conversion to a generic type or class conversions. Reviewed by @vasslitvinov - thanks!
PR #14956 added checks that either both
T.init=(_)
and= (T, _)
are user-provided or both are compiler-provided. It added this as a check that occurs after resolution. The strategy of making this case an error was discussed in #8065.However this strategy leaves it unclear what happens for
=
andinit=
functions that operate with a different RHS type. Issues #15717 and #15806 ran into this.This issue is a spin-off from #15806 which already included some discussion.
From #15806, the leading strategies are:
A. Additional error checking
Make it an error if a type T has
proc =(ref lhs:T, rhs:T2)
but notproc T.init=(rhs:T2)
or if it hasproc T.init=(rhs:T2)
but notproc =(ref lhs: T, rhs:T2)
(the argument names and intents are not important here but the types are important).This would make the patterns users are trying to write in #15717 and #15806 impossible to write for the time being, because neither tuples nor arrays currently use
init=
. If we wanted to be able to write those patterns specifically, we could make an exception to the error for tuples and arrays. (Then the compiler would run default-init and = at the initialization point instead of copy-initialization).So then we have two variants of A:
A1.
=
for tuple or array cannot be overridden by usersA2. Tuples and arrays have an exception to the error message and behave as if an
init=
existed that ran=
B. Generate init= from =
Change from the strategy in #8065 / #14956 of generating an error to a strategy of generating
proc init=
from aproc =
that is provided and vice versa. (This was brought up in #8065 (comment) and we chose to start with less permissive strategy).For B., if a type has
=
but notinit=
, then the compiler could generateLikewise, if a type has
init=
but not=
, then the compiler could generateSince the
lhs
variable might be on a different locale this also runs into questions about records and move initialization across locales (issue #15676). We could alternatively consider making the compiler only generateinit=
from=
and not the other way around (which would avoid that particular issue). So there are two variants of this option:B1. Enable generation of
init=
from=
and also generation of=
frominit=
B2. Enable only generation of
init=
from=
The text was updated successfully, but these errors were encountered: