Skip to content

Commit

Permalink
For unsafeReferenceCast rely on type checks in the runtime.
Browse files Browse the repository at this point in the history
<slight revision of yesterday's reverted commit>

The debugAsserts were nicely self-documenting, but generate an obscene
amount of useless SIL code that is inlined everywhere and sticks around
when we compile the stdlib. The old asserts would need to be fixed to
support Optionals but that makes the situation much worse.

Why is it ok to remove the asserts?
_unsafeReferenceCast remains an internal API.
If the src/dest types are not loadable reference types, the cast will
not be promoted to a value bitcast.
The remanining cases will be dynamically checked by swift_dynamicCast.

Swift SVN r32828
  • Loading branch information
atrick committed Oct 22, 2015
1 parent 9f33429 commit 60d2331
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 9 deletions.
10 changes: 8 additions & 2 deletions lib/SIL/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2163,10 +2163,16 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
}

void checkUncheckedRefCastAddrInst(UncheckedRefCastAddrInst *AI) {
require(AI->getSrc().getType().isAddress(),
auto srcTy = AI->getSrc().getType();
auto destTy = AI->getDest().getType();
require(srcTy.isAddress(),
"unchecked_ref_cast_addr operand must be an address");
require(AI->getDest().getType().isAddress(),
require(destTy.isAddress(),
"unchecked_ref_cast_addr result must be an address");
// The static src/dest types cannot be checked here even if they are
// loadable. unchecked_ref_cast_addr may accept nonreference static types
// (as a result of specialization). These cases will never be promoted to
// value bitcast, thus will cause the subsequent runtime cast to fail.
}

void checkUncheckedAddrCastInst(UncheckedAddrCastInst *AI) {
Expand Down
13 changes: 6 additions & 7 deletions stdlib/public/core/Builtin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -206,17 +206,16 @@ public func unsafeAddressOf(object: AnyObject) -> UnsafePointer<Void> {
return UnsafePointer(Builtin.bridgeToRawPointer(object))
}

/// Converts a reference of type `T` to a reference of type `U`.
/// Converts a reference of type `T` to a reference of type `U` after
/// unwrapping one level of Optional.
///
/// `T` and `U` must be convertible to AnyObject. They may be either a
/// class or a class protocol.
/// Unwrapped `T` and `U` must be convertible to AnyObject. They may
/// be either a class or a class protocol. Either T, U, or both may be
/// optional references.
@transparent
@warn_unused_result
public func _unsafeReferenceCast<T, U>(x: T, _: U.Type) -> U {
_debugPrecondition(x is AnyObject, "invalid unsafeReferenceCast")
let u: U = Builtin.castReference(x)
_debugPrecondition(u is AnyObject, "invalid unsafeReferenceCast")
return u
return Builtin.castReference(x)
}

/// - returns: `x as T`.
Expand Down

0 comments on commit 60d2331

Please sign in to comment.