…at least in the specific case of initializers.
Normally, clang validates that a SwiftNameAttr’s specified name seems to have the right number of argument labels for the declaration it’s applied to; if it doesn’t, it diagnoses and drops the attribute. However, this checking isn’t perfect because clang doesn’t know all of Clang Importer’s throwing rules. The upshot is that it’s possible to get a mismatched SwiftNameAttr into Clang Importer if the last parameter looks like an out parameter. This trips an assertion in asserts compilers, but release compilers get past that and don’t seem to notice the mismatch at all.
Add code to the compiler to tolerate this condition, at least in initializers, by modifying the Swift name to have the correct number of argument labels and deprecating the declaration with a message explaining the problem.
Fixes rdar://141124373.
We used to diagnose references to unavailable declarations in
two places:
- inside Exprs, right after type checking the expression
- inside TypeReprs, from resolveType()
In broad terms, resolveType() is called with TypeReprs
stored inside both Stmts and Decls.
To handle the first case, I added a new overload of
diagAvailability() that takes a Stmt, to be called from
typeCheckStmt(). This doesn't actually walk into any Exprs
stored inside the statement; this means it only walks
Patterns and such.
For the second case, a new DeclAvailabilityChecker is
now defined in TypeCheckAccess.cpp. It's structure is
analogous to the other three walkers there:
- AccessControlChecker
- UsableFromInlineChecker
- ExportabilityChecker
The new implementation of availability checking for types
introduces a lot more code than the old online logic
it replaces. However, I hope to consolidate some of the
code duplication among the four checkers that are defined
in TypeCheckAccess.cpp, and do some other cleanups that
will make the benefit of the new approach apparent.
Continue to emit notes for the candidates, but use different text.
Note that we can emit a typo correction fix-it even if there are
multiple candidates with the same name.
Also, disable typo correction in the migrator, since the operation
is quite expensive, the notes are never presented to the user, and
the fix-its can interfere with the migrator's own edits.
Our general guidance is that fix-its should be added on the main
diagnostic only when the fix-it is highly likely to be correct.
The exact threshold is debateable. Typo correction is certainly
capable of making mistakes, but most of its edits are right, and
when it's wrong it's usually obviously wrong. On balance, I think
this is the right thing to do. For what it's worth, it's also
what we do in Clang.
Previously this (1) did not work (the constant just disappeared), and
(2) would actually crash if the destination context was a class.
rdar://problem/32208235