Consider code like:
```
// Foo.h
typealias NSString * FooKey NS_EXTENSIBLE_TYPED_ENUM;
// Foo.swift
extension FooKey { … }
```
When Swift binds the extension to `FooKey`, that forces ClangImporter to import `FooKey`. ClangImporter’s newtype logic, among other things, checks whether the underlying type (`Swift.String` here) is Objective-C bridgeable and, if so, makes `FooKey` bridgeable too.
But what happens if this code is actually *in* Foundation, which is where the `extension String: _ObjectiveCBridgeable` lives? Well, if the compiler has already bound that extension, it works fine…but if it hasn’t, `FooKey` ends up unbridgeable, which can cause both type checking failures and IRGen crashes when code tries to use its bridging capabilities. And these symptoms are sensitive to precise details of the order Swift happens to bind extensions in, so e.g. adding empty files to the project can make the bug appear or disappear. Spooky.
Add a narrow hack to ClangImporter (only active for types in Foundation) to *assume* that `String` is bridgeable even if the extension declaring this hasn’t been bound yet.
Fixes rdar://142693093.
10.50 was once greater than any real macOS version, but now it compares
less than real released versions, which makes these tests depend on the
deployment target unnecessarily. Update these tests to use even larger
numbers to hopefully keep them independent a little longer.
This change introduces a new compilation target platform to the Swift compiler - visionOS.
- Changes to the compiler build infrastrucuture to support building compiler-adjacent artifacts and test suites for the new target.
- Addition of the new platform kind definition.
- Support for the new platform in language constructs such as compile-time availability annotations or runtime OS version queries.
- Utilities to read out Darwin platform SDK info containing platform mapping data.
- Utilities to support re-mapping availability annotations from iOS to visionOS (e.g. 'updateIntroducedPlatformForFallback', 'updateDeprecatedPlatformForFallback', 'updateObsoletedPlatformForFallback').
- Additional tests exercising platform-specific availability handling and availability re-mapping fallback code-path.
- Changes to existing test suite to accomodate the new platform.
Clang Importer strips prefixes from enum and option set case names. The logic to do this computes a common prefix from the type name and all non-deprecated case names (to oversimplify), which means that adding, removing, or changing one case can change the prefix that is removed from *all* cases. This typically causes the prefix to become shorter, meaning that additional words are prepended to each existing case name.
Existing diagnostics make it look like the case has disappeared, when in fact it still exists under a different name. A little more information may help developers to figure out what happened.
Add a tailored diagnostic for this scenario which kicks in when (a) a missing member is diagnosed, (b) the base is an imported enum or option set’s metatype, and (c) an enum case or static property exists which has the name we attempted to look up as a suffix.
Fixes rdar://116251319.
The `isBoolType` operation within the Clang importer has a historical
definition that excludes the C++ `bool` and its use in C as an
extension. Retain that definition, and check for the actual `bool`
when importing C++ conversion functions into Swift.
Fixes two regressions in the Clang importer:
1. We started to import `bool`-typed Objective-C properties with their
getter names.
2. We started importing `bool`-typed Objective-C methods with an
NSError** parameter as `throws`.
Both of these changes could be considered improvements, but they
cannot be made without breaking source compatibility, so roll those
changes back to maintain source compatibility.
We should have a separate discussion about enabling this behavior for
Swift >= 6.
[CodeCompletion] Make ExpectedTypeContext a class with explicit getters/setters
This simplifies debugging because you can break when the possible types are set and you can also search for references to `setPossibleType` to figure out where the expected types are being set.
Detect that result type of the overload choice is l-value and preserve
that information through the forced unwrap operation so it's possible
to load the value implicitly during solution application.
Resolves: rdar://problem/61337704
We were failing to bind the alternatives for an IUO @optional
requirement because we forgot to set the appropriate type variable option.
Fixes: rdar://problem/40868990
When trying to figure out errors from an import failure, the nullability
completeness warnings would clutter the output making it difficult to
identify the errors. Sprinkle the declaarations with
`_Null_unspecified` to maintain the current nullability semantics and
silence the warnings. NFC.
Avoid a temporary file and executing FileCheck multiple types and prefer
multiple check prefixes and streaming. Additionally, enable some of
previously XFAIL'ed tests on Linux as well as tests that were marked as
requiring Objective-C interop.
We want to treat arguments to ObjC override and protocol conformance thunks like "call results", since they might be called from ObjC code that doesn't fulfill its nullability promises in practice. Fixes SR-7240 | rdar://problem/38675815.
This allows them to be used in generic arguments for NSArray et al.
We already do this for the ones that wrap bridged values (like
NSString/String), but failed to do it for objects that /weren't/
bridged to Swift values (class instances and protocol compositions),
or for Error-which-is-special.
In addition to this being a sensible thing to do, /not/ doing this led
to IRGen getting very confused (i.e. crashing) when we imported a
Objective-C protocol that actually used an NS_TYPED_ENUM in this way.
(We actually shouldn't be using Swift's IRGen logic to emit protocol
descriptors for imported protocols at all, because it's possible we
weren't able to import all the requirements. But that's a separate
issue.)
https://bugs.swift.org/browse/SR-6844
We were not handling IUO results of @optional protocol methods
properly, sometimes forcing the @optional requirement rather than the
result of the call.
Fixes rdar://problem/37240984.
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.
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
Use the modern spelling for the nullability attributes in the test mock
headers. Currently, this was relying on the predefined macros from
clang to work. However, those are only available on Darwin targets.
This is needed to make the mock environments more portable.
When performing a lookup into a class C, we might find a member of
C that witnesses a requirement in a protocol Q that C conforms to.
In this case, AST name lookup returns both results.
There are two further levels of fitering which can eliminate the
ambiguity:
- Sema name lookup maps requirements to witnesses if the base type
of the lookup is a nominal type or a class-constrained archetype.
Imported conformances don't have this mapping recorded, but there's
another hack in this code path where if a requirement maps to
itself inside a conformance, it is dropped from the results
altogether.
- If the duplicate results were not filtered out in Sema name lookup,
there was another hack in CSRanking which would a witness higher
than it's requirement when comparing solutions. This doesn't work
for imported conformances, but usually name lookup filters out
the duplicate results sooner, which also eliminates the exponential
behavior from having multiple constraint system solutions.
However, if we have a subclass existential C & P where C conforms
to Q and we find a member of C that witnesses a requirement of Q,
then (C & P) does not conform to Q.
So if the conformance was imported, *both* of the above checks
would fail to disambiguate the witness and requirement, and the
member access would fail to type check.
To make this work with imported conformances, teach Sema name lookup
to extract the superclass from an existential before performing the
conformance check. If the conformance check fails, it means we
found the protocol member via the 'existential' part of the subclass
existential (eg, in our case, a member of P), and we proceed as
before.
Fixes <rdar://problem/33291112>.
just for pointer identity.
The current technique for deciding whether that's the case is *extremely*
hacky and need to be replaced with an attribute, but I'm reluctant to
take that on so late in the schedule. The hack is terrible but not too
hard to back out in the future. Anyone who names a method like this just
to get the magic behavior knows well that they are not on the side of
righteousness.
rdar://33265254
conversions that reverse an implicit conversion done to align
foreign declarations with their imported types.
For example, consider an Objective-C method that returns an NSString*:
- (nonnull NSString*) foo;
This will be imported into Swift as a method returning a String:
func foo() -> String
A call to this method will implicitly convert the result to String
behind the scenes. If the user then casts the result back to NSString*,
that would normally be compiled as an additional conversion. The
compiler cannot simply eliminate the conversion because that is not
necessarily semantically equivalent.
This peephole recognizes as-casts that immediately reverse a bridging
conversion as a special case and gives them special power to eliminate
both conversions. For example, 'foo() as NSString' will simply return
the original return value. In addition to call results, this also
applies to call arguments, property accesses, and subscript accesses.
Somehow the logic had slipped so that we were basing this decision purely
on the ImportTypeKind and not on whether the broader context is bridgeable.
This was allowing us to use bridged types when e.g. importing the results
and parameters of C function pointer types, which is really bad.
Also, when importing a reference to a typedef of block type, do not use
the typedef in a non-bridgeable context. We import typedefs of block type
as fully-bridged types, but this means that it is invalid to import a type
using the typedef in a context where the original C type must be used.
Similarly, make sure we use a properly-imported underlying type of the
typedef when the typedef itself is unavailable.
Also, extend the special behavior of block typedefs to abstract-function
typedefs, which seems to be consistent with the expected behavior of the
tests.
Finally, I changed importType to take a new Bridgeability enum instead of
a raw canFullyBridgeTypes bool. At the time, I was doing that because I
was going to make it tri-valued; that turned out to be unnecessary, but I
think it's an improvement anyway.
Ever since we stopped associating the top-level struct of an imported
NS_ERROR_ENUM with the Clang enum declaration, we've been unable to
print imported NS_ERROR_ENUMs. The module-printing infrastructure
would drop them thinking they aren't imported declarations.
This also affected NS_ERROR_ENUMs that were imported as members of
another type, as well as other types imported as members.
Fixes rdar://problem/32497693.
In Swift 3, an Objective-C type like SomeClass <SomeProtocol> is
imported as SomeClass. The protocol qualification is erased unless
the class bound is 'id' or 'Class'.
Importing such types as class-constrained existentials is a source
breaking change, so the new behavior is only enabled in Swift 4
mode.
Furthermore as a transitional step the staging flag
-enable-experimental-subclass-existentials has to be passed in
also. The flag will soon be removed.
This writeback scope's writeback is handled by the ArgumentScope for argument
emission. Since the scope will be destroyed after argument scope, we get
mismatched scope depths.
rdar://31313534
...and avoid making aliases from one unavailable declaration to another.
If it's unavailable, we can just import it as a normal case and not
worry about it. This fixes an issue where Sema would try to diagnose
the body of an "alias" for referring to unavailable declarations.
(Background: enum cases in Swift have to have unique values, so we
import any duplicate values as static properties. Pattern matching
logic has a hack to recognize these particular static properties as
being "case-like".)
This commit also sinks enum element uniqueness checking into importing
the enum, instead of keeping a global map we never consult again. This
should save a small bit of memory.
rdar://problem/30025723
Previously, for an Objective-C class method declaration that could be
imported as init, we were making 4 decls:
1) The Swift 2 init
2) The Swift 2 class method decl (suppressing init formation)
3) The Swift 3 init (omitting needless words)
4) The Swift 3 class method decl (suppressing init formation and
omitting needless words)
Decls 1), 2), and 4) exist for diagnostics and redirect the user at
3). But, 4) does not correspond to any actual Swift version name and
producing it correctly would require the user to understand how
omit-needless-words and other importer magic operates. It provides
very limited value and more importantly gets in the way of future
Clang importer refactoring. We’d like to turn Decl importing into
something that is simpler and language-version parameterized, but
there is no real Swift version to correspond to decl 4).
Therefore we will be making the following decls:
1) The "raw" decl, the name as it would appear to the user if they
copy-pasted Objective-C code
2) The name as it appeared in Swift 2 (which could be an init)
3) The name as it appeared in Swift 3 (which could be an init and omit
needless words)
This aligns with the language versions we want to import as in the
future: raw, swift2, swift3, …, and current.
Note that swift-ide-test prunes decls that are unavailable in the
current Swift version, so the Swift 2 non-init decls are not printed
out, though they are still present. Tests were updated and expanded to
ensure this was still the case.
Attempting to throw an error code value, e.g.,
throw CocoaError.fileNoSuchFileError
is now ill-formed, although it was well-formed prior to the
introduction of NSError bridging (SE-0112). Provide a specialized
diagnostic with a Fix-It to add the appropriate parentheses:
throw CocoaError(.fileNoSuchFileError)
Fixes rdar://problem/27543121.
* [ClangImporter] Remove importer-based NS stripping.
As Tony puts it, in the end we wound up with more Foundation
declarations imported as members or keeping "NS" than those that
dropped it, and any further decisions will be made on a case-by-case
basis. Move all of the existing cases of prefix-stripping into
Foundation's API notes and drop the logic from the compiler.
Tested by dumping the generated interface for Foundation and its
submodules for both macOS and the iOS simulator, and comparing the
results. A few cases did slip through here because of the interaction
between "SwiftName" and "Availability: nonswift".
The next commit will re-add "NS" to some stragglers that we missed.
rdar://problem/26880017
* APINotes: Add "NS" back to a few types.
NSKeyedUnarchiverDelegate
NSKeyedArchiverDelegate
NSTextCheckingTypes
NSBinarySearchingOptions
NSEnumerationOptions
NSSortOptions
More rdar://problem/26880017
* Remove now-redundant SwiftNames from API notes.
No change observed in the generated interface of Foundation and its
submodules.
Finishes rdar://problem/26880017.
Introduce bridging of NSError to ErrorProtocol, so an Objective-C API
expressed via an "NSError *" will be imported using ErrorProtocol in
the Swift. For example, the Objective-C method:
- (void)handleError:(NSError *)error userInteractionPermitted:(BOOL)userInteractionPermitted;
will now be imported as:
func handleError(_ error: ErrorProtocol, userInteractionPermitted: Bool)
This is bullet (3) under the proposed solution of SE-0112. Note that
we made one semantic change here: instead of removing the conformance
of NSError to ErrorProtocol, which caused numerous problems both
theoretical and actual because the model expects that an NSError
conforms to ErrorProtocol without requiring wrapping, we instead limit
the ErrorProtocol -> NSError conversion that would be implied by
bridging. This is defensible in the short term because it also
eliminates the implicit conversion, and aligns with SE-0072, which
eliminates implicit bridging conversions altogether.
When we have an argument expr of type Any that's being emitted as a bridged ObjC object parameter, look through any ErasureExprs and directly bridge the concrete value. This saves us emitting an intermediate 'Any' value in the common case where a value of known concrete type is passed in from Swift.
We map clang::AvailabilityAttr::getReplacement() to
swift::AvailableAttr::Rename, transforming the replacement
name using by looking up the named Clang replacement, and
importing its name.
Fixes <rdar://problem/26301742>.
We were failing to create an unavailable TypeAlias for the old name
in the case the renamed type was generic, leading to poor diagnostics.
Also, Sema resolves generic TypeAliases very early, while building
a Type from a TypeRepr -- this means the unavailable/deprecated
check runs too late to catch generic TypeAlises.
Add a hack where we preserve a reference to the original TypeAliasDecl
by way of constructing a SubstitutedType which desugars to the
replacement type, rather than resolving the replacement type
directly, so that the availability check can pick it up.
A better fix for this would be to introduce a BoundGenericAliasType
sugared type, but that's a bigger change that can come later.
Fixes <rdar://problem/26206263>.
We now specially import global decls who we identify as fitting the
notification pattern: extern NSStrings whose name ends in
"Notification". When we see them, we import them as a member of
NSNotificationName and, if NSNotificationName is swift_newtype-ed, we
use that new type.
Test cases included.
This is a squash of the following commits:
* [SE-0054] Import function pointer arg, return types, typedefs as optional
IUOs are only allowed on function decl arguments and return types, so
don't import typedefs or function pointer args or return types as IUO.
* [SE-0054] Only allow IUOs in function arg and result type.
When validating a TypeRepr, raise a diagnostic if an IUO is found
anywhere other thn the top level or as a function parameter or return
tpye.
* [SE-0054] Disable inference of IUOs by default
When considering a constraint of the form '$T1 is convertible to T!',
generate potential bindings 'T' and 'T?' for $T1, but not 'T!'. This
prevents variables without explicit type information from ending up with
IUO type. It also prevents implicit instantiation of functions and types
with IUO type arguments.
* [SE-0054] Remove the -disable-infer-iuos flag.
* Add nonnull annotations to ObjectiveCTests.h in benchmark suite.
When importing members of an NS_OPTIONS (aka an option set), mark imported
members that have a value of 0 with an unavailable error. This produces an
experience like this:
x = NSRuncingOptions.none // expected-error {{'none' is unavailable: use [] to construct an empty option set}}
This is important to do, because option set members with a value of zero
do not act like members of the option set. For example, they always fail a
"contains" check.