The migrator only applies changes from the APIDiffMigratorPass in the primary
file. This means that if a nominal type was renamed, for example, any members
users have added in an extension in a separate file won't be visible, because
the extension would still have the old name. This can result in 'wrong argument
label' errors with fixits to change the argument labels that, when applied by
the fixit pass, completely change which function was being called and cause
post-migration errors.
This patch updates the fixit pass to ignore diag::wrong_argument_labels.
diag::extra_argument_labels and diag::missing_argument_labels were already
filtered out for other reasons.
Resolves rdar://problem/40170377
The APIDiffMigrator pass was ignoring them in all cases, but function type
argument parens are significant and the API differ includes them as an index
level in the generated json. This was causing a segmentation fault when trying
to migrate anything inside a function type argument. E.g given the function
below:
func member(_ x: ([Any]?) -> Void) {}
to migrate Any to Int, the API differ produces an index into the signauture of
1:1:0:0:0, meant to indicate Any. The APIDiffMigratorPass was interpreting this
incorrectly, however:
1: The type of first parameter of member: ([Any]?) -> Void
Migrator agreed.
1: The type of the function type's argument: ([Any]?)
Migrator saw this as [Any]? due to the parens not being an index level
0: The 0th child of the paren type: [Any]?
Migrator saw the 0th child of the optional, [Any]
0: the 0th child of the optional type, [Any]
Migrator saw the 0th child of the array, Any
0: the 0th child of the array type, Any
Migrator tried to look up the 0th child of Any, causing a crash.
Resolves rdar://problem/40225476.
They were always enabled, meaning migrating from Swift 4 -> 4.2 would pick up
the associated fixits and add @objc unnecessarily in many places.
Resolves rdar://problem/39951671
When users' codebase assigns an attribute dictionary that used to be of
type [String: Any], this migration inserts a helper function call on the source of
the assignment to bridge the type.
For a function call used to take [String: Any]? as argument and now
takes [StringRepresentableStruct: Any]?, a helper function is inserted
to help the bridging of types.
When a user's code calls a function that used to take [String: Any] as
argument and now takes [StringRepresentableStruct: Any], this migration
inserts a helper function to convert the argument to the
expected type.
This patch migrates simple attribute assignment and reference when the
attribute used to be of type String and later became StringRepresentable struct.
Related: rdar://38192995
To support migration from both Swift 3 and 4, this patch
teaches the driver to pick up the right set of migration scripts
according to the given Swift version. We also pushed some placeholder script
files for migration from Swift 4. This patch also brings the migrator
up-to-date by avoiding migration if the Swift version is already 4.2.
This was broken by a recent commit, but because it only runs with
arch=arm64 it was missed (it can be run with lit parameter
swift_test_mode=only_non_executable).
rdar://38248707
This converts the instances of the pattern for which we have a proper
substitution in lit. This will make it easier to replace it
appropriately with Windows equivalents.
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