You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Sema: Fix diagnoseSelfAssignment() with computed properties
This check did not handle MemberRefExprs with an InOutExpr base,
giving it inconsistent behavior:
- With a class, we would diagnose self-assignment of computed
properties
- With a struct, accesses to computed properties would build a
MemberRefExpr with an InOutExpr base, so self-assignments
were *not* diagnosed.
Let's tweak the check to consistently diagnose self-assignments
to stored properties only, instead of the emergent behavior
as described above.
Copy file name to clipboardExpand all lines: test/Sema/diag_self_assign.swift
+81-7Lines changed: 81 additions & 7 deletions
Original file line number
Diff line number
Diff line change
@@ -21,6 +21,24 @@ class SA1 {
21
21
}
22
22
}
23
23
24
+
structSA1a{
25
+
varfoo:Int=0
26
+
init(fooi:Int){
27
+
varfoo= fooi
28
+
foo = foo // expected-error {{assigning a variable to itself}}
29
+
self.foo =self.foo // expected-error {{assigning a property to itself}}
30
+
foo =self.foo // no-error
31
+
self.foo = foo // no-error
32
+
}
33
+
mutatingfunc f(fooi:Int){
34
+
varfoo= fooi
35
+
foo = foo // expected-error {{assigning a variable to itself}}
36
+
self.foo =self.foo // expected-error {{assigning a property to itself}}
37
+
foo =self.foo // no-error
38
+
self.foo = foo // no-error
39
+
}
40
+
}
41
+
24
42
classSA2{
25
43
varfoo:Int{
26
44
get{
@@ -31,14 +49,37 @@ class SA2 {
31
49
init(fooi:Int){
32
50
varfoo= fooi
33
51
foo = foo // expected-error {{assigning a variable to itself}}
34
-
self.foo =self.foo // expected-error {{assigning a property to itself}}
52
+
self.foo =self.foo // no-error
35
53
foo =self.foo // no-error
36
54
self.foo = foo // no-error
37
55
}
38
56
func f(fooi:Int){
39
57
varfoo= fooi
40
58
foo = foo // expected-error {{assigning a variable to itself}}
41
-
self.foo =self.foo // expected-error {{assigning a property to itself}}
59
+
self.foo =self.foo // no-error
60
+
foo =self.foo // no-error
61
+
self.foo = foo // no-error
62
+
}
63
+
}
64
+
65
+
structSA2a{
66
+
varfoo:Int{
67
+
get{
68
+
return0
69
+
}
70
+
set{}
71
+
}
72
+
init(fooi:Int){
73
+
varfoo= fooi
74
+
foo = foo // expected-error {{assigning a variable to itself}}
75
+
self.foo =self.foo // no-error
76
+
foo =self.foo // no-error
77
+
self.foo = foo // no-error
78
+
}
79
+
mutatingfunc f(fooi:Int){
80
+
varfoo= fooi
81
+
foo = foo // expected-error {{assigning a variable to itself}}
82
+
self.foo =self.foo // no-error
42
83
foo =self.foo // no-error
43
84
self.foo = foo // no-error
44
85
}
@@ -50,10 +91,24 @@ class SA3 {
50
91
return foo // expected-warning {{attempting to access 'foo' within its own getter}} expected-note{{access 'self' explicitly to silence this warning}} {{14-14=self.}}
51
92
}
52
93
set{
53
-
foo = foo // expected-error {{assigning a property to itself}} expected-warning {{attempting to modify 'foo' within its own setter}} expected-note{{access 'self' explicitly to silence this warning}} {{7-7=self.}} expected-warning{{setter argument 'newValue' was never used, but the property was accessed}} expected-note{{did you mean to use 'newValue' instead of accessing the property's current value?}}
54
-
self.foo =self.foo // expected-error {{assigning a property to itself}}
55
-
foo =self.foo // expected-error {{assigning a property to itself}} expected-warning {{attempting to modify 'foo' within its own setter}} expected-note{{access 'self' explicitly to silence this warning}} {{7-7=self.}}
56
-
self.foo = foo // expected-error {{assigning a property to itself}}
94
+
foo = foo // expected-warning {{attempting to modify 'foo' within its own setter}} expected-note{{access 'self' explicitly to silence this warning}} {{7-7=self.}} expected-warning{{setter argument 'newValue' was never used, but the property was accessed}} expected-note{{did you mean to use 'newValue' instead of accessing the property's current value?}}
95
+
self.foo =self.foo // no-error
96
+
foo =self.foo // expected-warning {{attempting to modify 'foo' within its own setter}} expected-note{{access 'self' explicitly to silence this warning}} {{7-7=self.}}
97
+
self.foo = foo
98
+
}
99
+
}
100
+
}
101
+
102
+
structSA3a{
103
+
varfoo:Int{
104
+
get{
105
+
return foo // expected-warning {{attempting to access 'foo' within its own getter}} expected-note{{access 'self' explicitly to silence this warning}} {{14-14=self.}}
106
+
}
107
+
set{
108
+
foo = foo // expected-warning {{attempting to modify 'foo' within its own setter}} expected-note{{access 'self' explicitly to silence this warning}} {{7-7=self.}} expected-warning{{setter argument 'newValue' was never used, but the property was accessed}} expected-note{{did you mean to use 'newValue' instead of accessing the property's current value?}}
109
+
self.foo =self.foo // no-error
110
+
foo =self.foo // expected-warning {{attempting to modify 'foo' within its own setter}} expected-note{{access 'self' explicitly to silence this warning}} {{7-7=self.}}
111
+
self.foo = foo
57
112
}
58
113
}
59
114
}
@@ -69,10 +124,29 @@ class SA4 {
69
124
}
70
125
}
71
126
127
+
structSA4a{
128
+
varfoo:Int{
129
+
get{
130
+
return foo // expected-warning {{attempting to access 'foo' within its own getter}} expected-note{{access 'self' explicitly to silence this warning}} {{14-14=self.}}
131
+
}
132
+
set(value){
133
+
value = value // expected-error {{cannot assign to value: 'value' is a 'let' constant}}
134
+
}
135
+
}
136
+
}
137
+
72
138
classSA5{
73
139
varfoo:Int=0
74
140
}
75
-
func SA5_test(a:SA4, b:SA4){
141
+
func SA5_test(a:SA5, b:SA5){
142
+
a.foo = a.foo // expected-error {{assigning a property to itself}}
143
+
a.foo = b.foo
144
+
}
145
+
146
+
structSA5a{
147
+
varfoo:Int=0
148
+
}
149
+
func SA5a_test(a:inoutSA5, b:inoutSA5){
76
150
a.foo = a.foo // expected-error {{assigning a property to itself}}
0 commit comments