Skip to content

Commit f7babf2

Browse files
committed
Merge remote-tracking branch 'origin/main' into rebranch
2 parents 5a46464 + 59b136c commit f7babf2

File tree

12 files changed

+263
-44
lines changed

12 files changed

+263
-44
lines changed

include/swift/AST/AvailabilityConstraint.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,12 @@ enum class AvailabilityConstraintFlag : uint8_t {
174174
/// Include constraints for all domains, regardless of whether they are active
175175
/// or relevant to type checking.
176176
IncludeAllDomains = 1 << 1,
177+
178+
/// By default, non-type declarations that are universally unavailable are
179+
/// always diagnosed, regardless of whether the context of the reference
180+
/// is also universally unavailable. If this flag is set, though, those
181+
/// references are allowed.
182+
AllowUniversallyUnavailableInCompatibleContexts = 1 << 2,
177183
};
178184
using AvailabilityConstraintFlags = OptionSet<AvailabilityConstraintFlag>;
179185

include/swift/AST/Types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,9 @@ class alignas(1 << TypeAlignInBits) TypeBase
12641264
/// representation, i.e. whether it is representable as a single,
12651265
/// possibly nil pointer that can be unknown-retained and
12661266
/// unknown-released.
1267+
/// This does not include C++ imported `SWIFT_SHARED_REFERENCE` classes.
1268+
/// They act as Swift classes but are not compatible with Swift's
1269+
/// retain/release runtime functions.
12671270
bool hasRetainablePointerRepresentation();
12681271

12691272
/// Given that this type is a reference type, which kind of reference

