Skip to content

Commit 7725818

Browse files
committed
Revert "Merge pull request #27057 from theblixguy/unrevert/SR-11298"
This reverts commit c99facb, reversing changes made to 9a24013. rdar://problem/56165420
1 parent d930599 commit 7725818

File tree

8 files changed

+25
-92
lines changed

8 files changed

+25
-92
lines changed

CHANGELOG.md

Lines changed: 1 addition & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -58,63 +58,6 @@ Swift 5.2
5858
(foo as Magic)(5)
5959
```
6060

61-
* [SR-11298][]:
62-
63-
A class-constrained protocol extension, where the extended protocol does
64-
not impose a class constraint, will now infer the constraint implicitly.
65-
66-
```swift
67-
protocol Foo {}
68-
class Bar: Foo {
69-
var someProperty: Int = 0
70-
}
71-
72-
// Even though 'Foo' does not impose a class constraint, it is automatically
73-
// inferred due to the Self: Bar constraint.
74-
extension Foo where Self: Bar {
75-
var anotherProperty: Int {
76-
get { return someProperty }
77-
// As a result, the setter is now implicitly nonmutating, just like it would
78-
// be if 'Foo' had a class constraint.
79-
set { someProperty = newValue }
80-
}
81-
}
82-
```
83-
84-
As a result, this could lead to code that currently compiles today to throw an error.
85-
86-
```swift
87-
protocol Foo {
88-
var someProperty: Int { get set }
89-
}
90-
91-
class Bar: Foo {
92-
var someProperty = 0
93-
}
94-
95-
extension Foo where Self: Bar {
96-
var anotherProperty1: Int {
97-
get { return someProperty }
98-
// This will now error, because the protocol requirement
99-
// is implicitly mutating and the setter is implicitly
100-
// nonmutating.
101-
set { someProperty = newValue } // Error
102-
}
103-
}
104-
```
105-
106-
**Workaround**: Define a new mutable variable inside the setter that has a reference to `self`:
107-
108-
```swift
109-
var anotherProperty1: Int {
110-
get { return someProperty }
111-
set {
112-
var mutableSelf = self
113-
mutableSelf.someProperty = newValue // Okay
114-
}
115-
}
116-
```
117-
11861
* [SE-0253][]:
11962

12063
Values of types that declare `func callAsFunction` methods can be called
@@ -140,7 +83,7 @@ Swift 5.2
14083

14184
* [SR-4206][]:
14285

143-
A method override is no longer allowed to have a generic signature with
86+
A method override is no longer allowed to have a generic signature with
14487
requirements not imposed by the base method. For example:
14588

14689
```
@@ -7856,5 +7799,4 @@ Swift 1.0
78567799
[SR-8974]: <https://bugs.swift.org/browse/SR-8974>
78577800
[SR-9043]: <https://bugs.swift.org/browse/SR-9043>
78587801
[SR-9827]: <https://bugs.swift.org/browse/SR-9827>
7859-
[SR-11298]: <https://bugs.swift.org/browse/SR-11298>
78607802
[SR-11429]: <https://bugs.swift.org/browse/SR-11429>

include/swift/AST/DeclContext.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,10 +261,7 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
261261

262262
/// Returns the kind of context this is.
263263
DeclContextKind getContextKind() const;
264-
265-
/// Returns whether this context has value semantics.
266-
bool hasValueSemantics() const;
267-
264+
268265
/// Determines whether this context is itself a local scope in a
269266
/// code block. A context that appears in such a scope, like a
270267
/// local type declaration, does not itself become a local context.

