Skip to content

Commit 286772a

Browse files
committed
[Sema] Diagnose DisallowedExistential in type resolution
1 parent 050e20b commit 286772a

File tree

5 files changed

+30
-35
lines changed

5 files changed

+30
-35
lines changed

lib/AST/NameLookup.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2851,11 +2851,6 @@ CollectedOpaqueReprs swift::collectOpaqueReturnTypeReprs(TypeRepr *r, ASTContext
28512851
if (!compositionRepr->isTypeReprAny())
28522852
Reprs.push_back(compositionRepr);
28532853
return Action::SkipChildren();
2854-
} else if (auto generic = dyn_cast<GenericIdentTypeRepr>(repr)) {
2855-
// prevent any P<some P>
2856-
if (!Reprs.empty() && isa<ExistentialTypeRepr>(Reprs.front())){
2857-
Reprs.clear();
2858-
}
28592854
} else if (auto declRefTR = dyn_cast<DeclRefTypeRepr>(repr)) {
28602855
if (declRefTR->isProtocol(dc))
28612856
Reprs.push_back(declRefTR);

lib/Sema/TypeCheckDecl.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,11 +2132,8 @@ ResultTypeRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
21322132
return TupleType::getEmpty(ctx);
21332133

21342134
// Handle opaque types.
2135-
if (decl->getOpaqueResultTypeRepr()) {
2136-
auto *opaqueDecl = decl->getOpaqueResultTypeDecl();
2137-
return (opaqueDecl
2138-
? opaqueDecl->getDeclaredInterfaceType()
2139-
: ErrorType::get(ctx));
2135+
if (auto *opaqueDecl = decl->getOpaqueResultTypeDecl()) {
2136+
return opaqueDecl->getDeclaredInterfaceType();
21402137
}
21412138

21422139
auto options =

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator,
136136
}
137137
} else {
138138
opaqueReprs = collectOpaqueReturnTypeReprs(repr, ctx, dc);
139+
140+
if (opaqueReprs.empty()) {
141+
return nullptr;
142+
}
143+
139144
SmallVector<GenericTypeParamType *, 2> genericParamTypes;
140145
SmallVector<Requirement, 2> requirements;
141146
for (unsigned i = 0; i < opaqueReprs.size(); ++i) {

lib/Sema/TypeCheckType.cpp

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1968,7 +1968,7 @@ namespace {
19681968
return diags.diagnose(std::forward<ArgTypes>(Args)...);
19691969
}
19701970

1971-
Type diagnoseDisallowedExistential(TypeRepr *repr, Type type);
1971+
bool diagnoseDisallowedExistential(TypeRepr *repr);
19721972

19731973
NeverNullType resolveOpenedExistentialArchetype(
19741974
TypeAttributes &attrs, TypeRepr *repr,
@@ -2136,7 +2136,7 @@ Type ResolveTypeRequest::evaluate(Evaluator &evaluator,
21362136
return result;
21372137
}
21382138

2139-
Type TypeResolver::diagnoseDisallowedExistential(TypeRepr *repr, Type type) {
2139+
bool TypeResolver::diagnoseDisallowedExistential(TypeRepr *repr) {
21402140
auto options = resolution.getOptions();
21412141
if (!(options & TypeResolutionFlags::SilenceErrors) &&
21422142
options.contains(TypeResolutionFlags::DisallowOpaqueTypes)) {
@@ -2148,9 +2148,10 @@ Type TypeResolver::diagnoseDisallowedExistential(TypeRepr *repr, Type type) {
21482148
// FIXME: We shouldn't have to invalid the type repr here, but not
21492149
// doing so causes a double-diagnostic.
21502150
repr->setInvalid();
2151+
return true;
2152+
} else {
2153+
return false;
21512154
}
2152-
2153-
return type;
21542155
}
21552156

21562157
NeverNullType TypeResolver::resolveType(TypeRepr *repr,
@@ -2250,9 +2251,10 @@ NeverNullType TypeResolver::resolveType(TypeRepr *repr,
22502251
auto *DC = getDeclContext();
22512252
if (getASTContext().LangOpts.hasFeature(Feature::ImplicitSome)) {
22522253
if (auto opaqueDecl = dyn_cast<OpaqueTypeDecl>(DC)) {
2253-
if (auto ordinal = opaqueDecl->getAnonymousOpaqueParamOrdinal(repr))
2254-
return diagnoseDisallowedExistential(repr,
2255-
getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal));
2254+
if (auto ordinal = opaqueDecl->getAnonymousOpaqueParamOrdinal(repr)){
2255+
diagnoseDisallowedExistential(repr);
2256+
return getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal);
2257+
}
22562258
}
22572259
}
22582260

@@ -2272,10 +2274,12 @@ NeverNullType TypeResolver::resolveType(TypeRepr *repr,
22722274
// evaluation of an `OpaqueResultTypeRequest`.
22732275
auto opaqueRepr = cast<OpaqueReturnTypeRepr>(repr);
22742276
auto *DC = getDeclContext();
2277+
2278+
bool isInExistential = diagnoseDisallowedExistential(opaqueRepr);
2279+
22752280
if (auto opaqueDecl = dyn_cast<OpaqueTypeDecl>(DC)) {
22762281
if (auto ordinal = opaqueDecl->getAnonymousOpaqueParamOrdinal(opaqueRepr))
2277-
return diagnoseDisallowedExistential(opaqueRepr,
2278-
getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal));
2282+
return getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal);
22792283
}
22802284

22812285
// Check whether any of the generic parameters in the context represents
@@ -2285,17 +2289,18 @@ NeverNullType TypeResolver::resolveType(TypeRepr *repr,
22852289
if (auto genericParams = genericContext->getGenericParams()) {
22862290
for (auto genericParam : *genericParams) {
22872291
if (genericParam->getOpaqueTypeRepr() == opaqueRepr)
2288-
return diagnoseDisallowedExistential(opaqueRepr,
2289-
genericParam->getDeclaredInterfaceType());
2292+
return genericParam->getDeclaredInterfaceType();
22902293
}
22912294
}
22922295
}
22932296
}
2294-
2295-
// We are not inside an `OpaqueTypeDecl`, so diagnose an error.
2296-
if (!(options & TypeResolutionFlags::SilenceErrors)) {
2297-
diagnose(opaqueRepr->getOpaqueLoc(),
2298-
diag::unsupported_opaque_type);
2297+
2298+
if (!isInExistential){
2299+
// We are not inside an `OpaqueTypeDecl`, so diagnose an error.
2300+
if (!(options & TypeResolutionFlags::SilenceErrors)) {
2301+
diagnose(opaqueRepr->getOpaqueLoc(),
2302+
diag::unsupported_opaque_type);
2303+
}
22992304
}
23002305

23012306
// Try to resolve the constraint upper bound type as a placeholder.
@@ -3889,8 +3894,8 @@ TypeResolver::resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
38893894
// Check whether this type is an implicit opaque result type.
38903895
if (auto *opaqueDecl = dyn_cast<OpaqueTypeDecl>(getDeclContext())) {
38913896
if (auto ordinal = opaqueDecl->getAnonymousOpaqueParamOrdinal(repr)) {
3892-
return diagnoseDisallowedExistential(
3893-
repr, getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal));
3897+
diagnoseDisallowedExistential(repr);
3898+
return getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal);
38943899
}
38953900
}
38963901

test/type/opaque_parameterized_existential.swift

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,32 +13,25 @@ extension Never: P { typealias T = Never }
1313

1414
// I do not like them written clear
1515
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}}
1716

1817
// I do not like them nested here
1918
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}}
2119

2220
// I do not like them under questions
2321
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}}
2522

2623
// I do not like meta-type intentions
2724
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}}
2925

3026
// I do not like them (meta)static-ly
3127
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}}
3328

3429
// I do not like them tupled-three
3530
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}}
3731

3832
// I do not like them in generics
3933
struct Wrapper<T> {}
4034
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}}
4235

4336
// Your attempts to nest them put me in hysterics.
4437
func test(_ x: any P<some P>) {} // expected-error {{'some' types cannot be used in constraints on existential types}}

0 commit comments

Comments
 (0)