include/swift/SIL/SILType.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,9 @@ class SILType {
419419

420420
/// Returns true if the referenced type is guaranteed to have a
421421
/// single-retainable-pointer representation.
422+
/// This does not include C++ imported `SWIFT_SHARED_REFERENCE` classes.
423+
/// They act as Swift classes but are not compatible with Swift's
424+
/// retain/release runtime functions.
422425
bool hasRetainablePointerRepresentation() const {
423426
return getASTType()->hasRetainablePointerRepresentation();
424427
}

lib/AST/AvailabilityConstraint.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,16 @@ DeclAvailabilityConstraints::getPrimaryConstraint() const {
118118
}
119119

120120
static bool canIgnoreConstraintInUnavailableContexts(
121-
const Decl *decl, const AvailabilityConstraint &constraint) {
121+
const Decl *decl, const AvailabilityConstraint &constraint,
122+
const AvailabilityConstraintFlags flags) {
122123
auto domain = constraint.getDomain();
123124

124125
switch (constraint.getReason()) {
125126
case AvailabilityConstraint::Reason::UnconditionallyUnavailable:
127+
if (flags.contains(AvailabilityConstraintFlag::
128+
AllowUniversallyUnavailableInCompatibleContexts))
129+
return true;
130+
126131
// Always reject uses of universally unavailable declarations, regardless
127132
// of context, since there are no possible compilation configurations in
128133
// which they are available. However, make an exception for types and
@@ -162,11 +167,12 @@ static bool canIgnoreConstraintInUnavailableContexts(
162167
static bool
163168
shouldIgnoreConstraintInContext(const Decl *decl,
164169
const AvailabilityConstraint &constraint,
165-
const AvailabilityContext &context) {
170+
const AvailabilityContext &context,
171+
const AvailabilityConstraintFlags flags) {
166172
if (!context.isUnavailable())
167173
return false;
168174

169-
if (!canIgnoreConstraintInUnavailableContexts(decl, constraint))
175+
if (!canIgnoreConstraintInUnavailableContexts(decl, constraint, flags))
170176
return false;
171177

172178
return context.containsUnavailableDomain(constraint.getDomain());
@@ -256,7 +262,7 @@ static void getAvailabilityConstraintsForDecl(
256262
// declaration is unconditionally unavailable in a domain for which
257263
// the context is already unavailable.
258264
llvm::erase_if(constraints, [&](const AvailabilityConstraint &constraint) {
259-
return shouldIgnoreConstraintInContext(decl, constraint, context);
265+
return shouldIgnoreConstraintInContext(decl, constraint, context, flags);
260266
});
261267
}
262268

lib/AST/Type.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2844,6 +2844,11 @@ static bool hasRetainablePointerRepresentation(CanType type) {
28442844
type = objType;
28452845
}
28462846

2847+
// C++ imported `SWIFT_SHARED_REFERENCE` classes are not compatible with
2848+
// Swift's retain/release runtime functions.
2849+
if (type.isForeignReferenceType())
2850+
return false;
2851+
28472852
return isBridgeableObjectType(type);
28482853
}
28492854

lib/Sema/ConstraintSystem.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4997,11 +4997,7 @@ bool ConstraintSystem::isReadOnlyKeyPathComponent(
49974997
// If the setter is unavailable, then the keypath ought to be read-only
49984998
// in this context.
49994999
if (auto setter = storage->getOpaqueAccessor(AccessorKind::Set)) {
5000-
// FIXME: [availability] Fully unavailable setters should cause the key path
5001-
// to be readonly too.
5002-
auto constraint =
5003-
getUnsatisfiedAvailabilityConstraint(setter, DC, referenceLoc);
5004-
if (constraint && constraint->isPotentiallyAvailable())
5000+
if (getUnsatisfiedAvailabilityConstraint(setter, DC, referenceLoc))
50055001
return true;
50065002
}
50075003

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1771,8 +1771,17 @@ std::optional<AvailabilityConstraint>
17711771
swift::getUnsatisfiedAvailabilityConstraint(const Decl *decl,
17721772
const DeclContext *referenceDC,
17731773
SourceLoc referenceLoc) {
1774+
AvailabilityConstraintFlags flags;
1775+
1776+
// In implicit code, allow references to universally unavailable declarations
1777+
// as long as the context is also universally unavailable.
1778+
if (referenceLoc.isInvalid())
1779+
flags |= AvailabilityConstraintFlag::
1780+
AllowUniversallyUnavailableInCompatibleContexts;
1781+
17741782
return getAvailabilityConstraintsForDecl(
1775-
decl, AvailabilityContext::forLocation(referenceLoc, referenceDC))
1783+
decl, AvailabilityContext::forLocation(referenceLoc, referenceDC),
1784+
flags)
17761785
.getPrimaryConstraint();
17771786
}
17781787

lib/Sema/TypeCheckStorage.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1063,7 +1063,7 @@ getPropertyWrapperLValueness(VarDecl *var) {
10631063
/// - Wrapped: \c self._member.wrappedValue
10641064
/// - Composition: \c self._member.wrappedValue.wrappedValue….wrappedValue
10651065
/// - Projected: \c self._member.projectedValue
1066-
/// - Enclosed instance: \c Wrapper[_enclosedInstance: self, …]
1066+
/// - Enclosed instance: \c Wrapper[_enclosingInstance: self, …]
10671067
static Expr *buildStorageReference(AccessorDecl *accessor,
10681068
AbstractStorageDecl *storage,
10691069
TargetImpl target,

test/Availability/availability_accessors.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,14 @@ struct BaseStruct<T> {
6363
var unavailableSetter: T {
6464
get { fatalError() }
6565
@available(*, unavailable)
66-
set { fatalError() } // expected-note 38 {{setter for 'unavailableSetter' has been explicitly marked unavailable here}}
66+
set { fatalError() } // expected-note 33 {{setter for 'unavailableSetter' has been explicitly marked unavailable here}}
6767
}
6868

6969
var unavailableGetterAndSetter: T {
7070
@available(*, unavailable)
7171
get { fatalError() } // expected-note 67 {{getter for 'unavailableGetterAndSetter' has been explicitly marked unavailable here}}
7272
@available(*, unavailable)
73-
set { fatalError() } // expected-note 38 {{setter for 'unavailableGetterAndSetter' has been explicitly marked unavailable here}}
73+
set { fatalError() } // expected-note 33 {{setter for 'unavailableGetterAndSetter' has been explicitly marked unavailable here}}
7474
}
7575
}
7676

@@ -318,17 +318,17 @@ func testKeyPathAssignments_Struct(_ someValue: StructValue) {
318318
a[keyPath: \.[takesInOut(&x.unavailableGetter.a.b)]] = 0 // expected-error {{getter for 'unavailableGetter' is unavailable}}
319319
a[keyPath: \.[takesInOut(&x.unavailableGetter[0].b)]] = 0 // expected-error {{getter for 'unavailableGetter' is unavailable}}
320320

321-
x[keyPath: \.unavailableSetter] = someValue // expected-error {{setter for 'unavailableSetter' is unavailable}}
322-
x[keyPath: \.unavailableSetter.a] = someValue.a // expected-error {{setter for 'unavailableSetter' is unavailable}}
323-
x[keyPath: \.unavailableSetter[0]] = someValue.a // expected-error {{setter for 'unavailableSetter' is unavailable}}
324-
x[keyPath: \.unavailableSetter[0].b] = 1 // expected-error {{setter for 'unavailableSetter' is unavailable}}
321+
x[keyPath: \.unavailableSetter] = someValue // expected-error {{cannot assign through subscript: key path is read-only}}
322+
x[keyPath: \.unavailableSetter.a] = someValue.a // expected-error {{cannot assign through subscript: key path is read-only}}
323+
x[keyPath: \.unavailableSetter[0]] = someValue.a // expected-error {{cannot assign through subscript: key path is read-only}}
324+
x[keyPath: \.unavailableSetter[0].b] = 1 // expected-error {{cannot assign through subscript: key path is read-only}}
325325
a[keyPath: \.[takesInOut(&x.unavailableSetter.a.b)]] = 0 // expected-error {{setter for 'unavailableSetter' is unavailable}}
326326
a[keyPath: \.[takesInOut(&x.unavailableSetter[0].b)]] = 0 // expected-error {{setter for 'unavailableSetter' is unavailable}}
327327

328-
x[keyPath: \.unavailableGetterAndSetter] = someValue // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
329-
x[keyPath: \.unavailableGetterAndSetter.a] = someValue.a // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
330-
x[keyPath: \.unavailableGetterAndSetter[0]] = someValue.a // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
331-
x[keyPath: \.unavailableGetterAndSetter[0].b] = 1 // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
328+
x[keyPath: \.unavailableGetterAndSetter] = someValue // expected-error {{cannot assign through subscript: key path is read-only}}
329+
x[keyPath: \.unavailableGetterAndSetter.a] = someValue.a // expected-error {{cannot assign through subscript: key path is read-only}}
330+
x[keyPath: \.unavailableGetterAndSetter[0]] = someValue.a // expected-error {{cannot assign through subscript: key path is read-only}}
331+
x[keyPath: \.unavailableGetterAndSetter[0].b] = 1 // expected-error {{cannot assign through subscript: key path is read-only}}
332332
a[keyPath: \.[takesInOut(&x.unavailableGetterAndSetter.a.b)]] = 0 // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
333333
a[keyPath: \.[takesInOut(&x.unavailableGetterAndSetter[0].b)]] = 0 // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}} expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
334334
}
@@ -352,7 +352,7 @@ func testKeyPathAssignments_Class(_ someValue: ClassValue) {
352352
a[keyPath: \.[takesInOut(&x.unavailableGetter.a.b)]] = 0 // expected-error {{getter for 'unavailableGetter' is unavailable}}
353353
a[keyPath: \.[takesInOut(&x.unavailableGetter[0].b)]] = 0 // expected-error {{getter for 'unavailableGetter' is unavailable}}
354354

355-
x[keyPath: \.unavailableSetter] = someValue // expected-error {{setter for 'unavailableSetter' is unavailable}}
355+
x[keyPath: \.unavailableSetter] = someValue // expected-error {{cannot assign through subscript: key path is read-only}}
356356
// FIXME: spurious unavailable setter error
357357
x[keyPath: \.unavailableSetter.a] = someValue.a // expected-error {{setter for 'unavailableSetter' is unavailable}}
358358
// FIXME: spurious unavailable setter error
@@ -362,7 +362,7 @@ func testKeyPathAssignments_Class(_ someValue: ClassValue) {
362362
a[keyPath: \.[takesInOut(&x.unavailableSetter.a.b)]] = 0
363363
a[keyPath: \.[takesInOut(&x.unavailableSetter[0].b)]] = 0
364364

365-
x[keyPath: \.unavailableGetterAndSetter] = someValue // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
365+
x[keyPath: \.unavailableGetterAndSetter] = someValue // expected-error {{cannot assign through subscript: key path is read-only}}
366366
x[keyPath: \.unavailableGetterAndSetter.a] = someValue.a // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
367367
x[keyPath: \.unavailableGetterAndSetter[0]] = someValue.a // expected-error {{setter for 'unavailableGetterAndSetter' is unavailable}}
368368
// FIXME: spurious unavailable setter error

test/Availability/property_wrapper_availability.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,36 @@ func unavailableOnMacOSFunc(
186186
@WrappedValueUnavailableOnMacOS var unavailableWrappedValueLocal = S()
187187
@WrappedValueAvailable51 var wrappedValueAavailable51 = S()
188188
}
189+
190+
@propertyWrapper
191+
struct Observable<Value> {
192+
private var stored: Value
193+
194+
init(wrappedValue: Value) {
195+
self.stored = wrappedValue
196+
}
197+
198+
var wrappedValue: Value {
199+
get { fatalError() }
200+
set { fatalError() }
201+
}
202+
203+
static subscript<EnclosingSelf>(
204+
_enclosingInstance observed: EnclosingSelf,
205+
wrapped wrappedKeyPath: ReferenceWritableKeyPath<EnclosingSelf, Value>,
206+
storage storageKeyPath: ReferenceWritableKeyPath<EnclosingSelf, Self>
207+
) -> Value {
208+
get { fatalError() }
209+
set { fatalError() }
210+
}
211+
}
212+
213+
@available(macOS, unavailable)
214+
class UnavailableOnMacOSObserved {
215+
@Observable var observedProperty = 17
216+
}
217+
218+
@available(*, unavailable)
219+
class UniversallyUnavailableObserved {
220+
@Observable var observedProperty = 17
221+
}

0 commit comments

Comments
 (0)