-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Summary of issue:
Followup to #6124
The decision on #6124 was that abstract
types do not impl Destroy
. Does a partial
abstract
type impl Destroy
?
Details:
Carbon's generally expecting people to write factory functions for parents, and those factory functions will often return partial Self
for a base class. Particularly for an abstract
type, where they must return partial Self
.
A factory function's return type could also be something allowing failures, such as Optional(Self)
or Self*?
. The timing of when failure is allowed is important.
-
partial
types implDestroy
as long as their object representation does: If failure after construction starts but before it completes is to be allowed (including something like a parent type partially constructing, but a child type failing to construct), then I think apartial
abstract
type must be able toDestroy
, in order to garbage collect the partially destructed state.-
It would be a particular concern if a
partial
type could notimpl
Destructor
, because of potential leaks. See below for further notes on this. -
It may be worth thinking about how this interacts with the theorized
Indestructible
interface -- do people doimpl partial T as Indestructible
to mean that bothT
andpartial T
can't beDestroy
ed (becausepartial T
is inherently part ofT
's representation), or doesimpl T as Indestructible
imply thatpartial T
also can't beDestroy
ed (just always doing the impl lookup removingpartial
)?
-
-
partial
types do not implDestroy
: it could be a language rule that once construction ofpartial
state starts, the end result must be a complete object, and only the completed object can be destroyed.- Factory functions would need to rely on
returned var
move semantics and only starting construction of base types after they're sure construction will succeed.
- Factory functions would need to rely on
-
partial
types only implDestroy
when the main type implsDestroy
: This is subtly different from option (1) in that it means apartial abstract
type does not implDestroy
, but apartial base
type does.- This is noted in part for the question of
Indestructible
on (1) -- it's an approach that makes thepartial
version consistent.
- This is noted in part for the question of
Any other information that you want to share?
Regarding partial
and Destructor
, #6124 decided the signature of Destructor
is:
class B {
impl as Destructor {
fn Op[ref self: Self]() { ... }
}
}
As long as I'm asking questions about partial
types, I'd like to confirm that this decision -- that destructors can only be called on non-partial
types -- holds. Note destruction order probably looks something like:
- Call
Destructor
for child type - Destroy members of child type
- Call
Destructor
for parent type - Destroy members of parent type
Since Destructor
takes a non-partial
Self
, it means that the parent destructor can continue to use virtual functions.
Note though that using Destructor
with partial Self
also implies the signature would be more like:
class B {
impl partial Self as Destructor {
fn Op[ref self: Self]() { ... }
}
}
(where Self
there changes from B
in Destructor
to partial B
in Op
)
or a different interface; perhaps:
interface Destructor {
private fn Op[ref self: partial Self]() { ... }
}
Maybe #6124 should be augmented adding partial
to the Destructor
interface?