Skip to content

Commit 4b7b954

Browse files
authored
Merge pull request #72628 from xedin/opaque-return-diag-improvements-6.0
[6.0][CSDiagnostics] Add a few tailored diagnostics for opaque return type requirements mismatches
2 parents 2de86dc + 7f1b34c commit 4b7b954

File tree

4 files changed

+57
-3
lines changed

4 files changed

+57
-3
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2687,6 +2687,12 @@ ERROR(type_does_not_conform_anyobject_decl_owner,none,
26872687
ERROR(type_does_not_conform_in_opaque_return,none,
26882688
"return type of %kind0 requires that %1 %select{conform to %2|be a class type}3",
26892689
(const ValueDecl *, Type, Type, bool))
2690+
ERROR(type_is_not_equal_in_opaque_return,none,
2691+
"return type of %kind0 requires the types %1 and %2 be equivalent",
2692+
(const ValueDecl *, Type, Type))
2693+
ERROR(types_not_inherited_in_opaque_return,none,
2694+
"return type of %kind0 requires that %1 inherit from %2",
2695+
(const ValueDecl *, Type, Type))
26902696
ERROR(types_not_equal_decl,none,
26912697
"%kind0 requires the types %1 and %2 be equivalent",
26922698
(const ValueDecl *, Type, Type))

lib/Sema/CSDiagnostics.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,8 +455,28 @@ bool RequirementFailure::diagnoseAsError() {
455455

456456
if (auto *OTD = dyn_cast<OpaqueTypeDecl>(AffectedDecl)) {
457457
auto *namingDecl = OTD->getNamingDecl();
458-
emitDiagnostic(diag::type_does_not_conform_in_opaque_return,
459-
namingDecl, lhs, rhs, rhs->isAnyObject());
458+
459+
auto &req = getRequirement();
460+
switch (req.getKind()) {
461+
case RequirementKind::Conformance:
462+
case RequirementKind::Layout:
463+
emitDiagnostic(diag::type_does_not_conform_in_opaque_return, namingDecl,
464+
lhs, rhs, rhs->isAnyObject());
465+
break;
466+
467+
case RequirementKind::Superclass:
468+
emitDiagnostic(diag::types_not_inherited_in_opaque_return, namingDecl,
469+
lhs, rhs);
470+
break;
471+
472+
case RequirementKind::SameType:
473+
emitDiagnostic(diag::type_is_not_equal_in_opaque_return, namingDecl, lhs,
474+
rhs);
475+
break;
476+
477+
case RequirementKind::SameShape:
478+
return false;
479+
}
460480

461481
if (auto *repr = namingDecl->getOpaqueResultTypeRepr()) {
462482
emitDiagnosticAt(repr->getLoc(), diag::opaque_return_type_declared_here)

test/type/opaque.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,3 +590,31 @@ func f62787_1(x: Bool) -> Optional<some Collection<Int>> {
590590
}
591591
return nil // expected-error{{underlying type for opaque result type 'Optional<some Collection<Int>>' could not be inferred from return expression}}
592592
}
593+
594+
// rdar://124482122 - Make sure that constraints are respected by opaque types
595+
protocol P3<A> {
596+
associatedtype A: P1
597+
}
598+
599+
do {
600+
struct G<A: P1>: P3 {}
601+
602+
struct S: P1 {}
603+
604+
class A {}
605+
606+
func test1() -> some P3<Int> { // expected-note {{opaque return type declared here}}
607+
return G<S>()
608+
// expected-error@-1 {{return type of local function 'test1()' requires the types 'S' and 'Int' be equivalent}}
609+
}
610+
611+
func test2() -> some P3<G<S>> { // expected-note {{opaque return type declared here}}
612+
return G<S>()
613+
// expected-error@-1 {{return type of local function 'test2()' requires the types 'S' and 'G<S>' be equivalent}}
614+
}
615+
616+
func test3() -> some P1 & A { // expected-note {{opaque return type declared here}}
617+
S()
618+
// expected-error@-1 {{return type of local function 'test3()' requires that 'S' inherit from 'A'}}
619+
}
620+
}

test/type/parameterized_protocol.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ struct OpaqueTypes<E> {
158158
func returnSequenceOfIntBad() -> some Sequence<Int> {
159159
// expected-note@-1 {{opaque return type declared here}}
160160
return ConcreteSequence<E>()
161-
// expected-error@-1 {{return type of instance method 'returnSequenceOfIntBad()' requires that 'E' conform to 'Int'}}
161+
// expected-error@-1 {{return type of instance method 'returnSequenceOfIntBad()' requires the types 'E' and 'Int' be equivalent}}
162162
}
163163

164164
// Invalid

0 commit comments

Comments
 (0)