missing piece now is Sema support for detecting invalid exits
out of defer bodies. That said, SILGen will also detect it,
and produce an error if sema misses something, e.g.:
t.swift:11:23: error: defer statement is not allowed to be exited
while false { defer { break } }
^
t.swift:12:9: error: defer statement is not allowed to be exited
defer { return }
^
we should still diagnose these in Sema for better QoI of course.
This wraps up: <rdar://problem/17302850> Add a defer keyword to swift
Swift SVN r27760
On that testcase, we now generate:
t.swift:8:22: error: integer literal '123456' overflows when stored into 'UInt8'
case tooFarByFar = 123456
^
t.swift:7:8: error: integer literal '256' overflows when stored into 'UInt8'
case twoHundredFiftySix
^
instead of spitting out some warnings with no source loc (which Xcode eats).
This patch:
- Propagates source locations for literals when synthesizing code in various places,
so we get the right diagnostic at the right spot.
- Improves the constant folding SIL Pass to print the value overflowing, which is
necessary for cases with an implicit value (like 256 above), and is general goodness
for the QoI of the diagnostic anyway.
Swift SVN r27756
This falls out of the rework I did of 'self' in initializers. We now correctly
dealloc_ref the allocated object on the failure path of a convenience init.
Swift SVN r27752
...and similar for NSDictionary and NSSet.
For APIs that don't have a reason to distinguish "empty" and "absent" cases,
we encourage standardizing on "empty" and marking the result as non-optional
(or in Objective-C, __nonnull). However, there are system APIs whose
implementations currently do return nil rather than an empty collection
instance. In these cases, we recommend /changing/ the API to return the
appropriate "empty" value instead.
However, this can cause problems for backwards-deployment: while the API is
truly non-optional on system vN, a program may encounter a nil return value
if run on system vN-1. Objective-C can generally deal with this (especially
if the only thing you do is ask for the count or try to iterate over the
collection) but Swift can't. Therefore, we've decided to "play nice" and
accept nil return values for the collection types (NSArray, NSDictionary,
and NSSet) and implicitly treat them as "empty" values if they are the
result of an imported function or method.
Note that the current implementation has a hole regarding subscript getters,
since we still make an AST-level thunk for these in the Clang importer.
We can probably get rid of those these days, but I didn't want to touch
them at this point. It seems unlikely that there will be a subscript that
(a) is for a collection type, and (b) mistakenly returned nil in the past
rather than an empty collection.
There's another hole where an ObjC client calls one of these mistakenly-nil-
returning methods and then immediately hands the result off by calling a
Swift method. However, we have to draw the line somewhere.
(We're actually going to do this for strings as well; coming soon.)
rdar://problem/19734621
Swift SVN r26479
This patch also introduces some SILGen infrastructure for
dividing the function into "ordinary" and "postmatter"
sections, with error-handling-like stuff going into the
final section. Currently, this is largely undermined by
SILBuilder, but I'm going to fix that in a follow-up.
Swift SVN r26422
in a failable initializer. Previously, it would always just say "properties of a class
instance must be initialized before returning nil".
Now, in designated inits, it adds to that message with notes for each member that is not
initialized but must be. It also adds a note saying that super.init() must be called if
that is the problem.
In convenience inits, it says:
"failable convenience initializer must delegate to self.init() before returning nil"
For example, in:
class B : A {
var x : Int
override init?() { return nil }
We now produce:
t.swift:13:15: error: all stored properties of a class instance must be initialized before returning nil from an initializer
t.swift:11:7: note: 'self.x' not initialized
t.swift:13:15: note: super.init must be called before returning nil
I don't see any radars about this, but someone was confused on the dev forums:
https://devforums.apple.com/message/1113604#1113604
Swift SVN r26166
... now that we have an exquisitely shaved yak.
This provides a simple and uniform model for "let" constants: they are always either
immediately initialized in their declaration, or they are initialized dynamically
exactly once before any use.
This is a simple generalization of our current model for initializers, but enables
the use of let constants in more cases in local context, e.g. patterns like this:
let x : SomeThing
if condition {
x = foo()
} else {
x = bar()
}
use(x)
Previously this would have to be declared a "var" for no good reason: the value is
only ever initialized, never actually mutated.
The implementation of this is reasonably straight-forward now that the infrastructure
is in place: Sema treats 'let' constants as "settable" if they lack an initializer
(either in the declaration or in a non-PBD binding). This exposes them as an lvalue
at the AST level. SILGen then lowers these things to an alloc_stack, and DI enforces
the "initialization only" requirement that it already enforces for uninitialized 'let'
properties in structs/classes.
Swift SVN r23916
- We switch to a model where let properties may be "initialized", but never
reassigned. Specifically, immutable properties in structs/classes may have
an init value specified in their declaration (but can then never be reset
in any init implementation) or not (in which case they must be initialized
exactly once on all paths through every init. This makes a lot more sense
for immutability, defines several problems away, and provides a path to
supporting things like (rdar://16181314)
- We now *never* default initialize an immutable property. Formerly
we would default initialize optional let properties to nil, but this
isn't actually useful, and allows an error of omission with let
properties.
This resolves: <rdar://problem/19035287> let properties should only be initializable, not reassignable
and possibly other radars.
Swift SVN r23779
It returns the argument and specifies that the value is not negative.
It has only an effect if the argument is a load or call.
The effect of this builtin is that for the load/call argument a positive range metadata is created in llvm ir.
I also added a public function _assumeNonNegative(x: Int) -> Int in the stdlib.
To be on the save side, I prefixed it with an underscore. But maybe it makes sense to make it available for all users.
Swift SVN r23582
Dramatically improve DI diagnostics in initializers fixing rdar://18414728.
As one small example of the improvement, where an initializer like this:
class Foo {
var path:String? {
return "boo"
}
let aaaaa:String
init() {
if let p1 = path {
used to produce the error: "error: variable 'self.aaaaa' used before being initialized" on path,
we now produce:
x.swift:9:21: error: use of 'self' in property access 'path' before all stored properties are initialized
if let p1 = path {
^
x.swift:6:9: note: 'self.aaaaa' not initialized
let aaaaa:String
^
which is more useful.
Swift SVN r22238
As one small example of the improvement, where an initializer like this:
class Foo {
var path:String? {
return "boo"
}
let aaaaa:String
init() {
if let p1 = path {
used to produce the error: "error: variable 'self.aaaaa' used before being initialized" on path,
we now produce:
x.swift:9:21: error: use of 'self' in property access 'path' before all stored properties are initialized
if let p1 = path {
^
x.swift:6:9: note: 'self.aaaaa' not initialized
let aaaaa:String
^
which is more useful.
Swift SVN r22223
This raises an error for some cases we don't implement correctly yet, though not ones that require super.init or self.init delegation yet.
Swift SVN r21669
This isn't the theoretically purest way to do it--when we find ourselves reentering TypeLowering, instead of asserting, complain about the type being recursive. There's a nonzero chance this will complain about legitimate cases we just don't implement correctly, but it beats crashing. Recover by returning an address-only TypeLowering, which is sufficient to keep SILGen moving after the failure. <rdar://problem/16423940>
Swift SVN r20789
computed property" errors when SILGen could determine that there was
an inout writeback alias, and have the code instead perform CSE of the
writebacks directly.
This means that we produce more efficient code, that a lot of things
now "just work" the way users would expect, and that the still erroneous
cases now get diagnosed with the "inout arguments are not allowed to
alias each other" error, which people have a hope of understanding.
There is still more to do here in terms of detecting identical cases,
but that was true of the previous diagnostic as well.
Swift SVN r20658
t2.swift:4:11: error: inout arguments are not allowed to alias each other
swap(&x, &x)
^~
t2.swift:4:7: note: previous aliasing argument
swap(&x, &x)
^~
This can (and arguably should) also be handled with a later diagnostic pass, but
handling it in SILGen gives us full range emission capability.
Swift SVN r20469
introduced, as these are obvious miscompilations and clearly mystifying to our user base.
This is enough to emit diagnostics like this:
writeback_conflict_diagnostics.swift:58:70: error: inout writeback aliasing conflict detected on computed property 'c_local_struct_property'
swap(&c_local_struct_property.stored_int, &c_local_struct_property.stored_int)
~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
writeback_conflict_diagnostics.swift:58:33: note: concurrent writeback occurred here
swap(&c_local_struct_property.stored_int, &c_local_struct_property.stored_int)
~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
which isn't great, but is better than nothing (better wording is totally welcome!).
This doesn't handle subscripts (or many other kinds of logical lvalue) at all yet, so
it doesn't handle the swift WTF case, but this is progress towards that.
Swift SVN r20297
This has two changes:
- In the case when we have an invalid source loc, DI will default to emitting diagnostics
at the enclosing function's location. This makes it more robust in general against
implicitly synthesized code.
- For this diagnostic in particular, emit a tailored message, since super.init is a commonly
synthesized thing.
Swift SVN r20104
property in a base class before calling super.init. This is a nice improvement,
and also avoids regressing on QoI when a patch I'm working on finally lands.
Swift SVN r15379
Thanks to the way we've set up our diagnostics engine, there's not actually
a reason for /everything/ to get rebuilt when /one/ diagnostic changes.
I've split them up into five categories for now: Parse, Sema, SIL, IRGen,
and Frontend, plus a set of "Common" diagnostics that are used in multiple
areas of the compiler. We can massage this later.
No functionality change, but should speed up compile times!
Swift SVN r12438