Runtime: Fix problems with nil-to-nil casts

We have a special rule that Optional<T>.none successfully dynamically casts
to Optional<U>.none for any T and U. However the implementation was incorrect
if the source and destination types had a different size. We would initialize
the source to nil, and then copy to the result.

The correct implementation is to initialize the result using the result
payload type directly, and not call _succeed() at all.

Fixes <https://bugs.swift.org/browse/SR-1056>.
This commit is contained in:
Slava Pestov
2016-03-29 20:13:05 -07:00
parent 23eb156d31
commit e72caad3d7
3 changed files with 62 additions and 43 deletions

View File

@@ -2036,10 +2036,16 @@ checkDynamicCastFromOptional(OpaqueValue *dest,
_fail(src, srcType, targetType, flags);
return {false, nullptr};
}
// Get the destination payload type
const Metadata *targetPayloadType =
cast<EnumMetadata>(targetType)->getGenericArgs()[0];
// Inject the .none tag
swift_storeEnumTagSinglePayload(dest, payloadType, enumCase,
swift_storeEnumTagSinglePayload(dest, targetPayloadType, enumCase,
1 /*emptyCases=*/);
_succeed(dest, src, srcType, flags);
// We don't have to destroy the source, because it was nil.
return {true, nullptr};
}
// .Some