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.
Instead, just emit a deprecation warning and suggest switching to Optionals.
The old behavior caused several projects to break, so before we change
the behavior here we need to investigate whether we can mitigate most
of those breaks.
For Swift 3 / 4:
Deprecate the spelling "ImplicitlyUnwrappedOptional", emitting a warning
and suggesting "!" in places where they are allowed according to
SE-0054.
In places where SE-0054 disallowed IUOs but we continued to accept them
in previous compilers, emit a warning suggesting "Optional" or "?" as
an alternative depending on context and treat the IUO as an Optional,
noting this in the diagnostic.
For Swift 5:
Treat "ImplicitlyUnwrappedOptional" as an error, suggesting
"!" in places where they are allowed by SE-0054.
In places where SE-0054 disallowed IUOs, emit an error suggestion
"Optional" or "?" as an alternative depending on context.
Previously, we only handle dot syntax call expression for qualified
replacement, i.e. changing from A.a to B.b. This patch teaches the tool
to handle the migration of member reference expression tool.
Post-commit review follow-up:
This works better for properties that were all-caps, such as `URL`.
Thanks @harlanhaskins for the tip!
rdar://problem/32845968
AST passes assume that you are migrating from a version earlier
than Swift 4, where declaration references and type names may be
unconditionally renamed if their USRs match.
For example, this can happen for TypeMemberDiffItem entries where the
Objective-C USR is the same in Swift 3 and Swift 4, but the type is
spelled differently in Swift 4. A concrete example of this is:
`NSDocumentTypeDocumentAttribute` (Swift 3) ->
`NSAttributedString.DocumentAttributeKey` (Swift 4).
Although this declaration is imported differently in Swift 4, its
Objective-C USR is `c:@NSDocumentTypeDocumentAttribute` for both.
rdar://problem/32604558
In https://github.com/apple/swift/pull/10414, some SE-0110 features
were backed out, so the Migrator no longer needs to add `$0` shorthand
prefixing.
rdar://problem/32907276
Some changes for SE-0110 were backed out in
https://github.com/apple/swift/pull/10414, so the migrator no longer
needs to add its own tuple destructuring.
rdar://problem/32513074
The migrator pass that converts single-argument function input types
doesn't handle the case when the function input has a label and is
therefore a tuple. Expand it to handle that possibility.
rdar://problem/32477319
If a file is run through the migration workflow a second or third time,
but fails to compile in its current state in Swift 4, it might be possible
for the previous remap file to get picked up, resulting in the old changes
getting applied twice or at the wrong offsets. At the start of the migration,
proactively remove the remap file to prevent this.
rdar://problem/32545844
We already had this functionality in the FixitApplyDiagnosticConsumer,
but we also need it in the AST passes because different entries in the
API diff data may drive identical fix-its, namely a general type rename,
which can occur anywhere a DeclRef appears, but also for function overrides'
parameter type changes, which are context specific.
rdar://problem/32431533
Setting up an invocation adds -aarch64-use-tbi if the target is for
AArch64. In the fix-it passes, we inherit the frontend options which
already has it from the driver passing it down to the frontend.
rdar://problem/32284152
The clang::RewriteBuffer can do weird things when seeing multiple
replacements where the replacement text is one character longer or
one character shorter than the range it is replacing.
rdar://problem/32234525
The migrator pass to add tuple destructuring that now needs to add a
`return` statement for closures that were once single-expression but are
no longer because of the added statement to do the binding.
rdar://problem/32433206
This can be incorrectly reported by the type-checker when
argument arity doesn't match in trailing closure arguments.
This diagnostic isn't generally useful for the migrator.
rdar://problem/32477119
rdar://problem/32432254
This isn't generally useful for Swift 4 migration and in some cases
can result in code that doesn't compile, like `for let i in ...`.
rdar://problem/32390791
rdar://problem/32390726
We used to only migrate them in call sites, e.g. changing from
``p.getHeight()`` to ``p.Height``. However, with experimenting on more real-world
projects, we realize migrating overrides is equally important.
rdar://32265583