Skip to content

Commit f441e27

Browse files
Merge pull request #62924 from LucianoPAlmeida/opaque-diags
[Diagnostics] Improving diagnostics for inference of opaque result concrete type
2 parents f2302b9 + c6ea1f6 commit f441e27

File tree

5 files changed

+48
-11
lines changed

5 files changed

+48
-11
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3886,6 +3886,9 @@ ERROR(unresolved_member_no_inference,none,
38863886
(DeclNameRef))
38873887
ERROR(cannot_infer_base_of_unresolved_member,none,
38883888
"cannot infer contextual base in reference to member %0", (DeclNameRef))
3889+
ERROR(cannot_infer_concrete_for_opaque_result,none,
3890+
"cannot infer concrete type for opaque result %0 from return expression",
3891+
(Type))
38893892
ERROR(unresolved_nil_literal,none,
38903893
"'nil' requires a contextual type", ())
38913894
ERROR(cannot_force_unwrap_nil_literal,none,

lib/Sema/CSDiagnostics.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5963,6 +5963,16 @@ bool MissingGenericArgumentsFailure::hasLoc(GenericTypeParamType *GP) const {
59635963
}
59645964

59655965
bool MissingGenericArgumentsFailure::diagnoseAsError() {
5966+
auto locator = getLocator();
5967+
// Opaque result types that could not be inferred from return expressions.
5968+
if (auto opaqueElt =
5969+
locator->findLast<LocatorPathElt::OpenedOpaqueArchetype>()) {
5970+
auto *opaqueDecl = opaqueElt->getDecl();
5971+
emitDiagnostic(diag::cannot_infer_concrete_for_opaque_result,
5972+
opaqueDecl->getDeclaredInterfaceType());
5973+
return true;
5974+
}
5975+
59665976
llvm::SmallDenseMap<TypeRepr *, SmallVector<GenericTypeParamType *, 4>>
59675977
scopedParameters;
59685978

test/type/opaque.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,3 +578,15 @@ do {
578578
x
579579
}
580580
}
581+
582+
// https://github.com/apple/swift/issues/62787
583+
func f62787() -> Optional<some Collection<Int>> {
584+
return nil // expected-error{{cannot infer concrete type for opaque result 'Optional<some Collection<Int>>' from return expression}}
585+
}
586+
587+
func f62787_1(x: Bool) -> Optional<some Collection<Int>> {
588+
if x {
589+
return nil // expected-error{{cannot infer concrete type for opaque result 'Optional<some Collection<Int>>' from return expression}}
590+
}
591+
return nil // expected-error{{cannot infer concrete type for opaque result 'Optional<some Collection<Int>>' from return expression}}
592+
}

test/type/opaque_parameterized_existential.swift

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,34 @@ protocol P<T> {
1212
extension Never: P { typealias T = Never }
1313

1414
// I do not like them written clear
15-
func test() -> any P<some P> { fatalError() } // expected-error {{'some' types cannot be used in constraints on existential types}} expected-error {{generic parameter}}
15+
func test() -> any P<some P> { fatalError() } // expected-error {{'some' types cannot be used in constraints on existential types}}
16+
// expected-error@-1{{cannot infer concrete type for opaque result 'any P<some P>' from return expression}}
17+
1618
// I do not like them nested here
17-
func test() -> any P<[some P]> { fatalError() } // expected-error {{'some' types cannot be used in constraints on existential types}} expected-error {{generic parameter}}
19+
func test() -> any P<[some P]> { fatalError() } // expected-error {{'some' types cannot be used in constraints on existential types}}
20+
// expected-error@-1{{cannot infer concrete type for opaque result 'any P<[some P]>' from return expression}}
21+
1822
// I do not like them under questions
19-
func test() -> any P<(some P)??> { fatalError() } // expected-error {{'some' types cannot be used in constraints on existential types}} expected-error {{generic parameter}}
23+
func test() -> any P<(some P)??> { fatalError() } // expected-error {{'some' types cannot be used in constraints on existential types}}
24+
// expected-error@-1{{cannot infer concrete type for opaque result 'any P<(some P)??>' from return expression}}
25+
2026
// I do not like meta-type intentions
21-
func test() -> (any P<some P>).Type { fatalError() } // expected-error {{'some' types cannot be used in constraints on existential types}} expected-error {{generic parameter}}
27+
func test() -> (any P<some P>).Type { fatalError() } // expected-error {{'some' types cannot be used in constraints on existential types}}
28+
// expected-error@-1{{cannot infer concrete type for opaque result '(any P<some P>).Type' from return expression}}
29+
2230
// I do not like them (meta)static-ly
23-
func test() -> any P<some P>.Type { fatalError() } // expected-error {{'some' types cannot be used in constraints on existential types}} expected-error {{generic parameter}}
31+
func test() -> any P<some P>.Type { fatalError() } // expected-error {{'some' types cannot be used in constraints on existential types}}
32+
// expected-error@-1{{cannot infer concrete type for opaque result 'any P<some P>.Type' from return expression}}
33+
2434
// I do not like them tupled-three
25-
func test() -> (Int, any P<some P>, Int) { fatalError() } // expected-error {{'some' types cannot be used in constraints on existential types}} expected-error {{generic parameter}}
35+
func test() -> (Int, any P<some P>, Int) { fatalError() } // expected-error {{'some' types cannot be used in constraints on existential types}}
36+
// expected-error@-1{{cannot infer concrete type for opaque result '(Int, any P<some P>, Int)' from return expression}}
37+
2638
// I do not like them in generics
2739
struct Wrapper<T> {}
28-
func test() -> any P<Wrapper<some P>> { fatalError() } // expected-error {{'some' types cannot be used in constraints on existential types}} expected-error {{generic parameter}}
40+
func test() -> any P<Wrapper<some P>> { fatalError() } // expected-error {{'some' types cannot be used in constraints on existential types}}
41+
// expected-error@-1{{cannot infer concrete type for opaque result 'any P<Wrapper<some P>>' from return expression}}
42+
2943
// Your attempts to nest them put me in hysterics.
3044
func test(_ x: any P<some P>) {} // expected-error {{'some' types cannot be used in constraints on existential types}}
3145

test/type/opaque_return_named.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@
33
// Tests for experimental extensions to opaque return type support.
44

55
func f0() -> <T> T { return () }
6-
func f1() -> <T, U, V> T { () }
7-
// FIXME better diagnostic: expected-error@-1{{generic parameter 'U' could not be inferred}}
8-
// FIXME better diagnostic: expected-error@-2{{generic parameter 'V' could not be inferred}}
6+
func f1() -> <T, U, V> T { () } // expected-error{{cannot infer concrete type for opaque result 'T' from return expression}}
97
func f2() -> <T: Collection, U: SignedInteger> T { // expected-note{{required by opaque return type of global function 'f2()'}}
108
() // expected-error{{type '()' cannot conform to 'Collection'}}
119
// expected-note@-1{{only concrete types such as structs, enums and classes can conform to protocols}}
12-
// expected-error@-2{{generic parameter 'U' could not be inferred}}
10+
// expected-error@-2{{cannot infer concrete type for opaque result 'T' from return expression}}
1311
}
1412

1513
func f4() async -> <T> T { () }

0 commit comments

Comments
 (0)