Skip to content

Commit b0dd6f8

Browse files
authored
Merge pull request #66769 from hamishknight/out-of-context-5.9
2 parents 4eb81e7 + 1c52b0c commit b0dd6f8

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,21 @@ ValueDecl *RequirementFailure::getDeclRef() const {
313313
return cast<ValueDecl>(getDC()->getParent()->getAsDecl());
314314
}
315315

316-
return getAffectedDeclFromType(contextualTy);
316+
// We check for a contextual type here because we form a
317+
// ContextualType(CTP_Initialization) LocatorPathElt for pattern bindings
318+
// when there is no TypedPattern present. In such a case, there will be
319+
// no recorded contextual type (though the pattern may produce a type that
320+
// could be considered contextual).
321+
if (contextualTy) {
322+
// If the contextual type is e.g a tuple, we may not be able to resolve
323+
// a decl. Fall through to getting the 'owner type' in that case.
324+
if (auto *D = getAffectedDeclFromType(contextualTy))
325+
return D;
326+
} else {
327+
assert((contextualPurpose == CTP_Initialization ||
328+
contextualPurpose == CTP_Unused) &&
329+
"Should have had a contextual type");
330+
}
317331
}
318332

319333
if (getLocator()->isFirstElement<LocatorPathElt::CoercionOperand>())

test/Constraints/patterns.swift

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,3 +658,69 @@ enum LotsOfOptional {
658658
func testLotsOfNil(_ x: LotsOfOptional) {
659659
if case .yup(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) = x {}
660660
}
661+
662+
// https://github.com/apple/swift/issues/66752
663+
// FIXME: We ought to improve the diagnostics here
664+
func issue66752(_ x: Result<String, Error>) {
665+
let _ = {
666+
if case .failure() = x {}
667+
// expected-error@-1 {{type '()' cannot conform to 'Error}}
668+
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
669+
// expected-note@-3 {{required by generic enum 'Result' where 'Failure' = '()'}}
670+
}
671+
let _ = {
672+
if case (.failure(), let y) = (x, 0) {}
673+
// expected-error@-1 {{type '()' cannot conform to 'Error}}
674+
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
675+
// expected-note@-3 {{required by generic enum 'Result' where 'Failure' = '()'}}
676+
}
677+
if case .failure() = x {}
678+
// expected-error@-1 {{type '()' cannot conform to 'Error}}
679+
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
680+
// expected-note@-3 {{required by generic enum 'Result' where 'Failure' = '()'}}
681+
682+
if case (.failure(), let y) = (x, 0) {}
683+
// expected-error@-1 {{type '()' cannot conform to 'Error}}
684+
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
685+
// expected-note@-3 {{required by generic enum 'Result' where 'Failure' = '()'}}
686+
}
687+
688+
// https://github.com/apple/swift/issues/66750
689+
// FIXME: We ought to improve the diagnostics here
690+
func issue66750(_ x: Result<String, Error>) {
691+
let _ = {
692+
switch x {
693+
case .success:
694+
"a"
695+
case .failure():
696+
// expected-error@-1 {{type '()' cannot conform to 'Error}}
697+
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
698+
// expected-note@-3 {{required by generic enum 'Result' where 'Failure' = '()'}}
699+
"b"
700+
}
701+
}
702+
let _ = {
703+
switch (x, 0) {
704+
case (.success, let y):
705+
"a"
706+
case (.failure(), let y):
707+
// expected-error@-1 {{type '()' cannot conform to 'Error}}
708+
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
709+
// expected-note@-3 {{required by generic enum 'Result' where 'Failure' = '()'}}
710+
"b"
711+
}
712+
}
713+
switch x {
714+
case .success:
715+
break
716+
case .failure(): // expected-error {{tuple pattern cannot match values of the non-tuple type 'any Error'}}
717+
break
718+
}
719+
switch (x, 0) {
720+
case (.success, let y):
721+
break
722+
case (.failure(), let y):
723+
// expected-error@-1 {{tuple pattern cannot match values of the non-tuple type 'any Error'}}
724+
break
725+
}
726+
}

0 commit comments

Comments
 (0)