lib/AST/Decl.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5672,18 +5672,12 @@ void VarDecl::emitLetToVarNoteIfSimple(DeclContext *UseDC) const {
56725672
if (FD && !FD->isMutating() && !FD->isImplicit() && FD->isInstanceMember()&&
56735673
!FD->getDeclContext()->getDeclaredInterfaceType()
56745674
->hasReferenceSemantics()) {
5675-
// Do not suggest the fix-it in implicit getters
5675+
// Do not suggest the fix it in implicit getters
56765676
if (auto AD = dyn_cast<AccessorDecl>(FD)) {
56775677
if (AD->isGetter() && !AD->getAccessorKeywordLoc().isValid())
56785678
return;
5679-
5680-
auto accessorDC = AD->getDeclContext();
5681-
// Do not suggest the fix-it if `Self` is a class type.
5682-
if (accessorDC->isTypeContext() && !accessorDC->hasValueSemantics()) {
5683-
return;
5684-
}
56855679
}
5686-
5680+
56875681
auto &d = getASTContext().Diags;
56885682
d.diagnose(FD->getFuncLoc(), diag::change_to_mutating,
56895683
isa<AccessorDecl>(FD))

lib/AST/DeclContext.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,14 +1035,6 @@ DeclContextKind DeclContext::getContextKind() const {
10351035
llvm_unreachable("Unhandled DeclContext ASTHierarchy");
10361036
}
10371037

1038-
bool DeclContext::hasValueSemantics() const {
1039-
if (auto contextTy = getSelfTypeInContext()) {
1040-
return !contextTy->hasReferenceSemantics();
1041-
}
1042-
1043-
return false;
1044-
}
1045-
10461038
SourceLoc swift::extractNearestSourceLoc(const DeclContext *dc) {
10471039
switch (dc->getContextKind()) {
10481040
case DeclContextKind::AbstractFunctionDecl:

lib/Sema/TypeCheckDecl.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,10 +2090,17 @@ OperatorPrecedenceGroupRequest::evaluate(Evaluator &evaluator,
20902090
return group;
20912091
}
20922092

2093+
bool swift::doesContextHaveValueSemantics(DeclContext *dc) {
2094+
if (Type contextTy = dc->getDeclaredInterfaceType())
2095+
return !contextTy->hasReferenceSemantics();
2096+
return false;
2097+
}
2098+
20932099
llvm::Expected<SelfAccessKind>
20942100
SelfAccessKindRequest::evaluate(Evaluator &evaluator, FuncDecl *FD) const {
20952101
if (FD->getAttrs().getAttribute<MutatingAttr>(true)) {
2096-
if (!FD->isInstanceMember() || !FD->getDeclContext()->hasValueSemantics()) {
2102+
if (!FD->isInstanceMember() ||
2103+
!doesContextHaveValueSemantics(FD->getDeclContext())) {
20972104
return SelfAccessKind::NonMutating;
20982105
}
20992106
return SelfAccessKind::Mutating;
@@ -2115,7 +2122,8 @@ SelfAccessKindRequest::evaluate(Evaluator &evaluator, FuncDecl *FD) const {
21152122
case AccessorKind::MutableAddress:
21162123
case AccessorKind::Set:
21172124
case AccessorKind::Modify:
2118-
if (AD->isInstanceMember() && AD->getDeclContext()->hasValueSemantics())
2125+
if (AD->isInstanceMember() &&
2126+
doesContextHaveValueSemantics(AD->getDeclContext()))
21192127
return SelfAccessKind::Mutating;
21202128
break;
21212129

lib/Sema/TypeCheckDecl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ class DeclContext;
2525
class ValueDecl;
2626
class Pattern;
2727

28+
bool doesContextHaveValueSemantics(DeclContext *dc);
29+
2830
/// Walks up the override chain for \p CD until it finds an initializer that is
2931
/// required and non-implicit. If no such initializer exists, returns the
3032
/// declaration where \c required was introduced (i.e. closest to the root

lib/Sema/TypeCheckStorage.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,8 @@ void swift::validatePatternBindingEntries(TypeChecker &tc,
269269
llvm::Expected<bool>
270270
IsGetterMutatingRequest::evaluate(Evaluator &evaluator,
271271
AbstractStorageDecl *storage) const {
272-
auto storageDC = storage->getDeclContext();
273-
bool result = (!storage->isStatic() && storageDC->isTypeContext() &&
274-
storageDC->hasValueSemantics());
272+
bool result = (!storage->isStatic() &&
273+
doesContextHaveValueSemantics(storage->getDeclContext()));
275274

276275
// 'lazy' overrides the normal accessor-based rules and heavily
277276
// restricts what accessors can be used. The getter is considered
@@ -299,7 +298,7 @@ IsGetterMutatingRequest::evaluate(Evaluator &evaluator,
299298

300299
// Protocol requirements are always written as '{ get }' or '{ get set }';
301300
// the @_borrowed attribute determines if getReadImpl() becomes Get or Read.
302-
if (isa<ProtocolDecl>(storageDC))
301+
if (isa<ProtocolDecl>(storage->getDeclContext()))
303302
return checkMutability(AccessorKind::Get);
304303

305304
switch (storage->getReadImpl()) {
@@ -325,9 +324,8 @@ IsSetterMutatingRequest::evaluate(Evaluator &evaluator,
325324
AbstractStorageDecl *storage) const {
326325
// By default, the setter is mutating if we have an instance member of a
327326
// value type, but this can be overridden below.
328-
auto storageDC = storage->getDeclContext();
329-
bool result = (!storage->isStatic() && storageDC->isTypeContext() &&
330-
storageDC->hasValueSemantics());
327+
bool result = (!storage->isStatic() &&
328+
doesContextHaveValueSemantics(storage->getDeclContext()));
331329

332330
// If we have an attached property wrapper, the setter is mutating
333331
// or not based on the composition of the wrappers.

test/decl/ext/extensions.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ struct WrapperContext {
126126
}
127127

128128
// Class-constrained extension where protocol does not impose class requirement
129-
// SR-11298
129+
130130
protocol DoesNotImposeClassReq_1 {}
131131

132132
class JustAClass: DoesNotImposeClassReq_1 {
@@ -140,8 +140,8 @@ extension DoesNotImposeClassReq_1 where Self: JustAClass {
140140
}
141141
}
142142

143-
let instanceOfJustAClass = JustAClass()
144-
instanceOfJustAClass.wrappingProperty = "" // Okay
143+
let instanceOfJustAClass = JustAClass() // expected-note {{change 'let' to 'var' to make it mutable}}
144+
instanceOfJustAClass.wrappingProperty = "" // expected-error {{cannot assign to property: 'instanceOfJustAClass' is a 'let' constant}}
145145

146146
protocol DoesNotImposeClassReq_2 {
147147
var property: String { get set }
@@ -150,7 +150,7 @@ protocol DoesNotImposeClassReq_2 {
150150
extension DoesNotImposeClassReq_2 where Self : AnyObject {
151151
var wrappingProperty: String {
152152
get { property }
153-
set { property = newValue } // expected-error {{cannot assign to property: 'self' is immutable}}
153+
set { property = newValue } // Okay
154154
}
155155
}
156156

0 commit comments

Comments
 (0)