Skip to content

Commit 6db0540

Browse files
committed
Sema: Don't allow properties with inferred types to infer opaque result types.
This prevents opaque result types from propagating nontrivially into other declarations' types, which may be confusing and create implementation complexities.
1 parent e3bbd8c commit 6db0540

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,6 +1501,9 @@ WARNING(function_type_usable_from_inline_warn,none,
15011501
ERROR(opaque_type_invalid_constraint,none,
15021502
"an 'opaque' type must specify only 'Any', 'AnyObject', protocols, "
15031503
"and/or a base class", ())
1504+
ERROR(inferred_opaque_type,none,
1505+
"property definition has inferred type %0, involving the '__opaque' "
1506+
"return type of another declaration", (Type))
15041507

15051508
// Extensions
15061509
ERROR(non_nominal_extension,none,

lib/Sema/TypeCheckDecl.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,15 @@ static void validatePatternBindingEntry(TypeChecker &tc,
979979
if (!pattern->hasType() || pattern->getType()->hasUnboundGenericType()) {
980980
if (tc.typeCheckPatternBinding(binding, entryNumber))
981981
return;
982+
983+
// A pattern binding at top level is not allowed to pick up another decl's
984+
// opaque result type as its type by type inference.
985+
if (!binding->getDeclContext()->isLocalContext()
986+
&& binding->getInit(entryNumber)->getType()->hasOpaqueArchetype()) {
987+
// TODO: Check whether the type is the pattern binding's own opaque type.
988+
tc.diagnose(binding, diag::inferred_opaque_type,
989+
binding->getInit(entryNumber)->getType());
990+
}
982991
}
983992

984993
// If the pattern binding appears in a type or library file context, then

test/type/opaque.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ func zlop() -> __opaque C & AnyObject & P {
5656
return D()
5757
}
5858

59+
// Don't allow opaque types to propagate by inference into other global decls'
60+
// types
61+
struct Test {
62+
let inferredOpaque = bar() // expected-error{{inferred type}}
63+
let inferredOpaqueStructural = Optional(bar()) // expected-error{{inferred type}}
64+
let inferredOpaqueStructural2 = (bar(), bas()) // expected-error{{inferred type}}
65+
}
66+
5967
//let zingle = {() -> __opaque P in 1 } // FIXME ex/pected-error{{'opaque' types are only implemented}}
6068

6169
// Invalid positions

0 commit comments

Comments
 (0)