mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
In Swift 4, properties declared with a sugared Optional type, like Int?, have a default value of nil. This can be observed in two ways: - Classes and structs get an implicit no-argument initializer - Designated initializers don't have to initialize this property Note that this did not apply in general to properties where the type was spelled explicitly as Optional<Int>, etc, mostly because of implementation restrictions -- when we check if a type has implicit initializers, we have not realized types for all stored property members yet, and doing so is not really possible without the iterative decl checker. However, in some cases, we *did* perform default initialization for Optional<Int>, because of some code duplication and divergent code paths. A recent refactoring cleaned up some of the mess in this area, but accidentally broke source compatibility with code that relied on the broken Optional<Int> case. Fix this by simulating the old behavior in -swift-version 4, and preserving the more correct behavior in -swift-version 5. Fixes <rdar://problem/35319847>.
54 lines
1.8 KiB
Swift
54 lines
1.8 KiB
Swift
// RUN: %target-swift-frontend -typecheck -parse-as-library %s -verify -swift-version 5
|
|
|
|
// Default initialization of variables.
|
|
|
|
class X { }
|
|
|
|
struct CanDefaultInit {
|
|
var opt1: Int?
|
|
var (opt2, (opt3, opt4)): (Int?, (Float?, Double?))
|
|
weak var opt5: X?
|
|
}
|
|
|
|
func testCanDefaultInit() {
|
|
_ = CanDefaultInit()
|
|
}
|
|
|
|
|
|
// Cases where we cannot perform default initialization.
|
|
class NotInitializable1 { // expected-error{{class 'NotInitializable1' has no initializers}}
|
|
var (opt1, int1) : (Int?, Int) // expected-note{{stored properties 'opt1' and 'int1' without initial values prevent synthesized initializers}} {{33-33= = (nil, 0)}}
|
|
let opt2: Int? // expected-note{{stored property 'opt2' without initial value prevents synthesized initializers}}
|
|
var opt3: Int?
|
|
}
|
|
|
|
func localDefaultInit() -> Int? {
|
|
let i: Int?
|
|
return i
|
|
}
|
|
|
|
|
|
// <rdar://problem/16906000> Implicitly unwrapped optional let is not considered initialized, but var is
|
|
class DefaultInitOfLetProperty {
|
|
let property: DefaultInitOfLetProperty!
|
|
init(x: DefaultInitOfLetProperty) {
|
|
self.property = DefaultInitOfLetProperty(x: self)
|
|
}
|
|
}
|
|
|
|
var global: Int?
|
|
|
|
class NotInitializableOptionalClass { // expected-error{{class 'NotInitializableOptionalClass' has no initializers}}
|
|
// Do not perform default initialization for properties with explicitly-spelled 'Optional'.
|
|
var opt: Optional<Int> // expected-note{{stored property 'opt' without initial value prevents synthesized initializers}}
|
|
}
|
|
|
|
struct NotInitializableOptionalStruct { // expected-note {{'init(opt:)' declared here}}
|
|
var opt: Optional<Int>
|
|
}
|
|
|
|
func testBadDefaultInit() {
|
|
_ = NotInitializableOptionalStruct() // expected-error {{missing argument for parameter 'opt' in call}}
|
|
_ = NotInitializableOptionalClass() // expected-error {{'NotInitializableOptionalClass' cannot be constructed because it has no accessible initializers}}
|
|
}
|