Wrap only changes related to the closure frontend logic

This commit is contained in:
Mykola Pokhylets
2025-07-04 17:13:46 +02:00
parent ae48446716
commit 89f8f8b9bf
27 changed files with 82 additions and 153 deletions

View File

@@ -715,7 +715,8 @@ public:
/// RHS of the self condition references a var defined in a capture list.
/// - If `requireLoadExpr` is `true`, additionally requires that the RHS of
/// the self condition is a `LoadExpr`.
/// TODO: Remove `requireLoadExpr` after full-on of the WeakLet feature
/// TODO: Remove `requireLoadExpr` after full-on of the ImmutableWeakCaptures
/// feature
bool rebindsSelf(ASTContext &Ctx, bool requiresCaptureListRef = false,
bool requireLoadExpr = false) const;

View File

@@ -296,7 +296,7 @@ UPCOMING_FEATURE(InternalImportsByDefault, 409, 7)
MIGRATABLE_UPCOMING_FEATURE(MemberImportVisibility, 444, 7)
MIGRATABLE_UPCOMING_FEATURE(InferIsolatedConformances, 470, 7)
MIGRATABLE_UPCOMING_FEATURE(NonisolatedNonsendingByDefault, 461, 7)
UPCOMING_FEATURE(WeakLet, 481, 7)
UPCOMING_FEATURE(ImmutableWeakCaptures, 481, 7)
// Optional language features / modes

View File

