mirror of
https://github.com/roc-lang/roc.git
synced 2025-11-26 22:03:59 +00:00
fix ManuallyDrop usage in tag unions
This commit is contained in:
parent
9a6f9ad26e
commit
995e14747b
1 changed files with 34 additions and 15 deletions
|
|
@ -345,6 +345,13 @@ generateConstructorFunction = \buf, types, tagUnionType, name, optPayload ->
|
||||||
|
|
||||||
Some payloadId ->
|
Some payloadId ->
|
||||||
payloadType = typeName types payloadId
|
payloadType = typeName types payloadId
|
||||||
|
shape = Types.shape types payloadId
|
||||||
|
|
||||||
|
new =
|
||||||
|
if canDeriveCopy types shape then
|
||||||
|
"payload"
|
||||||
|
else
|
||||||
|
"core::mem::ManuallyDrop::new(payload)"
|
||||||
|
|
||||||
"""
|
"""
|
||||||
\(buf)
|
\(buf)
|
||||||
|
|
@ -353,7 +360,7 @@ generateConstructorFunction = \buf, types, tagUnionType, name, optPayload ->
|
||||||
Self {
|
Self {
|
||||||
discriminant: discriminant_\(tagUnionType)::\(name),
|
discriminant: discriminant_\(tagUnionType)::\(name),
|
||||||
payload: union_\(tagUnionType) {
|
payload: union_\(tagUnionType) {
|
||||||
\(name): core::mem::ManuallyDrop::new(payload),
|
\(name): \(new),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -380,13 +387,21 @@ generateDestructorFunction = \buf, types, tagUnionType, name, optPayload ->
|
||||||
|
|
||||||
Some payloadId ->
|
Some payloadId ->
|
||||||
payloadType = typeName types payloadId
|
payloadType = typeName types payloadId
|
||||||
|
shape = Types.shape types payloadId
|
||||||
|
|
||||||
|
take =
|
||||||
|
if canDeriveCopy types shape then
|
||||||
|
"unsafe { self.payload.\(name) }"
|
||||||
|
|
||||||
|
else
|
||||||
|
"unsafe { core::mem::ManuallyDrop::take(&mut self.payload.\(name)) }"
|
||||||
|
|
||||||
"""
|
"""
|
||||||
\(buf)
|
\(buf)
|
||||||
|
|
||||||
pub fn unwrap_\(name)(mut self) -> \(payloadType) {
|
pub fn unwrap_\(name)(mut self) -> \(payloadType) {
|
||||||
debug_assert_eq!(self.discriminant, discriminant_\(tagUnionType)::\(name));
|
debug_assert_eq!(self.discriminant, discriminant_\(tagUnionType)::\(name));
|
||||||
unsafe { core::mem::ManuallyDrop::take(&mut self.payload.\(name)) }
|
\(take)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_\(name)(&self) -> bool {
|
pub fn is_\(name)(&self) -> bool {
|
||||||
|
|
@ -876,37 +891,41 @@ canDerivePartialEq = \types, type ->
|
||||||
|
|
||||||
cannotDeriveCopy : Types, Shape -> Bool
|
cannotDeriveCopy : Types, Shape -> Bool
|
||||||
cannotDeriveCopy = \types, type ->
|
cannotDeriveCopy = \types, type ->
|
||||||
|
!(canDeriveCopy types type)
|
||||||
|
|
||||||
|
canDeriveCopy : Types, Shape -> Bool
|
||||||
|
canDeriveCopy = \types, type ->
|
||||||
when type is
|
when type is
|
||||||
Function rocFn ->
|
Function rocFn ->
|
||||||
runtimeRepresentation = Types.shape types rocFn.lambdaSet
|
runtimeRepresentation = Types.shape types rocFn.lambdaSet
|
||||||
cannotDeriveCopy types runtimeRepresentation
|
canDeriveCopy types runtimeRepresentation
|
||||||
|
|
||||||
# unsized values are heap-allocated
|
# unsized values are heap-allocated
|
||||||
Unsized -> Bool.true
|
Unsized -> Bool.false
|
||||||
|
|
||||||
Unit | EmptyTagUnion | Bool | Num _ | TagUnion (Enumeration _) -> Bool.false
|
Unit | EmptyTagUnion | Bool | Num _ | TagUnion (Enumeration _) -> Bool.true
|
||||||
RocStr | RocList _ | RocDict _ _ | RocSet _ | RocBox _ | TagUnion (NullableUnwrapped _) | TagUnion (NullableWrapped _) | TagUnion (Recursive _) | TagUnion (NonNullableUnwrapped _) | RecursivePointer _ -> Bool.true
|
RocStr | RocList _ | RocDict _ _ | RocSet _ | RocBox _ | TagUnion (NullableUnwrapped _) | TagUnion (NullableWrapped _) | TagUnion (Recursive _) | TagUnion (NonNullableUnwrapped _) | RecursivePointer _ -> Bool.false
|
||||||
TagUnion (SingleTagStruct { payload: HasNoClosure fields }) ->
|
TagUnion (SingleTagStruct { payload: HasNoClosure fields }) ->
|
||||||
List.any fields \{ id } -> cannotDeriveCopy types (Types.shape types id)
|
List.all fields \{ id } -> canDeriveCopy types (Types.shape types id)
|
||||||
|
|
||||||
TagUnion (SingleTagStruct { payload: HasClosure fields }) ->
|
TagUnion (SingleTagStruct { payload: HasClosure fields }) ->
|
||||||
List.any fields \{ id } -> cannotDeriveCopy types (Types.shape types id)
|
List.all fields \{ id } -> canDeriveCopy types (Types.shape types id)
|
||||||
|
|
||||||
TagUnion (NonRecursive { tags }) ->
|
TagUnion (NonRecursive { tags }) ->
|
||||||
List.any tags \{ payload } ->
|
List.all tags \{ payload } ->
|
||||||
when payload is
|
when payload is
|
||||||
Some id -> cannotDeriveCopy types (Types.shape types id)
|
Some id -> canDeriveCopy types (Types.shape types id)
|
||||||
None -> Bool.false
|
None -> Bool.true
|
||||||
|
|
||||||
RocResult okId errId ->
|
RocResult okId errId ->
|
||||||
cannotDeriveCopy types (Types.shape types okId)
|
canDeriveCopy types (Types.shape types okId)
|
||||||
|| cannotDeriveCopy types (Types.shape types errId)
|
&& canDeriveCopy types (Types.shape types errId)
|
||||||
|
|
||||||
Struct { fields: HasNoClosure fields } | TagUnionPayload { fields: HasNoClosure fields } ->
|
Struct { fields: HasNoClosure fields } | TagUnionPayload { fields: HasNoClosure fields } ->
|
||||||
List.any fields \{ id } -> cannotDeriveCopy types (Types.shape types id)
|
List.all fields \{ id } -> canDeriveCopy types (Types.shape types id)
|
||||||
|
|
||||||
Struct { fields: HasClosure fields } | TagUnionPayload { fields: HasClosure fields } ->
|
Struct { fields: HasClosure fields } | TagUnionPayload { fields: HasClosure fields } ->
|
||||||
List.any fields \{ id } -> cannotDeriveCopy types (Types.shape types id)
|
List.all fields \{ id } -> canDeriveCopy types (Types.shape types id)
|
||||||
|
|
||||||
cannotDeriveDefault = \types, type ->
|
cannotDeriveDefault = \types, type ->
|
||||||
when type is
|
when type is
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue