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/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; } 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}} } 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..2cb5a56010870 --- /dev/null +++ b/validation-test/Sema/type_checker_crashers_fixed/rdar116122902.swift @@ -0,0 +1,24 @@ +// 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) { + _ = { + // 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}} + return 0 + } + } +}