Files
swift-mirror/test/Sema/immutability.swift
Dmitri Hrybenko 6a15456cec Eliminate uses of println() where it is irrelevant
Swift SVN r28172
2015-05-05 18:21:39 +00:00

436 lines
12 KiB
Swift

// RUN: %target-parse-verify-swift
func markUsed<T>(t: T) {}
let bad_property_1: Int { // expected-error {{'let' declarations cannot be computed properties}}
get {
return 42
}
}
let bad_property_2: Int = 0 {
get { // expected-error {{use of unresolved identifier 'get'}}
return 42
}
}
let no_initializer : Int
func foreach_variable() {
for i in 0..<42 {
i = 11 // expected-error {{cannot assign to 'let' value 'i'}}
}
}
func takeClosure(fn : (Int)->Int) {}
func passClosure() {
takeClosure { a in
a = 42 // expected-error {{cannot assign to 'let' value 'a'}}
return a
}
takeClosure {
$0 = 42 // expected-error{{cannot assign to 'let' value '$0'}}
42
}
takeClosure { (a : Int) -> Int in
a = 42 // expected-error{{cannot assign to 'let' value 'a'}}
return 42
}
}
class FooClass {
class let type_let = 5 // expected-error {{class stored properties not yet supported in classes}}
init() {
self = FooClass() // expected-error {{cannot assign to 'self' in a method}}
}
func bar() {
self = FooClass() // expected-error {{cannot assign to 'self' in a method}}
}
mutating init(a : Bool) {} // expected-error {{'mutating' may only be used on 'func' declarations}}
mutating // expected-error {{'mutating' isn't valid on methods in classes or class-bound protocols}}
func baz() {}
var x : Int {
get {
return 32
}
set(value) {
value = 42 // expected-error {{cannot assign to 'let' value 'value'}}
}
}
subscript(i : Int) -> Int {
get {
i = 42 // expected-error {{cannot assign to 'let' value 'i'}}
return 1
}
}
}
func let_decls() {
// <rdar://problem/16927246> provide a fixit to change "let" to "var" if needing to mutate a variable
let a = 42 // expected-note {{change 'let' to 'var' to make it mutable}}
a = 17 // expected-error {{cannot assign}}
let (b,c) = (4, "hello")
markUsed(b); markUsed(c)
b = 17 // expected-error {{cannot assign}}
let d = (4, "hello")
markUsed(d.0); markUsed(d.1)
d.0 = 17 // expected-error {{cannot assign}}
let e = 42 // expected-note {{change 'let' to 'var' to make it mutable}}
++e // expected-error {{cannot pass 'let' value 'e' to mutating unary operator '++'}}
// <rdar://problem/16306600> QoI: passing a 'let' value as an inout results in an unfriendly diagnostic
let f = 96 // expected-note {{change 'let' to 'var' to make it mutable}}
var v = 1
swap(&f, &v) // expected-error {{cannot pass 'let' value 'f' as inout argument}}
// <rdar://problem/19711233> QoI: poor diagnostic for operator-assignment involving immutable operand
let g = 14 // expected-note {{change 'let' to 'var' to make it mutable}}
g /= 2 // expected-error {{cannot pass 'let' value 'g' to mutating binary operator '/='}}
}
struct SomeStruct {
var iv = 32
static let type_let = 5
mutating static func f() { // expected-error {{static functions may not be declared mutating}}
}
mutating func g() {
iv = 42
}
mutating func g2() {
iv = 42
}
func h() {
iv = 12 // expected-error {{cannot assign}}
}
var p: Int {
// Getters default to non-mutating.
get {
iv = 37 // expected-error {{cannot assign to 'iv' in 'self'}}
return 42
}
// Setters default to mutating.
set {
iv = newValue
}
}
// Defaults can be changed.
var q : Int {
mutating
get {
iv = 37
return 42
}
nonmutating
set {
iv = newValue // expected-error {{cannot assign to 'iv' in 'self'}}
}
}
var r : Int {
get {
iv = 37 // expected-error {{cannot assign to 'iv' in 'self'}}
return 42
}
mutating // Redundant but OK.
set {
iv = newValue
}
}
}
markUsed(SomeStruct.type_let) // ok
SomeStruct.type_let = 17 // expected-error {{cannot assign to the result of this expression}}
struct TestMutableStruct {
mutating
func f() {}
func g() {}
var mutating_property : Int {
mutating
get {}
set {}
}
var nonmutating_property : Int {
get {}
nonmutating
set {}
}
// This property has a mutating getter and !mutating setter.
var weird_property : Int {
mutating get {}
nonmutating set {}
}
@mutating func mutating_attr() {} // expected-error {{'mutating' is a declaration modifier, not an attribute}}
@nonmutating func nonmutating_attr() {} // expected-error {{'nonmutating' is a declaration modifier, not an attribute}}
}
func test_mutability() {
// Non-mutable method on rvalue is ok.
TestMutableStruct().g()
// Non-mutable method on let is ok.
let x = TestMutableStruct()
x.g()
// Mutable methods on let and rvalue are not ok.
x.f() // expected-error {{immutable value of type 'TestMutableStruct' only has mutating members named 'f'}}
TestMutableStruct().f() // expected-error {{immutable value of type 'TestMutableStruct' only has mutating members named 'f'}}
}
func test_arguments(a : Int, var b : Int, let c : Int) {
a = 1 // expected-error {{cannot assign to 'let' value 'a'}}
b = 2 // ok.
c = 3 // expected-error {{cannot assign to 'let' value 'c'}}
}
protocol ClassBoundProtocolMutating : class {
mutating // expected-error {{'mutating' isn't valid on methods in classes or class-bound protocols}}
func f()
}
protocol MutatingTestProto {
mutating
func mutatingfunc()
func nonmutatingfunc() // expected-note {{protocol requires}}
}
class TestClass : MutatingTestProto {
func mutatingfunc() {} // Ok, doesn't need to be mutating.
func nonmutatingfunc() {}
}
struct TestStruct1 : MutatingTestProto {
func mutatingfunc() {} // Ok, doesn't need to be mutating.
func nonmutatingfunc() {}
}
struct TestStruct2 : MutatingTestProto {
mutating
func mutatingfunc() {} // Ok, can be mutating.
func nonmutatingfunc() {}
}
struct TestStruct3 : MutatingTestProto { // expected-error {{type 'TestStruct3' does not conform to protocol 'MutatingTestProto'}}
func mutatingfunc() {}
// This is not ok, "nonmutatingfunc" doesn't allow mutating functions.
mutating
func nonmutatingfunc() {} // expected-note {{candidate is marked 'mutating' but protocol does not allow it}}
}
// <rdar://problem/16722603> invalid conformance of mutating setter
protocol NonMutatingSubscriptable {
subscript(i: Int) -> Int {get nonmutating set} // expected-note {{protocol requires subscript with type '(Int) -> Int'}}
}
struct MutatingSubscriptor : NonMutatingSubscriptable { // expected-error {{type 'MutatingSubscriptor' does not conform to protocol 'NonMutatingSubscriptable'}}
subscript(i: Int) -> Int {
get { return 42 }
mutating set {} // expected-note {{candidate is marked 'mutating' but protocol does not allow it}}
}
}
protocol NonMutatingGet {
var a: Int { get } // expected-note {{protocol requires property 'a' with type 'Int'}}
}
struct MutatingGet : NonMutatingGet { // expected-error {{type 'MutatingGet' does not conform to protocol 'NonMutatingGet'}}
var a: Int { mutating get { return 0 } } // expected-note {{candidate is marked 'mutating' but protocol does not allow it}}
}
func test_properties() {
let rvalue = TestMutableStruct()
markUsed(rvalue.nonmutating_property) // ok
markUsed(rvalue.mutating_property) // expected-error {{immutable value of type 'TestMutableStruct' only has mutating members named 'mutating_property'}}
markUsed(rvalue.weird_property) // expected-error {{immutable value of type 'TestMutableStruct' only has mutating members named 'weird_property'}}
rvalue.nonmutating_property = 1 // ok
rvalue.mutating_property = 1 // expected-error {{immutable value of type 'TestMutableStruct' only has mutating members named 'mutating_property'}}
rvalue.weird_property = 1 // expected-error {{mmutable value of type 'TestMutableStruct' only has mutating members named 'weird_property'}}
var lvalue = TestMutableStruct()
markUsed(lvalue.mutating_property) // ok
markUsed(lvalue.nonmutating_property) // ok
markUsed(lvalue.weird_property) // ok
lvalue.mutating_property = 1 // ok
lvalue.nonmutating_property = 1 // ok
lvalue.weird_property = 1 // ok
}
struct DuplicateMutating {
mutating mutating func f() {} // expected-error {{duplicate modifier}} expected-note {{modifier already specified here}}
}
protocol SubscriptNoGetter {
subscript (i: Int) -> Int { get }
}
func testSubscriptNoGetter(let iis: SubscriptNoGetter) {
var i: Int = iis[17]
}
func testSelectorStyleArguments1(var x: Int, var bar y: Int) {
++x; ++y
}
func testSelectorStyleArguments2(let x: Int, let bar y: Int) {
++x // expected-error {{cannot pass 'let' value 'x' to mutating unary operator '++'}}
++y // expected-error {{cannot pass 'let' value 'y' to mutating unary operator '++'}}
}
func invalid_inout(inout var x : Int) { // expected-error {{parameter may not have multiple 'inout', 'var', or 'let' specifiers}}
}
func updateInt(inout x : Int) {}
// rdar://15785677 - allow 'let' declarations in structs/classes be initialized in init()
class LetClassMembers {
let a : Int
let b : Int
init(arg : Int) {
a = arg // ok, a is mutable in init()
updateInt(&a) // ok, a is mutable in init() and has been initialized
b = 17 // ok, b is mutable in init()
}
func f() {
a = 42 // expected-error {{cannot assign to 'a' in 'self'}}
b = 42 // expected-error {{cannot assign to 'b' in 'self'}}
updateInt(&a) // expected-error {{cannot pass immutable value of type 'Int' as inout argument}}
}
}
struct LetStructMembers {
let a : Int
let b : Int
init(arg : Int) {
a = arg // ok, a is mutable in init()
updateInt(&a) // ok, a is mutable in init() and has been initialized
b = 17 // ok, b is mutable in init()
}
func f() {
a = 42 // expected-error {{cannot assign to 'a' in 'self'}}
b = 42 // expected-error {{cannot assign to 'b' in 'self'}}
updateInt(&a) // expected-error {{cannot pass immutable value of type 'Int' as inout argument}}
}
}
func QoI() {
let x = 97 // expected-note {{change 'let' to 'var' to make it mutable}}
x = 17 // expected-error {{cannot assign to 'let' value 'x'}}
var get_only: Int {
get { return 7 }
}
get_only = 92 // expected-error {{cannot assign to a get-only property 'get_only'}}
}
// <rdar://problem/17051675> Structure initializers in an extension cannot assign to constant properties
struct rdar17051675_S {
let x : Int
init(newX: Int) {
x = 42
}
}
extension rdar17051675_S {
init(newY: Int) {
x = 42
}
}
struct rdar17051675_S2<T> {
let x : Int
init(newX: Int) {
x = 42
}
}
extension rdar17051675_S2 {
init(newY: Int) {
x = 42
}
}
// <rdar://problem/17400366> let properties should not be mutable in convenience initializers
class ClassWithConvenienceInit {
let x : Int
init(newX: Int) {
x = 42
}
convenience init(newY: Int) {
self.init(newX: 19)
x = 67 // expected-error {{cannot assign to 'x' in 'self'}}
}
}
struct StructWithDelegatingInit {
let x: Int
init(x: Int) { self.x = x }
init() { self.init(x: 0); self.x = 22 } // expected-error {{cannot assign to 'x' in 'self'}}
}
func test_recovery_missing_name_1(var: Int) {} // expected-error 2{{expected ',' separator}} expected-error 2{{expected parameter type following ':'}}
func test_recovery_missing_name_2(let: Int) {} // expected-error 2{{expected ',' separator}} expected-error 2{{expected parameter type following ':'}}
// <rdar://problem/16792027> compiler infinite loops on a really really mutating function
struct F {
mutating mutating mutating f() { // expected-error 2 {{duplicate modifier}} expected-note 2 {{modifier already specified here}} expected-error {{consecutive declarations on a line must be separated by ';'}} expected-error 2 {{expected declaration}}
}
mutating nonmutating func g() { // expected-error {{method may not be declared both mutating and nonmutating}}
}
}