From 80e98ca9129c4fb59af96d7baf0f2f55202fe086 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Fri, 13 Oct 2023 10:39:38 -0700 Subject: [PATCH 1/4] [ConstraintSystem] Add a missing case to locator simplification If tuple element is anchored on an assignment, we need to look at the source of the assignment to find tuple expression the element belongs to. (cherry picked from commit 557c6f71f2fc971b8f7031e459a3cefed52c9d6f) --- lib/Sema/ConstraintSystem.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index d487e05762753..da279cf4600f2 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -5705,6 +5705,13 @@ void constraints::simplifyLocator(ASTNode &anchor, // Extract tuple element. auto elt = path[0].castTo(); unsigned index = elt.getIndex(); + + if (auto *AE = getAsExpr(anchor)) { + if (isa(AE->getSrc())) { + anchor = AE->getSrc(); + } + } + if (auto tupleExpr = getAsExpr(anchor)) { if (index < tupleExpr->getNumElements()) { anchor = tupleExpr->getElement(index); @@ -5720,6 +5727,7 @@ void constraints::simplifyLocator(ASTNode &anchor, continue; } } + break; } From 92dbcb1715d64b8921cef89d455040299b42f0b2 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Fri, 13 Oct 2023 10:45:50 -0700 Subject: [PATCH 2/4] [CSDiagnostics] Use simplified locator to find owner type of a requirement failure Only simplified locator points to the right underlying expression. Resolves: rdar://116122902 (cherry picked from commit b3da15e324cda0b26b1d483e3e6922c3cab3edea) --- lib/Sema/CSDiagnostics.cpp | 3 +-- test/Generics/conditional_conformances.swift | 2 +- .../conditional_conformances_literals.swift | 14 +++++++------- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index 0142d66708484..64571e3c6c0f5 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -216,8 +216,7 @@ bool FailureDiagnostic::conformsToKnownProtocol( } Type RequirementFailure::getOwnerType() const { - auto anchor = getRawAnchor(); - + auto anchor = getAnchor(); // If diagnostic is anchored at assignment expression // it means that requirement failure happened while trying // to convert source to destination, which means that diff --git a/test/Generics/conditional_conformances.swift b/test/Generics/conditional_conformances.swift index cbcd9e07397cd..26bf8ba736bb3 100644 --- a/test/Generics/conditional_conformances.swift +++ b/test/Generics/conditional_conformances.swift @@ -353,7 +353,7 @@ func existential_good(_: T.Type) { } func existential_bad(_: T.Type) { - _ = Free() as P2 // expected-error{{protocol 'P2' requires that 'T' conform to 'P1'}} + _ = Free() as P2 // expected-error{{generic struct 'Free' requires that 'T' conform to 'P1'}} } // rdar://problem/35837054 diff --git a/test/Generics/conditional_conformances_literals.swift b/test/Generics/conditional_conformances_literals.swift index 94eaac72d75e4..34ff204beadd3 100644 --- a/test/Generics/conditional_conformances_literals.swift +++ b/test/Generics/conditional_conformances_literals.swift @@ -45,7 +45,7 @@ func arraySameType() { let _: SameType = arrayWorks as SameType let _: SameType = arrayFails as SameType - // expected-error@-1 {{protocol 'SameType' requires the types 'Fails' and 'Works' be equivalent}} + // expected-error@-1 {{generic struct 'Array' requires the types 'Fails' and 'Works' be equivalent}} } func dictionarySameType() { @@ -70,7 +70,7 @@ func dictionarySameType() { let _: SameType = dictWorks as SameType let _: SameType = dictFails as SameType - // expected-error@-1 {{protocol 'SameType' requires the types 'Fails' and 'Works' be equivalent}} + // expected-error@-1 {{generic struct 'Dictionary' requires the types 'Fails' and 'Works' be equivalent}} } func arrayConforms() { @@ -91,11 +91,11 @@ func arrayConforms() { let _: Conforms = [works] as Conforms let _: Conforms = [fails] as Conforms - // expected-error@-1 {{protocol 'Conforms' requires that 'Fails' conform to 'Conforms'}} + // expected-error@-1 {{generic struct 'Array' requires that 'Fails' conform to 'Conforms'}} let _: Conforms = arrayWorks as Conforms let _: Conforms = arrayFails as Conforms - // expected-error@-1 {{protocol 'Conforms' requires that 'Fails' conform to 'Conforms'}} + // expected-error@-1 {{generic struct 'Array' requires that 'Fails' conform to 'Conforms'}} } func dictionaryConforms() { @@ -116,11 +116,11 @@ func dictionaryConforms() { let _: Conforms = [0 : works] as Conforms let _: Conforms = [0 : fails] as Conforms - // expected-error@-1 {{protocol 'Conforms' requires that 'Fails' conform to 'Conforms'}} + // expected-error@-1 {{generic struct 'Dictionary' requires that 'Fails' conform to 'Conforms'}} let _: Conforms = dictWorks as Conforms let _: Conforms = dictFails as Conforms - // expected-error@-1 {{protocol 'Conforms' requires that 'Fails' conform to 'Conforms'}} + // expected-error@-1 {{generic struct 'Dictionary' requires that 'Fails' conform to 'Conforms'}} } func combined() { @@ -133,6 +133,6 @@ func combined() { // expected-error@-1 {{type 'any Conforms' cannot conform to 'Conforms'}} expected-note@-1 {{only concrete types such as structs, enums and classes can conform to protocols}} let _: Conforms = [[0: [1 : [fails]] as Conforms]] - // expected-error@-1 {{protocol 'Conforms' requires that 'Fails' conform to 'Conforms'}} + // expected-error@-1 {{generic struct 'Dictionary' requires that 'Fails' conform to 'Conforms'}} // expected-error@-2 {{type 'any Conforms' cannot conform to 'Conforms'}} expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}} } From 7e09101d4ce0d05d38227bead18afd06b9edd942 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Fri, 13 Oct 2023 10:50:15 -0700 Subject: [PATCH 3/4] [Tests] NFC: Add a test-case for rdar://116122902 (cherry picked from commit a90bd1cbe1f9038754723e41a82982bd6c23a17e) --- .../rdar116122902.swift | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 validation-test/Sema/type_checker_crashers_fixed/rdar116122902.swift diff --git a/validation-test/Sema/type_checker_crashers_fixed/rdar116122902.swift b/validation-test/Sema/type_checker_crashers_fixed/rdar116122902.swift new file mode 100644 index 0000000000000..3214c9390f216 --- /dev/null +++ b/validation-test/Sema/type_checker_crashers_fixed/rdar116122902.swift @@ -0,0 +1,23 @@ +// RUN: %target-typecheck-verify-swift + +protocol AnyValue { +} + +struct Value {} + +extension Value: AnyValue where T = { // expected-error {{use '==' for same-type requirements rather than '='}} expected-error {{expected type}} +// expected-note@-1 {{requirement from conditional conformance of 'Value' to 'AnyValue'}} +} + +struct Test { + var tuple: (value: any AnyValue, id: Int)? + + mutating func test(v: Value) { + _ = { + self.tuple = (v, 42) + // expected-error@-1 {{cannot assign value of type '(Value, Int)' to type '(value: any AnyValue, id: Int)'}} + // expected-error@-2 {{generic struct 'Value' requires the types 'T' and '<>' be equivalent}} + return 0 + } + } +} From 3cdb2a14063e8ce2858a43afeef7f03173ad409b Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Mon, 16 Oct 2023 12:37:54 -0700 Subject: [PATCH 4/4] [Tests] NFC: Add a FIXME about use of <> in a diagnostic (cherry picked from commit 4c38d7223019c693f4766bdb4f81fba0d09ebb11) --- .../Sema/type_checker_crashers_fixed/rdar116122902.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/validation-test/Sema/type_checker_crashers_fixed/rdar116122902.swift b/validation-test/Sema/type_checker_crashers_fixed/rdar116122902.swift index 3214c9390f216..2cb5a56010870 100644 --- a/validation-test/Sema/type_checker_crashers_fixed/rdar116122902.swift +++ b/validation-test/Sema/type_checker_crashers_fixed/rdar116122902.swift @@ -14,6 +14,7 @@ struct Test { mutating func test(v: Value) { _ = { + // FIXME(diagnostics): We need to figure out how to avoid mentioning <> in the second diagnostic self.tuple = (v, 42) // expected-error@-1 {{cannot assign value of type '(Value, Int)' to type '(value: any AnyValue, id: Int)'}} // expected-error@-2 {{generic struct 'Value' requires the types 'T' and '<>' be equivalent}}