diff --git a/CHANGELOG.md b/CHANGELOG.md index 83edf56791968..b4a845a54e6e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,69 @@ > [!NOTE] > This is in reverse chronological order, so newer entries are added to the top. -## Swift (next) +## Swift 6.3 + +* The checking for illegal forward references to local variables is now consistent regardless of + whether the reference appears in a closure. Previously the type-checker could incorrectly permit + forward references within a closure that it would reject outside of the closure, however this + is not something that can be supported in general in the type-checker. In most cases this should + have no impact since such invalid references would have already been rejected by later diagnostic + passes in the compiler. However there are a couple of cases that were previously legal that are + now illegal. + + These include: + + - `lazy` local variables with initializers that forward reference a local variable in a closure, + or local variables with attached macros that relocate the initializer into an accessor, e.g: + + ```swift + func foo() { + lazy var x = { y } // error: use of local variable 'y' before its declaration + let y = 0 + } + ``` + + ```swift + func foo() { + @LazyLikeMacro var x = { y } // error: use of local variable 'y' before its declaration + let y = 0 + } + ``` + + - Forward references to local computed variables from a closure, e.g: + + ```swift + func foo() { + var x = { y } // error: use of local variable 'y' before its declaration + var y: Int { 0 } + } + ``` + + Both cases were already invalid if there was no closure involved. These are now consistently + rejected. + + This then allows for consistent shadowing behavior inside and outside of closures, allowing the + following previously illegal case to become legal: + + ```swift + struct S { + var x: Int + func foo() { + // Already legal, both refer to `self.x` + let y = x + let x = x + + let z = x // Refers to the local var. + } + func bar() { + // Both previously illegal, now both refer to `self.x`. + let y = { x }() + let x: Int = { x }() + + let z = x // Still refers to the local var. + } + } + ``` * [SE-0491][]: You can now use a module selector to specify which module Swift should look inside to find a named declaration. A diff --git a/lib/Sema/PreCheckTarget.cpp b/lib/Sema/PreCheckTarget.cpp index 4ee4290dd81b4..2d8b894788a15 100644 --- a/lib/Sema/PreCheckTarget.cpp +++ b/lib/Sema/PreCheckTarget.cpp @@ -393,29 +393,28 @@ static bool isMemberChainTail(Expr *expr, Expr *parent, MemberChainKind kind) { } static bool isValidForwardReference(ValueDecl *D, DeclContext *DC, - ValueDecl **localDeclAfterUse) { - *localDeclAfterUse = nullptr; - - // References to variables injected by lldb are always valid. - if (isa(D) && cast(D)->isDebuggerVar()) + ValueDecl *&localDeclAfterUse) { + // Only VarDecls require declaration before use. + auto *VD = dyn_cast(D); + if (!VD) return true; - // If we find something in the current context, it must be a forward - // reference, because otherwise if it was in scope, it would have - // been returned by the call to ASTScope::lookupLocalDecls() above. - if (D->getDeclContext()->isLocalContext()) { - do { - if (D->getDeclContext() == DC) { - *localDeclAfterUse = D; - return false; - } + // Non-local and variables injected by lldb are always valid. + auto *varDC = VD->getDeclContext(); + if (!varDC->isLocalContext() || VD->isDebuggerVar()) + return true; - // If we're inside of a 'defer' context, walk up to the parent - // and check again. We don't want 'defer' bodies to forward - // reference bindings in the immediate outer scope. - } while (isa(DC) && - cast(DC)->isDeferBody() && - (DC = DC->getParent())); + while (true) { + if (varDC == DC) { + localDeclAfterUse = VD; + return false; + } + if (isa(DC) || + (isa(DC) && cast(DC)->isDeferBody())) { + DC = DC->getParent(); + continue; + } + break; } return true; } @@ -587,12 +586,11 @@ static Expr *resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE, DeclContext *DC, Lookup = TypeChecker::lookupUnqualified(DC, LookupName, Loc, lookupOptions); ValueDecl *localDeclAfterUse = nullptr; - AllDeclRefs = - findNonMembers(Lookup.innerResults(), UDRE->getRefKind(), - /*breakOnMember=*/true, ResultValues, - [&](ValueDecl *D) { - return isValidForwardReference(D, DC, &localDeclAfterUse); - }); + AllDeclRefs = findNonMembers( + Lookup.innerResults(), UDRE->getRefKind(), + /*breakOnMember=*/true, ResultValues, [&](ValueDecl *D) { + return isValidForwardReference(D, DC, localDeclAfterUse); + }); // If local declaration after use is found, check outer results for // better matching candidates. @@ -609,12 +607,11 @@ static Expr *resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE, DeclContext *DC, Lookup.shiftDownResults(); ResultValues.clear(); localDeclAfterUse = nullptr; - AllDeclRefs = - findNonMembers(Lookup.innerResults(), UDRE->getRefKind(), - /*breakOnMember=*/true, ResultValues, - [&](ValueDecl *D) { - return isValidForwardReference(D, DC, &localDeclAfterUse); - }); + AllDeclRefs = findNonMembers( + Lookup.innerResults(), UDRE->getRefKind(), + /*breakOnMember=*/true, ResultValues, [&](ValueDecl *D) { + return isValidForwardReference(D, DC, localDeclAfterUse); + }); } } } diff --git a/test/NameLookup/name_lookup.swift b/test/NameLookup/name_lookup.swift index 0b969aab367a0..4a1cfb3d17fd2 100644 --- a/test/NameLookup/name_lookup.swift +++ b/test/NameLookup/name_lookup.swift @@ -643,8 +643,8 @@ struct PatternBindingWithTwoVars3 { var x = y, y = x } // https://github.com/apple/swift/issues/51518 do { - let closure1 = { closure2() } // expected-error {{circular reference}} expected-note {{through reference here}} - let closure2 = { closure1() } // expected-note {{through reference here}} expected-note {{through reference here}} + let closure1 = { closure2() } // expected-error {{use of local variable 'closure2' before its declaration}} + let closure2 = { closure1() } // expected-note {{'closure2' declared here}} } func color(with value: Int) -> Int { diff --git a/test/NameLookup/use_before_declaration_shadowing.swift b/test/NameLookup/use_before_declaration_shadowing.swift new file mode 100644 index 0000000000000..79bef0ad5521d --- /dev/null +++ b/test/NameLookup/use_before_declaration_shadowing.swift @@ -0,0 +1,94 @@ +// RUN: %target-typecheck-verify-swift +// RUN: %target-typecheck-verify-swift -parse-as-library + +func testLocal() { + // The first `y` here is considered the inner result. + do { + let y = "" + do { + let _: String = y + let y = 0 + _ = y + } + } + do { + let y = "" + do { + _ = { + let _: String = y + } + let y = 0 + _ = y + } + } + do { + let y = "" + _ = { + _ = { + let _: String = y + } + let y = 0 + _ = y + } + } + do { + let y = "" + func bar() { + _ = { + let _: String = y + } + let y = 0 + _ = y + } + } +} + +let topLevelString = "" + +func testTopLevel() { + // Here 'topLevelString' is now an outer result. + do { + let _: String = topLevelString + let topLevelString = 0 + _ = topLevelString + } + do { + _ = { + let _: String = topLevelString + } + let topLevelString = 0 + _ = topLevelString + } + _ = { + _ = { + let _: String = topLevelString + } + let topLevelString = 0 + _ = topLevelString + } + func bar() { + _ = { + let _: String = topLevelString + } + let topLevelString = 0 + _ = topLevelString + } +} + +struct TestLocalPropertyShadowing { + var str: String + + func foo() { + { _ = str }() + let str = str + _ = str + } + func bar() { + let str = { str } + _ = str + } + func baz() { + let str = str + _ = str + } +} diff --git a/test/SILGen/capture_order.swift b/test/SILGen/capture_order.swift index 564224e5dbfd0..50d8e452cdad4 100644 --- a/test/SILGen/capture_order.swift +++ b/test/SILGen/capture_order.swift @@ -109,16 +109,6 @@ func transitiveForwardCapture3() { } } -func captureInClosure() { - let x = { (i: Int) in // expected-error {{closure captures 'currentTotal' before it is declared}} - currentTotal += i // expected-note {{captured here}} - } - - var currentTotal = 0 // expected-note {{captured value declared here}} - - _ = x -} - /// Regression tests // https://github.com/apple/swift/issues/47389 @@ -183,16 +173,6 @@ func f_57097() { // expected-warning@-1 {{variable 'r' was never mutated; consider changing to 'let' constant}} } -class class77933460 {} - -func func77933460() { - var obj: class77933460 = { obj }() - // expected-error@-1 {{closure captures 'obj' before it is declared}} - // expected-note@-2 {{captured here}} - // expected-note@-3 {{captured value declared here}} - // expected-warning@-4 {{variable 'obj' was never mutated; consider changing to 'let' constant}} -} - // MARK: - Forward Declared Lets // https://github.com/swiftlang/swift/issues/84909 @@ -208,110 +188,6 @@ func global_fwd(_ a: () -> Any) -> Any { a() } func global_gen_fwd(_ g: () -> T) -> T { g() } func global_fwd_p(_ p: () -> any P) -> any P { p() } -func forward_declared_let_captures() { - do { - let bad: Any = { bad }() - // expected-error@-1 {{closure captures 'bad' before it is declared}} - // expected-note@-2 {{captured here}} - // expected-note@-3 {{captured value declared here}} - } - - do { - func fwd(_ i: () -> Any) -> Any { i() } - let bad = fwd { bad } - // expected-error@-1 {{closure captures 'bad' before it is declared}} - // expected-note@-2 {{captured here}} - // expected-note@-3 {{captured value declared here}} - } - - do { - let bad = global_fwd { bad } - // expected-error@-1 {{closure captures 'bad' before it is declared}} - // expected-note@-2 {{captured here}} - // expected-note@-3 {{captured value declared here}} - } - - do { - let bad: Any = global_gen_fwd { bad } - // expected-error@-1 {{closure captures 'bad' before it is declared}} - // expected-note@-2 {{captured here}} - // expected-note@-3 {{captured value declared here}} - } - - do { - let bad: Any = E.static_gen_fwd { bad } - // expected-error@-1 {{closure captures 'bad' before it is declared}} - // expected-note@-2 {{captured here}} - // expected-note@-3 {{captured value declared here}} - } - - do { - let badNested: Any = global_fwd { { [badNested] in badNested }() } - // expected-error@-1 {{closure captures 'badNested' before it is declared}} - // expected-note@-2 {{captured here}} - // expected-note@-3 {{captured value declared here}} - } - - do { - let badOpt: Any? = { () -> Any? in badOpt }() - // expected-error@-1 {{closure captures 'badOpt' before it is declared}} - // expected-note@-2 {{captured here}} - // expected-note@-3 {{captured value declared here}} - } - - do { - let badTup: (Any, Any) = { (badTup.0, badTup.1) }() - // expected-error@-1 {{closure captures 'badTup' before it is declared}} - // expected-note@-2 {{captured here}} - // expected-note@-3 {{captured value declared here}} - } - - do { - let badTup: (Int, Any) = { (badTup.0, badTup.1) }() - // expected-error@-1 {{closure captures 'badTup' before it is declared}} - // expected-note@-2 {{captured here}} - // expected-note@-3 {{captured value declared here}} - } - - do { - let (badTup3, badTup4): (Any, Any) = { (badTup4, badTup3) }() - // expected-error@-1 {{closure captures 'badTup4' before it is declared}} - // expected-note@-2 {{captured here}} - // expected-note@-3 {{captured value declared here}} - // expected-error@-4 {{closure captures 'badTup3' before it is declared}} - // expected-note@-5 {{captured here}} - // expected-note@-6 {{captured value declared here}} - } - - do { - struct S { var p: Any } - let badStruct: S = { S(p: badStruct.p) }() - // expected-error@-1 {{closure captures 'badStruct' before it is declared}} - // expected-note@-2 {{captured here}} - // expected-note@-3 {{captured value declared here}} - } - - do { - enum EE { - case boring - case weird(Any) - case strange(Any) - } - - let badEnum: EE = { .weird(EE.strange(badEnum)) }() - // expected-error@-1 {{closure captures 'badEnum' before it is declared}} - // expected-note@-2 {{captured here}} - // expected-note@-3 {{captured value declared here}} - } - - do { - let badproto: any P = global_fwd_p { badproto } - // expected-error@-1 {{closure captures 'badproto' before it is declared}} - // expected-note@-2 {{captured here}} - // expected-note@-3 {{captured value declared here}} - } -} - func forward_declared_let_captures_local_fn() { do { func bad_local_f() -> Any { bad } @@ -441,10 +317,13 @@ func forward_declared_let_captures_local_fn() { } } -func forward_declared_local_lazy_captures() { - // runtime stack overflow - lazy var infiniteRecurse: Any = { infiniteRecurse }() - - // function that returns itself - lazy var hmm: () -> Any = { hmm } -} +// FIXME: Currently they crash SILGen (TypeConverter-setCaptureTypeExpansionContext-e72208.swift) +//func forward_declared_local_lazy_captures() { +// // runtime stack overflow +// var _infiniteRecurse: Any { infiniteRecurse } +// lazy var infiniteRecurse = _infiniteRecurse +// +// // function that returns itself +// func _hmm() -> Any { hmm } +// lazy var hmm = _hmm +//} diff --git a/test/SILOptimizer/closure_lifetime_fixup_undef.swift b/test/SILOptimizer/closure_lifetime_fixup_undef.swift index cf27396999f52..88cd500183762 100644 --- a/test/SILOptimizer/closure_lifetime_fixup_undef.swift +++ b/test/SILOptimizer/closure_lifetime_fixup_undef.swift @@ -1,7 +1,6 @@ -// RUN: not %target-swift-frontend %s -sil-verify-all -c 2>&1 | %FileCheck %s +// RUN: %target-swift-frontend %s -sil-verify-all -c -// Report the error but don't crash. -// CHECK: error: closure captures 'stringList' before it is declared +// Make sure we don't crash. class TestUndefined { private var stringList: [String]! diff --git a/test/SILOptimizer/definite_init_closures_fail.swift b/test/SILOptimizer/definite_init_closures_fail.swift index 64d05e31c6e5d..af616b935ab08 100644 --- a/test/SILOptimizer/definite_init_closures_fail.swift +++ b/test/SILOptimizer/definite_init_closures_fail.swift @@ -65,3 +65,7 @@ struct Generic { } // expected-error {{return from initializer without initializing all stored properties}} } +func captureUninitialized() { + let fn: () -> Void // expected-note {{constant defined here}} + fn = { fn() } // expected-error {{constant 'fn' captured by a closure before being initialized}} +} diff --git a/test/Sema/diag_use_before_declaration.swift b/test/Sema/diag_use_before_declaration.swift index 216490315daf9..d07bc05d5e7f1 100644 --- a/test/Sema/diag_use_before_declaration.swift +++ b/test/Sema/diag_use_before_declaration.swift @@ -80,6 +80,141 @@ func nested_scope_3() { } } +func captureInClosure() { + let x = { (i: Int) in + currentTotal += i // expected-error {{use of local variable 'currentTotal' before its declaration}} + } + + var currentTotal = 0 // expected-note {{'currentTotal' declared here}} + + _ = x +} + +class class77933460 {} + +func func77933460() { + var obj: class77933460 = { obj }() + // expected-error@-1 {{use of local variable 'obj' before its declaration}} + // expected-note@-2 {{'obj' declared here}} +} + +protocol P {} + +enum E { + static func static_gen_fwd(_ g: () -> T) -> T { g() } +} + +func global_fwd(_ a: () -> Any) -> Any { a() } +func global_gen_fwd(_ g: () -> T) -> T { g() } +func global_fwd_p(_ p: () -> any P) -> any P { p() } + +func forward_declared_let_captures() { + do { + let bad: Any = { bad }() + // expected-error@-1 {{use of local variable 'bad' before its declaration}} + // expected-note@-2 {{'bad' declared here}} + } + + do { + func fwd(_ i: () -> Any) -> Any { i() } + let bad = fwd { bad } + // expected-error@-1 {{use of local variable 'bad' before its declaration}} + // expected-note@-2 {{'bad' declared here}} + } + + do { + let bad = global_fwd { bad } + // expected-error@-1 {{use of local variable 'bad' before its declaration}} + // expected-note@-2 {{'bad' declared here}} + } + + do { + let bad: Any = global_gen_fwd { bad } + // expected-error@-1 {{use of local variable 'bad' before its declaration}} + // expected-note@-2 {{'bad' declared here}} + } + + do { + let bad: Any = E.static_gen_fwd { bad } + // expected-error@-1 {{use of local variable 'bad' before its declaration}} + // expected-note@-2 {{'bad' declared here}} + } + + do { + let badNested: Any = global_fwd { { [badNested] in badNested }() } + // expected-error@-1 {{use of local variable 'badNested' before its declaration}} + // expected-note@-2 {{'badNested' declared here}} + } + + do { + let badOpt: Any? = { () -> Any? in badOpt }() + // expected-error@-1 {{use of local variable 'badOpt' before its declaration}} + // expected-note@-2 {{'badOpt' declared here}} + } + + do { + let badTup: (Any, Any) = { (badTup.0, badTup.1) }() + // expected-error@-1 2{{use of local variable 'badTup' before its declaration}} + // expected-note@-2 2{{'badTup' declared here}} + } + + do { + let badTup: (Int, Any) = { (badTup.0, badTup.1) }() + // expected-error@-1 2{{use of local variable 'badTup' before its declaration}} + // expected-note@-2 2{{'badTup' declared here}} + } + + do { + let (badTup3, badTup4): (Any, Any) = { (badTup4, badTup3) }() + // expected-error@-1 {{use of local variable 'badTup3' before its declaration}} + // expected-note@-2 {{'badTup3' declared here}} + // expected-error@-3 {{use of local variable 'badTup4' before its declaration}} + // expected-note@-4 {{'badTup4' declared here}} + } + + do { + struct S { var p: Any } + let badStruct: S = { S(p: badStruct.p) }() + // expected-error@-1 {{use of local variable 'badStruct' before its declaration}} + // expected-note@-2 {{'badStruct' declared here}} + } + + do { + enum EE { + case boring + case weird(Any) + case strange(Any) + } + + let badEnum: EE = { .weird(EE.strange(badEnum)) }() + // expected-error@-1 {{use of local variable 'badEnum' before its declaration}} + // expected-note@-2 {{'badEnum' declared here}} + } + + do { + let badproto: any P = global_fwd_p { badproto } + // expected-error@-1 {{use of local variable 'badproto' before its declaration}} + // expected-note@-2 {{'badproto' declared here}} + } +} + +func forward_declared_local_lazy_captures() { + lazy var infiniteRecurse: Any = { infiniteRecurse }() + // expected-error@-1 {{use of local variable 'infiniteRecurse' before its declaration}} + // expected-note@-2 {{'infiniteRecurse' declared here}} + + lazy var hmm: () -> Any = { hmm } + // expected-error@-1 {{use of local variable 'hmm' before its declaration}} + // expected-note@-2 {{'hmm' declared here}} +} + +func forward_declared_computed_locals() { + // In principle we could allow these, but it's simpler to just reject them. + let x = z // expected-error {{use of local variable 'z' before its declaration}} + let y = { z } // expected-error {{use of local variable 'z' before its declaration}} + var z: Int { 0 } // expected-note 2{{'z' declared here}} +} + //===----------------------------------------------------------------------===// // Type scope //===----------------------------------------------------------------------===// diff --git a/test/expr/closure/closures.swift b/test/expr/closure/closures.swift index b8af7e06c653c..572153f6bd1ab 100644 --- a/test/expr/closure/closures.swift +++ b/test/expr/closure/closures.swift @@ -1852,6 +1852,18 @@ class TestLazyLocal { } } +class TestLocalPropertyShadowing { + var str: String = "" + + func foo() { + let str = { str } + // expected-error@-1 {{reference to property 'str' in closure requires explicit use of 'self' to make capture semantics explicit}} + // expected-note@-2 {{reference 'self.' explicitly}} + // expected-note@-3 {{capture 'self' explicitly to enable implicit 'self' in this closure}} + _ = str + } +} + class TestExtensionOnOptionalSelf { init() {} } diff --git a/test/expr/closure/multi_statement.swift b/test/expr/closure/multi_statement.swift index c37d1ecb3f2f4..1a28a55ab758d 100644 --- a/test/expr/closure/multi_statement.swift +++ b/test/expr/closure/multi_statement.swift @@ -358,7 +358,8 @@ func test_no_crash_with_circular_ref_due_to_error() { // expected-error@-1 {{consecutive statements on a line must be separated by ';'}} // expected-error@-2 {{'let' cannot appear nested inside another 'var' or 'let' pattern}} // expected-error@-3 {{cannot call value of non-function type 'Int?'}} - print(next) + // expected-note@-4 {{'next' declared here}} + print(next) // expected-error {{use of local variable 'next' before its declaration}} return x } return 0 @@ -676,20 +677,26 @@ func test_recursive_var_reference_in_multistatement_closure() { func test(optionalInt: Int?, themes: MyStruct?) { takeClosure { - let int = optionalInt { // expected-error {{cannot call value of non-function type 'Int?'}} - print(int) + let int = optionalInt { + // expected-error@-1 {{cannot call value of non-function type 'Int?'}} + // expected-note@-2 {{'int' declared here}} + print(int) // expected-error {{use of local variable 'int' before its declaration}} } } takeClosure { - let theme = themes?.someMethod() { // expected-error {{extra trailing closure passed in call}} - _ = theme + let theme = themes?.someMethod() { + // expected-error@-1 {{extra trailing closure passed in call}} + // expected-note@-2 {{'theme' declared here}} + _ = theme // expected-error {{use of local variable 'theme' before its declaration}} } } takeClosure { - let theme = themes?.filter({ $0 }) { // expected-error {{value of type 'MyStruct' has no member 'filter'}} - _ = theme + let theme = themes?.filter({ $0 }) { + // expected-error@-1 {{value of type 'MyStruct' has no member 'filter'}} + // expected-note@-2 {{'theme' declared here}} + _ = theme // expected-error {{use of local variable 'theme' before its declaration}} } } } diff --git a/test/expr/expressions.swift b/test/expr/expressions.swift index b4416db19c5bd..3a0710b8f4485 100644 --- a/test/expr/expressions.swift +++ b/test/expr/expressions.swift @@ -244,23 +244,33 @@ func test_as_2() { x as [] // expected-error {{expected element type}} {{9-9= <#type#>}} } -func test_lambda() { +func test_lambda1() { // A simple closure. var a = { (value: Int) -> () in markUsed(value+1) } // expected-warning@-1 {{initialization of variable 'a' was never used; consider replacing with assignment to '_' or removing it}} +} +func test_lambda2() { // A recursive lambda. - var fib = { (n: Int) -> Int in - // expected-warning@-1 {{variable 'fib' was never mutated; consider changing to 'let' constant}} + var fibLocal = { (n: Int) -> Int in // expected-note 2{{'fibLocal' declared here}} if (n < 2) { return n } + return fibLocal(n-1)+fibLocal(n-2) // expected-error 2{{use of local variable 'fibLocal' before its declaration}} + } + + var fib = { (n: Int) -> Int in + if (n < 2) { + return n + } + + // These resolve to the top-level function. return fib(n-1)+fib(n-2) } } -func test_lambda2() { +func test_lambda3() { { () -> protocol in // expected-error @-1 {{'protocol<...>' composition syntax has been removed and is not needed here}} {{11-24=Int}} // expected-error @-2 {{non-protocol, non-class type 'Int' cannot be used within a protocol-constrained type}} diff --git a/test/expr/unary/if_expr.swift b/test/expr/unary/if_expr.swift index f7775d99ff97c..761abb5a9f5df 100644 --- a/test/expr/unary/if_expr.swift +++ b/test/expr/unary/if_expr.swift @@ -1647,3 +1647,14 @@ func testCaptureList() { let _ = { [x = (if .random() { 0 } else { 1 })] in x } // expected-error@-1 {{'if' may only be used as expression in return, throw, or as the source of an assignment}} } + +func testUseBeforeDecl() throws { + let x = if .random() { // expected-note {{'x' declared here}} + print(y) // expected-error {{use of local variable 'y' before its declaration}} + let y = 0 // expected-note {{'y' declared here}} + print(x) // expected-error {{use of local variable 'x' before its declaration}} + throw Err() + } else { + 0 + } +} diff --git a/validation-test/IDE/crashers/ConstraintSystem-getTypeOfReferencePre-1a97a7.swift b/validation-test/IDE/crashers_fixed/ConstraintSystem-getTypeOfReferencePre-1a97a7.swift similarity index 76% rename from validation-test/IDE/crashers/ConstraintSystem-getTypeOfReferencePre-1a97a7.swift rename to validation-test/IDE/crashers_fixed/ConstraintSystem-getTypeOfReferencePre-1a97a7.swift index a8b10f008bb19..94fea2ca1eb63 100644 --- a/validation-test/IDE/crashers/ConstraintSystem-getTypeOfReferencePre-1a97a7.swift +++ b/validation-test/IDE/crashers_fixed/ConstraintSystem-getTypeOfReferencePre-1a97a7.swift @@ -1,5 +1,5 @@ // {"kind":"complete","original":"2d0bf5d7","signature":"swift::constraints::ConstraintSystem::getTypeOfReferencePre(swift::constraints::OverloadChoice, swift::DeclContext*, swift::constraints::ConstraintLocatorBuilder, swift::constraints::PreparedOverloadBuilder*)","signatureAssert":"Assertion failed: (!valueType->hasUnboundGenericType() && !valueType->hasTypeParameter()), function getTypeOfReferencePre"} -// RUN: not --crash %target-swift-ide-test -code-completion -batch-code-completion -skip-filecheck -code-completion-diagnostics -source-filename %s +// RUN: %target-swift-ide-test -code-completion -batch-code-completion -skip-filecheck -code-completion-diagnostics -source-filename %s { (a: Dictionary) in #^^# let b = a { diff --git a/validation-test/Sema/type_checker_crashers_fixed/rdar100753270.swift b/validation-test/Sema/type_checker_crashers_fixed/rdar100753270.swift index bdac4d0d580bc..56282f4859dad 100644 --- a/validation-test/Sema/type_checker_crashers_fixed/rdar100753270.swift +++ b/validation-test/Sema/type_checker_crashers_fixed/rdar100753270.swift @@ -20,7 +20,7 @@ struct Test { // expected-note {{to match this opening '{'}} var infos = [Info]() for (index, info) in infos.enumerated() { - let dataPerHost = Dictionary(grouping: info.data) { data in + let dataPerHost = Dictionary(grouping: info.data) { data in // expected-note {{'dataPerHost' declared here}} let location = data.location() guard let host = location.host else { return 0 @@ -30,7 +30,7 @@ struct Test { // expected-note {{to match this opening '{'}} // Missing paren! } - for _ in dataPerHost { // `dataPerHost` is inside of the closure! + for _ in dataPerHost { // expected-error {{use of local variable 'dataPerHost' before its declaration}} } } } diff --git a/validation-test/Sema/type_checker_crashers_fixed/rdar141012049.swift b/validation-test/Sema/type_checker_crashers_fixed/rdar141012049.swift index cd132c2afa4cb..60b28806acd79 100644 --- a/validation-test/Sema/type_checker_crashers_fixed/rdar141012049.swift +++ b/validation-test/Sema/type_checker_crashers_fixed/rdar141012049.swift @@ -1,12 +1,12 @@ // RUN: %target-typecheck-verify-swift -verify-ignore-unrelated func test(_ v: [Int]) { - let result = v.filter { }.flatMap(\.wrong) { + let result = v.filter { }.flatMap(\.wrong) { // expected-note {{'result' declared here}} // expected-error@-1 {{type for closure argument list expects 1 argument, which cannot be implicitly ignored}} // expected-error@-2 {{cannot convert value of type '()' to closure result type 'Bool'}} // expected-error@-3 {{value of type 'Int' has no member 'wrong'}} // expected-error@-4 {{extra trailing closure passed in call}} - print(result) + print(result) // expected-error {{use of local variable 'result' before its declaration}} } let otherResult = v.filter { _ in false }.flatMap(\.wrong, { $0 }, 42) diff --git a/validation-test/compiler_crashers/KeyPathExpr-getKeyPathType-c80788.swift b/validation-test/compiler_crashers_fixed/KeyPathExpr-getKeyPathType-c80788.swift similarity index 81% rename from validation-test/compiler_crashers/KeyPathExpr-getKeyPathType-c80788.swift rename to validation-test/compiler_crashers_fixed/KeyPathExpr-getKeyPathType-c80788.swift index 90c97a3ff0cba..0565a77fa631b 100644 --- a/validation-test/compiler_crashers/KeyPathExpr-getKeyPathType-c80788.swift +++ b/validation-test/compiler_crashers_fixed/KeyPathExpr-getKeyPathType-c80788.swift @@ -1,3 +1,3 @@ // {"kind":"typecheck","original":"6bb0b020","signature":"swift::KeyPathExpr::getKeyPathType() const","signatureAssert":"Assertion failed: (isa(Val) && \"cast() argument of incompatible type!\"), function cast"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s { let a = \ .b { c} (let c = a diff --git a/validation-test/compiler_crashers_fixed/TypeChecker-typeCheckStmtConditionElement-08b850.swift b/validation-test/compiler_crashers_fixed/TypeChecker-typeCheckStmtConditionElement-08b850.swift new file mode 100644 index 0000000000000..e8a6229bdf79a --- /dev/null +++ b/validation-test/compiler_crashers_fixed/TypeChecker-typeCheckStmtConditionElement-08b850.swift @@ -0,0 +1,11 @@ +// {"kind":"typecheck","signature":"swift::TypeChecker::typeCheckStmtConditionElement(swift::StmtConditionElement&, bool&, swift::DeclContext*)","signatureAssert":"Assertion failed: (!elt.getPattern()->hasType() && \"the pattern binding condition is already type checked\"), function typeCheckPatternBindingStmtConditionElement"} +// RUN: not %target-swift-frontend -typecheck %s +struct a { + func b() {} +} +func foo() { + _ = { c } + var d: a? + guard let d else {} + let c = d.b() +} diff --git a/validation-test/compiler_crashers/Verifier-dispatchVisitPreExpr-9ebf7c.swift b/validation-test/compiler_crashers_fixed/Verifier-dispatchVisitPreExpr-9ebf7c.swift similarity index 89% rename from validation-test/compiler_crashers/Verifier-dispatchVisitPreExpr-9ebf7c.swift rename to validation-test/compiler_crashers_fixed/Verifier-dispatchVisitPreExpr-9ebf7c.swift index c397b5c884d9d..3b9104f879181 100644 --- a/validation-test/compiler_crashers/Verifier-dispatchVisitPreExpr-9ebf7c.swift +++ b/validation-test/compiler_crashers_fixed/Verifier-dispatchVisitPreExpr-9ebf7c.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","original":"5b785ef0","signature":"swift::ASTWalker::PreWalkResult (anonymous namespace)::Verifier::dispatchVisitPreExpr(swift::OpenExistentialExpr*)","signatureAssert":"Assertion failed: (isa(Val) && \"cast() argument of incompatible type!\"), function cast"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s extension Dictionary { a(b: Sequence) {