Implements SE-0055: https://github.com/apple/swift-evolution/blob/master/proposals/0055-optional-unsafe-pointers.md
- Add NULL as an extra inhabitant of Builtin.RawPointer (currently
hardcoded to 0 rather than being target-dependent).
- Import non-object pointers as Optional/IUO when nullable/null_unspecified
(like everything else).
- Change the type checker's *-to-pointer conversions to handle a layer of
optional.
- Use 'AutoreleasingUnsafeMutablePointer<NSError?>?' as the type of error
parameters exported to Objective-C.
- Drop NilLiteralConvertible conformance for all pointer types.
- Update the standard library and then all the tests.
I've decided to leave this commit only updating existing tests; any new
tests will come in the following commits. (That may mean some additional
implementation work to follow.)
The other major piece that's missing here is migration. I'm hoping we get
a lot of that with Swift 1.1's work for optional object references, but
I still need to investigate.
Migrate the check for whether a given type is representable in
Objective-C, which is currently used to verify when @objc can be
inferred or verify that an explicitly-written @objc is well-formed,
from Sema into a set of queries on the Type within the AST library, so
it can be used in other parts of the compiler.
As part of this refactoring, clean up and improve a number of aspects
of this code:
* Unify the "trivially representable" and "representable" code paths
into a single code path that covers these cases. Clarify the
different levels of "representable" we have in both the code and
in comments.
* Distinguish between representation in C vs. representation in
Objective-C. While we aren't using this now, I'm anticipating it
being useful to allow exporting C interfaces via @_cdecl (or
similar).
* Eliminate the special cases for bridging String/Array/Dictionary/Set
with their Foundation counterparts; we now consult
_ObjectiveCBridgeable conformances exclusively to get this
information.
* Cache foreign-representation information on the ASTContext in a
manner that will let us more easily get the right answer across
different contexts while providing more sharing than the TypeChecker
version.
Annoyingly, this only seemed to fix a small class of error where we
were permitting Unsafe(Mutable)Pointer<T> to be representable in
Objective-C when T was representable but not trivially representable,
e.g., T=String or T=AnyObject.Type.
Parse 'var [behavior] x: T', and when we see it, try to instantiate the property's
implementation in terms of the given behavior. To start out, behaviors are modeled
as protocols. If the protocol follows this pattern:
```
protocol behavior {
associatedtype Value
}
extension behavior {
var value: Value { ... }
}
```
then the property is instantiated by forming a conformance to `behavior` where
`Self` is bound to the enclosing type and `Value` is bound to the property's
declared type, and invoking the accessors of the `value` implementation:
```
struct Foo {
var [behavior] foo: Int
}
/* behaves like */
extension Foo: private behavior {
@implements(behavior.Value)
private typealias `[behavior].Value` = Int
var foo: Int {
get { return value }
set { value = newValue }
}
}
```
If the protocol requires a `storage` member, and provides an `initStorage` method
to provide an initial value to the storage:
```
protocol storageBehavior {
associatedtype Value
var storage: Something<Value> { ... }
}
extension storageBehavior {
var value: Value { ... }
static func initStorage() -> Something<Value> { ... }
}
```
then a stored property of the appropriate type is instantiated to witness the
requirement, using `initStorage` to initialize:
```
struct Foo {
var [storageBehavior] foo: Int
}
/* behaves like */
extension Foo: private storageBehavior {
@implements(storageBehavior.Value)
private typealias `[storageBehavior].Value` = Int
@implements(storageBehavior.storage)
private var `[storageBehavior].storage`: Something<Int> = initStorage()
var foo: Int {
get { return value }
set { value = newValue }
}
}
```
In either case, the `value` and `storage` properties should support any combination
of get-only/settable and mutating/nonmutating modifiers. The instantiated property
follows the settability and mutating-ness of the `value` implementation. The
protocol can also impose requirements on the `Self` and `Value` types.
Bells and whistles such as initializer expressions, accessors,
out-of-line initialization, etc. are not implemented. Additionally, behaviors
that instantiate storage are currently only supported on instance properties.
This also hasn't been tested past sema yet; SIL and IRGen will likely expose
additional issues.
These APIs are from the Swift 1.2 => Swift 2.0 transition, and are not
relevant anymore.
Removing them reduces the surface area of the library that needs to be
reviewed.
The code path for handling foreign error conventions of methods in
classes is sufficiently complicated that it needed its own logic, and
@objc protocol methods weren't handled at all. Fix that in the obvious
way, addressing rdar://problem/22262699.
Swift SVN r32234
for: func blah(x: @convention(c) Int throws -> Int) { }
we'd previously complain:
error: @convention(c) type is not representable in Objective-C
now we produce:
error: 'Int throws -> Int' is not representable in Objective-C, so it cannot be used with '@convention(c)'
Swift SVN r32007
- Disallow @objc on members of non-@objc protocols (the
real reason for this patch)
- Add a separate diagnostic for @objc appearing on members
in non-class, non-protocol types.
- Clean up the code that enforces that @objc can only be
applied to @objc-rooted classes. The diagnostic would
be incorrectly emitted for @objc subclasses of generic
classes.
Fixes <rdar://problem/17273524>.
Swift SVN r31303
It ~ought~ not to be bridged either, but that was the best solution to
rdar://problem/16899681 because it's not being special-cased.
rdar://problem/22042454
Swift SVN r30747
As Slava pointed out, we haven't implemented these cases either, for the
same reason. The issues in this area are tracked by rdar://problem/21216149.
Swift SVN r30725
We allow any array of bridgeable types to be converted to NSArray (and
similar for Dictionary and Set), but to be part of an API is a little
stricter. Previously, '[MySwiftObject]' as a parameter would get exposed
to Objective-C as 'NSArray *', but that's not type-safe at all---and in
corner cases, crashd in the ObjC printer. Now we just don't allow that.
On the plus side, '[Int]' is now exposed as 'NSArray<NSNumber *> *',
which is a fair amount better than just 'NSArray *'.
rdar://problem/19787270
Swift SVN r30719
Generic subclasses of @objc classes are thus no longer @objc, but still
have implicitly @objc members.
Explicit @objc on generic classes or classes that inherit from @objc
classes is now forbidden with a diagnostic. Users need to know that
while they can override Objective-C methods and properties in such
a class, they cannot refer to the class by name from Objective-C code,
since it will not appear in the bridging header.
Fixes <rdar://problem/21342574>.
Swift SVN r30494
For properties, "must be accessed with ObjC dispatch" is different from
"needs objc metadata". When we mean the latter, just call isObjC() on
the AbstractStorageDecl instead of using hasObjCMethodDispatch().
The latter returns false if any overridden declaration is not @objc, in
which case at runtime we don't need to dispatch.
Fixes <rdar://problem/21544588>.
Swift SVN r30382
These classes don't show up well in generated headers (rdar://problem/20855568),
can't actually be allocated from Objective-C (rdar://problem/17184317), and
make the story of "what is exposed to Objective-C" more complicated. Better
to just disallow them.
All classes are still "id-compatible" in that they can be converted to
AnyObject and passed to Objective-C, they secretly implement NSObjectProtocol
(via our SwiftObject root class), and their members can still be individually
exposed to Objective-C.
The frontend flag -disable-objc-attr-requires-foundation-module will disable
this requirement as well, which is still necessary for both the standard
library and a variety of tests I didn't feel like transforming.
Swift SVN r29760
Enhance fixItRemove() to be a bit more careful about what whitespace it leaves around: if the thing it is removing has leading and trailing whitespace already, this nukes an extra space to avoid leaving double spaces or incorrectly indented results.
This includes an extra fix for looking off the start of a buffer, which extractText doesn't and can't handle.
This fixes <rdar://problem/21045509> Fixit deletes 'let' from non-binding 'if case let' statements, but leaves an extra space
Swift SVN r29449
if the thing it is removing has leading and trailing whitespace already, this nukes
an extra space to avoid leaving double spaces or incorrectly indented results. This
fixes <rdar://problem/21045509> Fixit deletes 'let' from non-binding 'if case let' statements, but leaves an extra space
Swift SVN r29419
Now that generic subclasses of @objc classes are supported, dust off
Doug Gregor's fix for <rdar://problem/20385288>. It is now an error
to override an @objc declaration with something that cannot be
represented as @objc.
For example, the override of foo() here will not compile unless
it is explicitly marked @nonobjc:
func foo(i: Int) {}
...
override func foo(i: Int?) {}
Note that I updated IRGen to delete some logic for figuring out when
to emit @objc metadata. We can now rely on Sema to correctly set
isObjC(), instead of checking overrides ourselves. This was wrong
anyway, now that we can have @nonobjc overrides of @objc methods,
and vice versa.
Swift SVN r29263