This comes up because when we perform mandatory inlining, we perform the
transform as we inline. So the tests for this are in mandatory_inlining
naturally.
Previously the cast optimizer bailed out on any conformance with
requirements.
We can now constant-propagate this:
```
protocol P {}
struct S<E> {
var e: E
}
extension S : P where E == Int {}
func specializeMe<T>(_ t: T) {
if let p = t as? P {
// do fast things.
}
}
specializeMe(S(e: 0))
```
This turns out to be as simple as calling the TypeChecker.
<rdar://problem/46375150> Inlining does not seem to handle
specialization properly for Data.
This enabled two SIL transformations required to optimize
the code above:
(1) The witness method call can be devirtualized.
(2) The allows expensive dynamic runtime checks such as:
unconditional_checked_cast_addr Array<UInt8> in %array : $*Array<UInt8> to ContiguousBytes in %protocol : $*ContiguousBytes
Will be converted into:
%value = init_existential_addr %existential : $*ContiguousBytes, $Array<UInt8>
store %array to %value : $*Array<UInt8>
- Existentials may eventually be able to conform to protocols
- Functions may grow new arms we haven't designed and implemented yet,
which could influence how they cast in the future.
rdar://problem/38684452
ClassDecl::getSuperclass() produces a complete interface type describing the
superclass of a class, including any generic arguments (for a generic type).
Most callers only need the referenced ClassDecl, which is (now) cheaper
to compute: switch those callers over to ClassDecl::getSuperclassDecl().
Fixes an existing test for SR-5993.
The archetype tests in the code being removed will never succeed
because there is code earlier in the function testing for any
archetypes in either type, and that path always returns.
The remaining test is broken (it's comparing source input and target
input and then target input to target result rather than comparing the
source input and target input and then source result and target
result), and is just duplicating the test that happens above.
If we really want to do a better test for substitutability we can do
so at a later time. In the meantime, I don't think it makes sense to
leave redundant comparisons and an unreachable return in place.
Assume we have:
Protocol P
An intenal extension to Optional - conforming to P
Compiling under whole module mode
Use of Optional type T?
Given a dynamic cast from T? to P, that cast might succeed even if T itself does not conform to P
rdar://problem/40500142
The conformance existing isn't enough to be sure the cast will succeed,
there may be dynamic information, so we just assume they're always
dynamic and always "MaySucceed".
Fixes rdar://problem/38694450.
"Accessibility" has a different meaning for app developers, so we've
already deliberately excised it from our diagnostics in favor of terms
like "access control" and "access level". Do the same in the compiler
now that we aren't constantly pulling things into the release branch.
This commit changes the 'Accessibility' enum to be named 'AccessLevel'.
Remove the cast consumption kind from all unconditional casts. It
doesn't make sense for unconditional casts, complicates SIL ownership,
and wasn't fully supported for all variants. Copies should be
explicit.
If the source and target are the same existential type, but the source is P.Protocol and the dest is P.Type, then we need to consider whether the protocol is self-conforming.
The only cases where a protocol self-conforms are objc protocols, but we're going to expect P.Type to hold a class object. And this case doesn't matter since for a self-conforming protocol type there can't be any type-level methods.
Thus we consider this kind of cast to always fail. The only exception from this rule is when the target is Any.Type, because *.Protocol can always be casted to Any.Type.
Fixes rdar://32682967
When casting from an object type to a bridged Swift value type, classifyDynamicCast would use the cast classification for the target type's bridged object type, which would be trivially WillSucceed for thinks like NSNumber-to-Int or NSError-to-SomeError, even though the bridging itself could fail. Fixing this fixes SR-2920|rdar://problem/31404281.
In particular, it doesn't "toll-free bridge" to the Error existential on non-ObjC-interop platforms, and we would miscompile as if it could. This should fix SR-585.
Most of this involved sprinkling ValueOwnershipKind::Owned in many places. In
some of these places, I am sure I was too cavalier and I expect some of them to
be trivial. The verifier will help me to track those down.
On the other hand, I do expect there to be some places where we are willing to
accept guaranteed+trivial or owned+trivial. In those cases, I am going to
provide an aggregate ValueOwnershipKind that will then tell SILArgument that it
should disambiguate using the type. This will eliminate the ackwardness from
such code.
I am going to use a verifier to fix such cases.
This commit also begins the serialization of ValueOwnershipKind of arguments,
but does not implement parsing of value ownership kinds. That and undef are the
last places that we still use ValueOwnershipKind::Any.
rdar://29791263
The typedef `swift::Module` was a temporary solution that allowed
`swift::Module` to be renamed to `swift::ModuleDecl` without requiring
every single callsite to be modified.
Modify all the callsites, and get rid of the typedef.
If a Swift type T needs to be casted to a CF type, then we first cast T to its bridged NS type and then ref_cast the result to a corresponding CF type.
For example, if we need to cast String to CFString, we first cast String to NSString and then ref_cast the NSString to CFString.
Fixes rdar://problem/29745498
Not sure why but this was another "toxic utility method".
Most of the usages fell into one of three categories:
- The base value was always non-null, so we could just call
getCanonicalType() instead, making intent more explicit
- The result was being compared for equality, so we could
skip canonicalization and call isEqual() instead, removing
some boilerplate
- Utterly insane code that made no sense
There were only a couple of legitimate uses, and even there
open-coding the conditional null check made the code clearer.
Also while I'm at it, make the SIL open archetypes tracker
more typesafe by passing around ArchetypeType * instead of
Type and CanType.
We preserve the current behavior of assuming Any ownership always and use
default arguments to hide this change most of the time. There are asserts now in
the SILBasicBlock::{create,replace,insert}{PHI,Function}Argument to ensure that
the people can only create SILFunctionArguments in entry blocks and
SILPHIArguments in non-entry blocks. This will ensure that the code in tree
maintains the API distinction even if we are not using the full distinction in
between the two.
Once the verifier is finished being upstreamed, I am going to audit the
createPHIArgument cases for the proper ownership. This is b/c I will be able to
use the verifier to properly debug the code. At that point, I will also start
serializing/printing/parsing the ownershipkind of SILPHIArguments, but lets take
things one step at a time and move incrementally.
In the process, I also discovered a CSE bug. I am not sure how it ever worked.
Basically we replace an argument with a new argument type but return the uses of
the old argument to refer to the old argument instead of a new argument.
rdar://29671437
Changes:
* Terminate all namespaces with the correct closing comment.
* Make sure argument names in comments match the corresponding parameter name.
* Remove redundant get() calls on smart pointers.
* Prefer using "override" or "final" instead of "virtual". Remove "virtual" where appropriate.