Refutable pattern initializations require that the 'isInit' parameter
is set to true, which transfers ownership of the input value.
One way it was getting set to false was when the pattern was bound to
an expression containing OpaqueValueExprs.
The opaque value of an open existential is +0, but that can't show
up here; only the result of a tuple conversion can. In principle this
is always a +1 value, however it could also be trivial, and we were
incorrectly treating it as a +0 value. We need to check isPlusOne()
instead of hasCleanup(); the latter returns false for trivial values.
Doing this lets us avoid going through the initialization altogether.
Fixes <rdar://problem/56809385>.
ProtocolConformanceRef already has an invalid state. Drop all of the
uses of Optional<ProtocolConformanceRef> and just use
ProtocolConformanceRef::forInvalid() to represent it. Mechanically
translate all of the callers and callsites to use this new
representation.
Structurally prevent a number of common anti-patterns involving generic
signatures by separating the interface into GenericSignature and the
implementation into GenericSignatureBase. In particular, this allows
the comparison operators to be deleted which forces callers to
canonicalize the signature or ask to compare pointers explicitly.
This mostly requires changing various entry points to pass around a
TypeConverter instead of a SILModule. I've left behind entry points
that take a SILModule for a few methods like SILType::subst() to
avoid creating even more churn.
Add `llvm_unreachable` to mark covered switches which MSVC does not
analyze correctly and believes that there exists a path through the
function without a return value.
OpaqueValueState used to store a SILValue, so back then the IsConsumable flag
was meaningful. But now we can just check if the ManagedValue has a cleanup
or not.
Also, we were passing around an opened ArchetypeType for no good reason.
The ownership kind is Any for trivial types, or Owned otherwise, but
whether a type is trivial or not will soon depend on the resilience
expansion.
This means that a SILModule now uniques two SILUndefs per type instead
of one, and serialization uses two distinct sentinel IDs for this
purpose as well.
For now, the resilience expansion is not actually used here, so this
change is NFC, other than changing the module format.
To make that work, enter appropriate scopes (ArgumentScopes and
FormalEvaluationScopes) at a bunch of places. But note that l-value
emission generally can't enter such a scope, so in generic routines
like emitOpenExistentialExpr we have to just assert that we're
already in a scope.
Delay allocating the result buffer for an opened Self return until right before it's needed. When a mutating method is invoked on an existential, the Self type won't be opened until late, when the formal access to the mutable value begins. Fixes rdar://problem/43507711.
Modifies SILGen and the `Swift._diagnoseUnexpectedNilOptional` call to print a slightly different message for force unwraps which were implicitly inserted by the compiler for IUOs. The message is chosen based on the presence of certain flags in the `ForceValueExpr`, not on the type of the value being unwrapped.
In general, SILGen assumes that only +1 values are "forwarded" into memory. This
is because we want any value that is stored in memory to not be dependent on
other values and for the forwarded object to be able to maintain its own
liveness. So this assert was correct to fire.
The specific test case that exposed this issue is:
What happened here is that we needed to reabstract a loadable value into an
existential and tried to maximally abstract it and thus store it into
memory. The That code was never updated to make sure the value was at +1. So we
would store a guaranteed value into memory and hope that whereever we stored it
doesn't escape the current function. In this case, I believe that we would be
safe... but past returns are not indicators of future results.
rdar://40773543
SR-7858
Replace two prominent uses of SubstitutionList, in ConcreteDeclRef and
Witness, with SubstitutionMap. Deal with the myriad places where we
now have substitution maps and need substitution lists (or vice versa)
caused by this change.
Overall, removes ~50 explicit uses of SubstitutionList (of ~400).
This assumption is already in the code here. My change just makes it so that
when we perform optional-to-optional on a +0 argument, we copy before the
transform.
Caught via the ownership verifier when updating test/SILGen/objc_blocks_bridging.swift for +0 arguments.
rdar://34222540
Previously SwitchEnumBuilder was in SILGenBuilder.{h,cpp} and
SwitchEnumCaseFullExpr was in its own file. This really made no sense since:
1. The two classes are inherently related to each other so really should be
together in the source base.
2. SwitchEnumBuilder uses a SILGenBuilder, but is really a separate independent
concept/entity, so there really is no reason to keep it in SILGenBuilder.cpp.
Just a quick fix to eliminate something that was bugging me.
NFC.
This commit does two different things:
1. Changes some code paths in SILGenConvert to use SILGenBuilder APIs.
2. It eliminates a few bugs in this path exposed by running the SILGen tests
with +0 enabled.
The bug specifically is that we are assuming in this code that the input value
is always at +1, so we unconditionally forward the input value and then create
destroys on the output. This is not correct in general (since we have guaranteed
values) and occurs all the time with +0 arguments enabled.
This is tested by running the SILGen tests with +0 arguments enabled.
rdar://34222540
Stop creating ImplicitlyUnwrappedOptional<T> so that we can remove it
from the type system.
Enable the code that generates disjunctions for Optional<T> and
rewrites expressions based on the original declared type being 'T!'.
Most of the changes supporting this were previously merged to master,
but some things were difficult to merge to master without actually
removing IUOs from the type system:
- Dynamic member lookup and dynamic subscripting
- Changes to ensure the bridging peephole still works
Past commits have attempted to retain as much fidelity with how we
were printing things as possible. There are some cases where we still
are not printing things the same way:
- In diagnostics we will print '?' rather than '!'
- Some SourceKit and Code Completion output where we print a Type
rather than Decl.
Things like module printing via swift-ide-test attempt to print '!'
any place that we now have Optional types that were declared as IUOs.
There are some diagnostics regressions related to the fact that we can
no longer "look through" IUOs. For the same reason some output and
functionality changes in Code Completion. I have an idea of how we can
restore these, and have opened a bug to investigate doing so.
There are some small source compatibility breaks that result from
this change:
- Results of dynamic lookup that are themselves declared IUO can in
rare circumstances be inferred differently. This shows up in
test/ClangImporter/objc_parse.swift, where we have
var optStr = obj.nsstringProperty
Rather than inferring optStr to be 'String!?', we now infer this to
be 'String??', which is in line with the expectations of SE-0054.
The fact that we were only inferring the outermost IUO to be an
Optional in Swift 4 was a result of the incomplete implementation of
SE-0054 as opposed to a particular design. This should rarely cause
problems since in the common-case of actually using the property rather
than just assigning it to a value with inferred type, we will behave
the same way.
- Overloading functions with inout parameters strictly by a difference
in optionality (i.e. Optional<T> vs. ImplicitlyUnwrappedOptional<T>)
will result in an error rather than the diagnostic that was added
in Swift 4.1.
- Any place where '!' was being used where it wasn't supposed to be
allowed by SE-0054 will now treat the '!' as if it were '?'.
Swift 4.1 generates warnings for these saying that putting '!'
in that location is deprecated. These locations include for example
typealiases or any place where '!' is nested in another type like
`Int!?` or `[Int!]`.
This commit effectively means ImplicitlyUnwrappedOptional<T> is no
longer part of the type system, although I haven't actually removed
all of the code dealing with it yet.
ImplicitlyUnwrappedOptional<T> is is dead, long live implicitly
unwrapped Optional<T>!
Resolves rdar://problem/33272674.
The problem was that the unreachable instruction after the IUO unwrapping error call was interpreted as missing-return-unreachable.
rdar://problem/36611041
at AnyObject?.
Also, ensure that @convention(block) functions can be erased to
AnyObject, and teach SILGen how to do this with unchecked_ref_cast.
Fixes a source compatibility suite regression.
It additionally removes some code from SILGenBuilder::createUncheckedEnumData
that introduced extra borrows. That is really the builder's caller's
responsibility. Plus, it isn't that hard to do anymore now that one can just
call ManagedValue::borrow.
rdar://34222540
Also, fix some logic in the peephole that was incorrectly recognizing
T? -> U? -> AnyObject as a force instead of a request to create NSNull.
In both cases, we ought to still be able to do much better than the
unpeepholed code by just applying the peephole and then merging in NSNull
in the nil case, but in the short term we need to fix this bug.
Fixes rdar://35402853
This rename makes since since:
1. This is SILGen specific functionality.
2. In the next commit I am going to be adding a SIL SavedInsertionPoint class. I
want to make sure the two can not be confused.
When we peephole away a bridge from Objective-C followed by a
bridge to Objective-C where the destination type is AnyObject,
we need to force the source value if it was an optional.
Fixes <rdar://problem/33669575>.
These instructions have the same semantics as the *ExistentialAddr instructions
but operate directly on the existential value, not its address.
This is in preparation for adding ExistentialBoxValue instructions.
The previous name would cause impossible confusion with "opaque existentials"
and "opaque existential boxes".