@@ -1373,7 +1373,8 @@ CaptureListEntry CaptureListEntry::createParsed(
SourceRange ownershipRange, Identifier name, SourceLoc nameLoc,
SourceLoc equalLoc, Expr *initializer, DeclContext *DC) {
bool forceVar = ownershipKind == ReferenceOwnership::Weak && !Ctx.LangOpts.hasFeature(Feature::WeakLet);
bool forceVar = ownershipKind == ReferenceOwnership::Weak &&
!Ctx.LangOpts.hasFeature(Feature::ImmutableWeakCaptures);
auto introducer = forceVar ? VarDecl::Introducer::Var : VarDecl::Introducer::Let;
auto *VD =
new (Ctx) VarDecl(/*isStatic==*/false, introducer, nameLoc, name, DC);

View File

@@ -441,15 +441,7 @@ UNINTERESTING_FEATURE(BuiltinSelect)
UNINTERESTING_FEATURE(BuiltinInterleave)
UNINTERESTING_FEATURE(BuiltinVectorsExternC)
UNINTERESTING_FEATURE(AddressOfProperty2)
static bool usesFeatureWeakLet(Decl *decl) {
if (auto *VD = dyn_cast<VarDecl>(decl)) {
if (auto *refAttr = VD->getAttrs().getAttribute<ReferenceOwnershipAttr>()) {
return VD->isLet() && refAttr->get() == ReferenceOwnership::Weak;
}
}
return false;
}
UNINTERESTING_FEATURE(ImmutableWeakCaptures)
// ----------------------------------------------------------------------------
// MARK: - FeatureSet

View File

@@ -170,15 +170,6 @@ CaptureKind TypeConverter::getDeclCaptureKind(CapturedValue capture,
return CaptureKind::StorageAddress;
}
// Reference storage types can appear in a capture list, which means
// we might allocate boxes to store the captures. However, those boxes
// have the same lifetime as the closure itself, so we must capture
// the box itself and not the payload, even if the closure is noescape,
// otherwise they will be destroyed when the closure is formed.
if (var->getInterfaceType()->is<ReferenceStorageType>() && !Context.LangOpts.hasFeature(Feature::WeakLet)) {
return CaptureKind::Box;
}
// For 'let' constants
if (!var->supportsMutation()) {
assert(getTypeProperties(

View File

@@ -1780,8 +1780,8 @@ public:
if (!conditionalStmt) {
return false;
}
if (Ctx.LangOpts.hasFeature(Feature::WeakLet)) {
if (Ctx.LangOpts.hasFeature(Feature::ImmutableWeakCaptures)) {
// Require that the RHS of the `let self = self` condition
// refers to a variable defined in a capture list.
// This lets us reject invalid examples like:
@@ -1809,7 +1809,6 @@ public:
//
return conditionalStmt->rebindsSelf(Ctx, /*requiresCaptureListRef*/ false,
/*requireLoadExpr*/ true);
}
}
@@ -4108,9 +4107,12 @@ VarDeclUsageChecker::~VarDeclUsageChecker() {
// If this variable has WeakStorageType, then it can be mutated in ways we
// don't know.
if (var->getInterfaceType()->is<WeakStorageType>() && !DC->getASTContext().LangOpts.hasFeature(Feature::WeakLet))
if (var->getInterfaceType()->is<WeakStorageType>() &&
(access & RK_CaptureList) &&
!DC->getASTContext().LangOpts.hasFeature(
Feature::ImmutableWeakCaptures))
access |= RK_Written;
// Diagnose variables that were never used (other than their
// initialization).
//

View File

@@ -5406,11 +5406,6 @@ Type TypeChecker::checkReferenceOwnershipAttr(VarDecl *var, Type type,
case ReferenceOwnershipOptionality::Allowed:
break;
case ReferenceOwnershipOptionality::Required:
if (var->isLet() && !ctx.LangOpts.hasFeature(Feature::WeakLet)) {
var->diagnose(diag::invalid_ownership_is_let, ownershipKind);
attr->setInvalid();
}
if (!isOptional) {
attr->setInvalid();

View File

@@ -1,12 +1,12 @@
// RUN: %target-swift-frontend -emit-sil -swift-version 6 -target %target-swift-5.1-abi-triple -verify -verify-additional-prefix old- %s -o /dev/null
// RUN: %target-swift-frontend -emit-sil -swift-version 6 -target %target-swift-5.1-abi-triple -verify -verify-additional-prefix new- -enable-upcoming-feature WeakLet %s -o /dev/null
// RUN: %target-swift-frontend -emit-sil -swift-version 6 -target %target-swift-5.1-abi-triple -verify -verify-additional-prefix new- -enable-upcoming-feature ImmutableWeakCaptures %s -o /dev/null
// This test validates the behavior of transfer non sendable around ownership
// constructs like non copyable types, consuming/borrowing parameters, and inout
// parameters.
// REQUIRES: concurrency
// REQUIRES: swift_feature_WeakLet
// REQUIRES: swift_feature_ImmutableWeakCaptures
final class S: Sendable {
func foo() {}
@@ -30,15 +30,12 @@ final class CheckOptionality1: Sendable {
}
final class CheckOptionality2: Sendable {
// expected-old-error@+3 {{'weak' must be a mutable variable, because it may change at runtime}}
// expected-old-error@+2 {{'weak' variable should have optional type 'S?'}}
// expected-new-error@+1 {{'weak' variable should have optional type 'S?'}}
// expected-error@+1 {{'weak' variable should have optional type 'S?'}}
weak let x: S = getS()
}
final class CheckSendability1: Sendable {
// expected-old-error@+2 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability1' is mutable}}
// expected-new-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability1' is mutable}}
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability1' is mutable}}
weak var x: S? = nil
weak var y: S? {
@@ -48,32 +45,26 @@ final class CheckSendability1: Sendable {
}
final class CheckSendability2: Sendable {
// expected-old-error@+2 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability2' is mutable}}
// expected-new-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability2' is mutable}}
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability2' is mutable}}
weak var x: NS? = nil
}
final class CheckSendability3: Sendable {
// expected-old-error@+1 {{'weak' must be a mutable variable, because it may change at runtime}}
weak let x: S? = nil
}
final class CheckSendability4: Sendable {
// expected-old-error@+3 {{'weak' must be a mutable variable, because it may change at runtime}}
// expected-old-error@+2 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability4' contains non-Sendable type 'NS'}}
// expected-new-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability4' contains non-Sendable type 'NS'}}
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability4' contains non-Sendable type 'NS'}}
weak let x: NS? = nil
}
final class CheckSendability5: Sendable {
// expected-old-error@+2 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability5' is mutable}}
// expected-new-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability5' is mutable}}
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability5' is mutable}}
unowned var x: S = getS()
}
final class CheckSendability6: Sendable {
// expected-old-error@+2 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability6' is mutable}}
// expected-new-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability6' is mutable}}
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability6' is mutable}}
unowned var x: NS = getNS()
}
@@ -87,14 +78,12 @@ final class CheckSendability8: Sendable {
}
final class CheckSendability9: Sendable {
// expected-old-error@+2 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability9' is mutable}}
// expected-new-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability9' is mutable}}
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability9' is mutable}}
unowned(unsafe) var x: S = getS()
}
final class CheckSendability10: Sendable {
// expected-old-error@+2 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability10' is mutable}}
// expected-new-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability10' is mutable}}
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability10' is mutable}}
unowned(unsafe) var x: NS = getNS()
}
@@ -109,17 +98,15 @@ final class CheckSendability12: Sendable {
func checkWeakCapture1(_ strongRef: S) -> @Sendable () -> Void {
// expected-new-warning@+1 {{variable 'weakRef' was never mutated; consider changing to 'let' constant}}
// expected-warning@+1 {{variable 'weakRef' was never mutated; consider changing to 'let' constant}}
weak var weakRef: S? = strongRef
return {
// expected-old-error@+2 {{reference to captured var 'weakRef' in concurrently-executing code}}
// expected-new-error@+1 {{reference to captured var 'weakRef' in concurrently-executing code}}
// expected-error@+1 {{reference to captured var 'weakRef' in concurrently-executing code}}
weakRef?.foo()
}
}
func checkWeakCapture2(_ strongRef: S) -> @Sendable () -> Void {
// expected-old-error@+1 {{'weak' must be a mutable variable, because it may change at runtime}}
weak let weakRef: S? = strongRef
return {
weakRef?.foo()
@@ -137,7 +124,7 @@ func checkWeakCapture3(_ strongRef: S) -> @Sendable () -> Void {
}
func checkWeakCapture4(_ strongRef: NS) -> @Sendable () -> Void {
// expected-new-warning@+1 {{variable 'weakRef' was never mutated; consider changing to 'let' constant}}
// expected-warning@+1 {{variable 'weakRef' was never mutated; consider changing to 'let' constant}}
weak var weakRef: NS? = strongRef
return {
// expected-error@+2 {{capture of 'weakRef' with non-Sendable type 'NS?' in a '@Sendable' closure}}
@@ -147,7 +134,6 @@ func checkWeakCapture4(_ strongRef: NS) -> @Sendable () -> Void {
}
func checkWeakCapture5(_ strongRef: NS) -> @Sendable () -> Void {
// expected-old-error@+1 {{'weak' must be a mutable variable, because it may change at runtime}}
weak let weakRef: NS? = strongRef
return {
// expected-error@+1 {{capture of 'weakRef' with non-Sendable type 'NS?' in a '@Sendable' closure}}

View File

@@ -1,7 +1,7 @@
// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s
// RUN: %target-swift-frontend %s -enable-upcoming-feature WeakLet -emit-ir -g -o - | %FileCheck %s
// RUN: %target-swift-frontend %s -enable-upcoming-feature ImmutableWeakCaptures -emit-ir -g -o - | %FileCheck %s
// REQUIRES: swift_feature_WeakLet
// REQUIRES: swift_feature_ImmutableWeakCaptures
class A {
init(handler: (() -> ())) { }

View File

@@ -1,6 +1,6 @@
// RUN: %target-swift-frontend -g -Xllvm -sil-print-types -emit-sil %s -parse-as-library -module-name a | %FileCheck %s
// RUN: %target-swift-frontend -g -Xllvm -sil-print-types -emit-sil %s -parse-as-library -module-name a -enable-upcoming-feature WeakLet | %FileCheck %s --check-prefixes=CHECK,CHECK-HAS-WEAK-LET
// REQUIRES: swift_feature_WeakLet
// RUN: %target-swift-frontend -g -Xllvm -sil-print-types -emit-sil %s -parse-as-library -module-name a -enable-upcoming-feature ImmutableWeakCaptures | %FileCheck %s --check-prefixes=CHECK,CHECK-HAS-WEAK-LET
// REQUIRES: swift_feature_ImmutableWeakCaptures
open class C {
public func run() {
{ [weak self] in

View File

@@ -1,7 +1,7 @@
// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s
// RUN: %target-swift-frontend %s -enable-upcoming-feature WeakLet -emit-ir -g -o - | %FileCheck %s
// RUN: %target-swift-frontend %s -enable-upcoming-feature ImmutableWeakCaptures -emit-ir -g -o - | %FileCheck %s
// REQUIRES: swift_feature_WeakLet
// REQUIRES: swift_feature_ImmutableWeakCaptures
public class ClosureMaker {
var a : Int

View File

@@ -1,8 +1,8 @@
// RUN: %target-run-simple-swift | %FileCheck %s
// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-feature -Xfrontend WeakLet) | %FileCheck %s --check-prefixes=CHECK,CHECK-WEAK-LET
// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-feature -Xfrontend ImmutableWeakCaptures) | %FileCheck %s --check-prefixes=CHECK
// REQUIRES: executable_test
// REQUIRES: swift_feature_WeakLet
// REQUIRES: swift_feature_ImmutableWeakCaptures
protocol Protocol : class {
func noop()
@@ -79,19 +79,17 @@ func testWeakInLet() {
testWeakInLet()
#if hasFeature(WeakLet)
func testWeakLet() {
print("testWeakLet") // CHECK-WEAK-LET-LABEL: testWeakLet
print("testWeakLet") // CHECK-LABEL: testWeakLet
var obj: SwiftClassBase? = SwiftClass() // CHECK-WEAK-LET: SwiftClass Created
var obj: SwiftClassBase? = SwiftClass() // CHECK: SwiftClass Created
weak let weakRef = obj
printState(weakRef) // CHECK-WEAK-LET-NEXT: is present
obj = nil // CHECK-WEAK-LET-NEXT: SwiftClass Destroyed
printState(weakRef) // CHECK-WEAK-LET-NEXT: is nil
printState(weakRef) // CHECK-NEXT: is present
obj = nil // CHECK-NEXT: SwiftClass Destroyed
printState(weakRef) // CHECK-NEXT: is nil
}
testWeakLet()
#endif
//======================== Test Classbound Protocols ========================

View File

@@ -2,13 +2,13 @@
// RUN: %target-codesign %t-main
// RUN: %target-run %t-main | %FileCheck %s
// RUN: %target-build-swift %s -Xfrontend -disable-objc-attr-requires-foundation-module -enable-upcoming-feature WeakLet -o %t-main-weak-let
// RUN: %target-build-swift %s -Xfrontend -disable-objc-attr-requires-foundation-module -enable-upcoming-feature ImmutableWeakCaptures -o %t-main-weak-let
// RUN: %target-codesign %t-main-weak-let
// RUN: %target-run %t-main-weak-let | %FileCheck %s --check-prefixes=CHECK,CHECK-WEAK-LET
// REQUIRES: executable_test
// REQUIRES: objc_interop
// REQUIRES: swift_feature_WeakLet
// REQUIRES: swift_feature_ImmutableWeakCaptures
import Foundation
@@ -54,7 +54,6 @@ func testObjCClass() {
testObjCClass()
#if hasFeature(WeakLet)
func testObjCWeakLet() {
print("testObjCWeakLet") // CHECK-WEAK-LET: testObjCWeakLet
@@ -80,4 +79,3 @@ func testObjCWeakLetCapture() {
}
testObjCWeakLetCapture()
#endif

View File

@@ -1,9 +1,7 @@
// RUN: %target-typecheck-verify-swift -verify-additional-prefix no-weak-let-
// RUN: %target-typecheck-verify-swift -enable-upcoming-feature WeakLet
// RUN: %target-typecheck-verify-swift
// REQUIRES: swift_swift_parser
// FIXME: Swift parser is not enabled on Linux CI yet.
// REQUIRES: OS=macosx
// REQUIRES: swift_feature_WeakLet
// rdar://15946844
func test1(inout var x : Int) {} // expected-warning {{'var' in this position is interpreted as an argument label}} {{18-21=`var`}}
@@ -121,7 +119,6 @@ prefix func %<T>(x: T) -> T { return x } // No error expected - the < is conside
struct Weak<T: class> { // expected-error {{'class' constraint can only appear on protocol declarations}}
// expected-note@-1 {{did you mean to write an 'AnyObject' constraint?}} {{16-21=AnyObject}}
// expected-no-weak-let-error@+1 {{'weak' must be a mutable variable, because it may change at runtime}}
weak let value: T // expected-error {{'weak' variable should have optional type 'T?'}} expected-error {{'weak' must not be applied to non-class-bound 'T'; consider adding a protocol conformance that has a class bound}}
}

View File

@@ -1,7 +1,7 @@
// RUN: %target-swift-emit-silgen %s | %FileCheck %s --check-prefixes=CHECK,CHECK-NO-WEAK-LET
// RUN: %target-swift-emit-silgen -enable-upcoming-feature WeakLet %s | %FileCheck %s --check-prefixes=CHECK,CHECK-HAS-WEAK-LET
// RUN: %target-swift-emit-silgen -enable-upcoming-feature ImmutableWeakCaptures %s | %FileCheck %s --check-prefixes=CHECK,CHECK-HAS-WEAK-LET
// REQUIRES: swift_feature_WeakLet
// REQUIRES: swift_feature_ImmutableWeakCaptures
// https://github.com/apple/swift/issues/50924
@@ -34,7 +34,7 @@ class C {
func returnsSelf1() -> Self {
return { [weak self] in self?.f(); return .init() }()
// CHECK-NO-WEAK-LET-LABEL: sil private [ossa] @{{.*}}returnsSelf{{.*}} : $@convention(thin) (@guaranteed { var @sil_weak Optional<C> }, @thick @dynamic_self C.Type) -> @owned C {
// CHECK-NO-WEAK-LET-LABEL: sil private [ossa] @{{.*}}returnsSelf{{.*}} : $@convention(thin) (@inout_aliasable @sil_weak Optional<C>, @thick @dynamic_self C.Type) -> @owned C {
// CHECK-HAS-WEAK-LET-LABEL: sil private [ossa] @{{.*}}returnsSelf{{.*}} : $@convention(thin) (@in_guaranteed @sil_weak Optional<C>, @thick @dynamic_self C.Type) -> @owned C {
}

View File

@@ -1,6 +1,6 @@
// RUN: %target-swift-emit-silgen -enable-upcoming-feature WeakLet %s -verify
// RUN: %target-swift-emit-silgen -enable-upcoming-feature ImmutableWeakCaptures %s -verify
// REQUIRES: swift_feature_WeakLet
// REQUIRES: swift_feature_ImmutableWeakCaptures
/// We emit an invalid forward capture as an 'undef'; make sure
/// we cover the various possible cases.

View File

@@ -1,12 +1,12 @@
// RUN: %target-swift-emit-silgen -Xllvm -sil-print-types -swift-version 4 -enable-upcoming-feature WeakLet %s -disable-objc-attr-requires-foundation-module -enable-objc-interop | %FileCheck %s
// RUN: %target-swift-emit-sil -Xllvm -sil-print-types -swift-version 4 -O -enable-upcoming-feature WeakLet %s -disable-objc-attr-requires-foundation-module -enable-objc-interop
// RUN: %target-swift-emit-ir -swift-version 4 -enable-upcoming-feature WeakLet %s -disable-objc-attr-requires-foundation-module -enable-objc-interop
// RUN: %target-swift-emit-silgen -Xllvm -sil-print-types -swift-version 4 -enable-upcoming-feature ImmutableWeakCaptures %s -disable-objc-attr-requires-foundation-module -enable-objc-interop | %FileCheck %s
// RUN: %target-swift-emit-sil -Xllvm -sil-print-types -swift-version 4 -O -enable-upcoming-feature ImmutableWeakCaptures %s -disable-objc-attr-requires-foundation-module -enable-objc-interop
// RUN: %target-swift-emit-ir -swift-version 4 -enable-upcoming-feature ImmutableWeakCaptures %s -disable-objc-attr-requires-foundation-module -enable-objc-interop
// RUN: %target-swift-emit-silgen -Xllvm -sil-print-types -swift-version 5 -enable-upcoming-feature WeakLet %s -disable-objc-attr-requires-foundation-module -enable-objc-interop | %FileCheck %s
// RUN: %target-swift-emit-sil -Xllvm -sil-print-types -swift-version 5 -O -enable-upcoming-feature WeakLet %s -disable-objc-attr-requires-foundation-module -enable-objc-interop
// RUN: %target-swift-emit-ir -swift-version 5 -enable-upcoming-feature WeakLet %s -disable-objc-attr-requires-foundation-module -enable-objc-interop
// RUN: %target-swift-emit-silgen -Xllvm -sil-print-types -swift-version 5 -enable-upcoming-feature ImmutableWeakCaptures %s -disable-objc-attr-requires-foundation-module -enable-objc-interop | %FileCheck %s
// RUN: %target-swift-emit-sil -Xllvm -sil-print-types -swift-version 5 -O -enable-upcoming-feature ImmutableWeakCaptures %s -disable-objc-attr-requires-foundation-module -enable-objc-interop
// RUN: %target-swift-emit-ir -swift-version 5 -enable-upcoming-feature ImmutableWeakCaptures %s -disable-objc-attr-requires-foundation-module -enable-objc-interop
// REQUIRES: swift_feature_WeakLet
// REQUIRES: swift_feature_ImmutableWeakCaptures
protocol P {
func f() -> Self

View File

@@ -1,6 +1,4 @@
// RUN: %target-swift-emit-silgen %s -enable-objc-interop -enable-upcoming-feature WeakLet | %FileCheck %s
// REQUIRES: swift_feature_WeakLet
// RUN: %target-swift-emit-silgen %s -enable-objc-interop | %FileCheck %s
protocol ClassProtocol: AnyObject {}

View File

@@ -1,7 +1,4 @@
// RUN: %target-swift-emit-silgen -Xllvm -sil-print-types -module-name weak -Xllvm -sil-full-demangle %s | %FileCheck %s
// RUN: %target-swift-emit-silgen -Xllvm -sil-print-types -module-name weak -Xllvm -sil-full-demangle %s -enable-upcoming-feature WeakLet | %FileCheck %s
// REQUIRES: swift_feature_WeakLet
class C {
func f() -> Int { return 42 }
@@ -69,7 +66,6 @@ func testClosureOverWeak() {
takeClosure { bC!.f() }
}
#if hasFeature(WeakLet)
func testClosureOverWeakLet() {
weak let bC = C()
takeClosure { bC!.f() }
@@ -80,8 +76,6 @@ func testClosureOverWeakCapture() {
takeClosure { [weak bC] in bC!.f() }
}
#endif
class CC {
weak var x: CC?

View File

@@ -1,7 +1,4 @@
// RUN: %target-swift-frontend -enable-copy-propagation=requested-passes-only -emit-sil -primary-file %s -o /dev/null -verify -verify-additional-prefix no-weak-let-
// RUN: %target-swift-frontend -enable-copy-propagation=requested-passes-only -enable-upcoming-feature WeakLet -emit-sil -primary-file %s -o /dev/null -verify -verify-additional-prefix has-weak-let-
// REQUIRES: swift_feature_WeakLet
// RUN: %target-swift-frontend -enable-copy-propagation=requested-passes-only -emit-sil -primary-file %s -o /dev/null -verify
import Swift
@@ -106,22 +103,15 @@ func test2() {
// Weak
// expected-has-weak-let-warning@+1 {{variable 'w1' was never mutated; consider changing to 'let' constant}} {{8-11=let}}
// expected-warning@+1 {{variable 'w1' was never mutated; consider changing to 'let' constant}} {{8-11=let}}
weak var w1 : SomeClass?
_ = w1 // ok: default-initialized
// Note: with -enable-copy-propagation, we also expect: {{weak reference will always be nil because the referenced object is deallocated here}}
#if hasFeature(WeakLet)
// expected-has-weak-let-warning@+3 {{instance will be immediately deallocated because variable 'w2' is 'weak'}}
// expected-has-weak-let-note@+2 {{a strong reference is required to prevent the instance from being deallocated}}
// expected-has-weak-let-note@+1 {{'w2' declared here}}
// expected-warning@+3 {{instance will be immediately deallocated because variable 'w2' is 'weak'}}
// expected-note@+2 {{a strong reference is required to prevent the instance from being deallocated}}
// expected-note@+1 {{'w2' declared here}}
weak let w2 = SomeClass()
#else
// expected-no-weak-let-warning@+3 {{instance will be immediately deallocated because variable 'w2' is 'weak'}}
// expected-no-weak-let-note@+2 {{a strong reference is required to prevent the instance from being deallocated}}
// expected-no-weak-let-note@+1 {{'w2' declared here}}
weak var w2 = SomeClass()
#endif
_ = w2 // ok

View File

@@ -1,6 +1,6 @@
// RUN: %target-typecheck-verify-swift -module-name ModuleName -enable-upcoming-feature WeakLet
// RUN: %target-typecheck-verify-swift -module-name ModuleName -enable-upcoming-feature ImmutableWeakCaptures
// REQUIRES: swift_feature_WeakLet
// REQUIRES: swift_feature_ImmutableWeakCaptures
protocol ClassProtocol : class {
init()

View File

@@ -1,7 +1,4 @@
// RUN: %target-typecheck-verify-swift -verify-additional-prefix no-weak-let-
// RUN: %target-typecheck-verify-swift -enable-upcoming-feature WeakLet -verify-additional-prefix has-weak-let-
// REQUIRES: swift_feature_WeakLet
// RUN: %target-typecheck-verify-swift
func markUsed<T>(_ t: T) {}
@@ -118,11 +115,10 @@ var x15: Int {
// applied to the getter.
weak
var foo: SomeClass? = SomeClass()
// expected-no-weak-let-warning@-1 {{variable 'foo' was written to, but never read}}
// expected-has-weak-let-warning@-2 {{variable 'foo' was never used; consider replacing with '_' or removing it}}
// expected-warning@-3 {{instance will be immediately deallocated because variable 'foo' is 'weak'}}
// expected-note@-4 {{a strong reference is required to prevent the instance from being deallocated}}
// expected-note@-5 {{'foo' declared here}}
// expected-warning@-1 {{variable 'foo' was never used; consider replacing with '_' or removing it}}
// expected-warning@-2 {{instance will be immediately deallocated because variable 'foo' is 'weak'}}
// expected-note@-3 {{a strong reference is required to prevent the instance from being deallocated}}
// expected-note@-4 {{'foo' declared here}}
return 0
}

View File

@@ -1,7 +1,4 @@
// RUN: %target-typecheck-verify-swift -verify-additional-prefix no-weak-let-
// RUN: %target-typecheck-verify-swift -enable-upcoming-feature WeakLet -verify-additional-prefix has-weak-let-
// REQUIRES: swift_feature_WeakLet
// RUN: %target-typecheck-verify-swift
var t1 : Int
var t2 = 10
@@ -92,10 +89,9 @@ class SomeClass {}
weak let V = SomeClass() // ok since SE-0481
// expected-no-weak-let-error@-1 {{'weak' must be a mutable variable, because it may change at runtime}}
// expected-has-weak-let-warning@-2 {{instance will be immediately deallocated because variable 'V' is 'weak'}}
// expected-has-weak-let-note@-3 {{'V' declared here}}
// expected-has-weak-let-note@-4 {{a strong reference is required to prevent the instance from being deallocated}}
// expected-warning@-1 {{instance will be immediately deallocated because variable 'V' is 'weak'}}
// expected-note@-2 {{'V' declared here}}
// expected-note@-3 {{a strong reference is required to prevent the instance from being deallocated}}
let a = b ; let b = a
// expected-error@-1 {{circular reference}}

View File

@@ -1,7 +1,7 @@
// RUN: %target-typecheck-verify-swift -disable-availability-checking -verify-additional-prefix no-weak-let-
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-upcoming-feature WeakLet -verify-additional-prefix has-weak-let-
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-upcoming-feature ImmutableWeakCaptures -verify-additional-prefix has-weak-let-
// REQUIRES: swift_feature_WeakLet
// REQUIRES: swift_feature_ImmutableWeakCaptures
var func6 : (_ fn : (Int,Int) -> Int) -> ()
var func6a : ((Int, Int) -> Int) -> ()
@@ -1633,7 +1633,7 @@ final class AutoclosureTests {
let someOptional: Self? = Self()
var `self` = self ?? someOptional // expected-warning {{'self' was never mutated; consider changing to 'let' constant}}
guard let self = self else { return }
#if hasFeature(WeakLet)
#if hasFeature(ImmutableWeakCaptures)
method() // expected-has-weak-let-error{{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}}
#else
// This is not supposed to be permitted, but has been allowed since Swift 5.8,

View File

@@ -1,12 +1,12 @@
// There seems to be a minor bug in the diagnostic of the self-capture.
// Diagnostic algorithm does not @lvalue DeclRefExpr wrapped into LoadExpr,
// and enabling WeakLet removes the LoadExpr.
// and enabling ImmutableWeakCaptures removes the LoadExpr.
// As a result, diagnostic messages change slightly.
// RUN: %target-typecheck-verify-swift -swift-version 6 -verify-additional-prefix no-weak-let-
// RUN: %target-typecheck-verify-swift -swift-version 6 -verify-additional-prefix has-weak-let- -enable-upcoming-feature WeakLet
// RUN: %target-typecheck-verify-swift -swift-version 6 -verify-additional-prefix has-weak-let- -enable-upcoming-feature ImmutableWeakCaptures
// REQUIRES: swift_feature_WeakLet
// REQUIRES: swift_feature_ImmutableWeakCaptures
func doStuff(_ fn : @escaping () -> Int) {}
func doVoidStuff(_ fn : @escaping () -> ()) {}

View File

@@ -1,9 +1,9 @@
// RUN: %target-run-simple-swift(-Xfrontend -disable-availability-checking -swift-version 6)
// RUN: %target-run-simple-swift(-Xfrontend -disable-availability-checking -swift-version 6 -enable-upcoming-feature WeakLet)
// RUN: %target-run-simple-swift(-Xfrontend -disable-availability-checking -swift-version 6 -enable-upcoming-feature ImmutableWeakCaptures)
// REQUIRES: concurrency
// REQUIRES: executable_test
// REQUIRES: swift_feature_WeakLet
// REQUIRES: swift_feature_ImmutableWeakCaptures
// rdar://102155748
// UNSUPPORTED: back_deployment_runtime

View File

@@ -14,9 +14,9 @@
// RUN: if [ %target-runtime == "objc" ]; \
// RUN: then \
// RUN: %target-clang %S/Inputs/Mirror/Mirror.mm -c -o %t/Mirror.mm.o -g && \
// RUN: %target-build-swift -Xfrontend -disable-access-control -Xfrontend -enable-experimental-feature -Xfrontend WeakLet %s -I %S/Inputs/Mirror/ -Xlinker %t/Mirror.mm.o -o %t/Mirror; \
// RUN: %target-build-swift -Xfrontend -disable-access-control -Xfrontend -enable-experimental-feature -Xfrontend ImmutableWeakCaptures %s -I %S/Inputs/Mirror/ -Xlinker %t/Mirror.mm.o -o %t/Mirror; \
// RUN: else \
// RUN: %target-build-swift %s -Xfrontend -disable-access-control -Xfrontend -enable-experimental-feature -Xfrontend WeakLet -o %t/Mirror; \
// RUN: %target-build-swift %s -Xfrontend -disable-access-control -Xfrontend -enable-experimental-feature -Xfrontend ImmutableWeakCaptures -o %t/Mirror; \
// RUN: fi
// RUN: %target-codesign %t/Mirror
// RUN: %target-run %t/Mirror
@@ -24,7 +24,7 @@
// REQUIRES: executable_test
// REQUIRES: shell
// REQUIRES: reflection
// REQUIRES: swift_feature_WeakLet
// REQUIRES: swift_feature_ImmutableWeakCaptures
import StdlibUnittest
@@ -124,7 +124,6 @@ mirrors.test("class/NativeSwiftClassHasNativeWeakReferenceNoLeak") {
expectNil(verifier)
}
#if hasFeature(WeakLet)
class NativeSwiftClassHasWeakLet {
weak let weakProperty: AnyObject?
let x: Int
@@ -207,7 +206,6 @@ mirrors.test("class/NativeSwiftClassHasNativeWeakLetReferenceNoLeak") {
}
expectNil(verifier)
}
#endif
#if _runtime(_ObjC)
@@ -378,8 +376,6 @@ mirrors.test("struct/StructHasObjCClassBoundExistential") {
print(extractedChild)
}
#if hasFeature(WeakLet)
class NativeSwiftClassHasObjCClassBoundExistentialLet {
weak let weakProperty: ObjCClassExistential?
let x: Int
@@ -532,6 +528,4 @@ mirrors.test("struct/StructHasObjCClassBoundExistentialLet") {
#endif
#endif
runAllTests()