Skip to content

Commit 07f0ad2

Browse files
committed
[Sema] Diagnose DisallowedExistential in type resolution
1 parent a1788f0 commit 07f0ad2

File tree

5 files changed

+41
-53
lines changed

5 files changed

+41
-53
lines changed

lib/AST/NameLookup.cpp

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

lib/Sema/TypeCheckDecl.cpp

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

21392139
// Handle opaque types.
2140-
if (decl->getOpaqueResultTypeRepr()) {
2141-
auto *opaqueDecl = decl->getOpaqueResultTypeDecl();
2142-
return (opaqueDecl
2143-
? opaqueDecl->getDeclaredInterfaceType()
2144-
: ErrorType::get(ctx));
2140+
if (auto *opaqueDecl = decl->getOpaqueResultTypeDecl()) {
2141+
return opaqueDecl->getDeclaredInterfaceType();
21452142
}
21462143

21472144
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: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,8 +1990,9 @@ namespace {
19901990
return diags.diagnose(std::forward<ArgTypes>(Args)...);
19911991
}
19921992

1993-
Type diagnoseDisallowedExistential(TypeRepr *repr, Type type);
19941993
bool diagnoseMoveOnly(TypeRepr *repr, Type genericArgTy);
1994+
1995+
bool diagnoseDisallowedExistential(TypeRepr *repr);
19951996

19961997
NeverNullType resolveOpenedExistentialArchetype(
19971998
TypeAttributes &attrs, TypeRepr *repr,
@@ -2205,7 +2206,7 @@ static Type evaluateTypeResolution(const TypeResolution *resolution,
22052206
return result;
22062207
}
22072208

2208-
Type TypeResolver::diagnoseDisallowedExistential(TypeRepr *repr, Type type) {
2209+
bool TypeResolver::diagnoseDisallowedExistential(TypeRepr *repr) {
22092210
auto options = resolution.getOptions();
22102211
if (!(options & TypeResolutionFlags::SilenceErrors) &&
22112212
options.contains(TypeResolutionFlags::DisallowOpaqueTypes)) {
@@ -2217,9 +2218,10 @@ Type TypeResolver::diagnoseDisallowedExistential(TypeRepr *repr, Type type) {
22172218
// FIXME: We shouldn't have to invalid the type repr here, but not
22182219
// doing so causes a double-diagnostic.
22192220
repr->setInvalid();
2221+
return true;
2222+
} else {
2223+
return false;
22202224
}
2221-
2222-
return type;
22232225
}
22242226

22252227
/// Checks the given type, assuming that it appears as an argument for a
@@ -2336,9 +2338,10 @@ NeverNullType TypeResolver::resolveType(TypeRepr *repr,
23362338
auto *DC = getDeclContext();
23372339
if (getASTContext().LangOpts.hasFeature(Feature::ImplicitSome)) {
23382340
if (auto opaqueDecl = dyn_cast<OpaqueTypeDecl>(DC)) {
2339-
if (auto ordinal = opaqueDecl->getAnonymousOpaqueParamOrdinal(repr))
2340-
return diagnoseDisallowedExistential(repr,
2341-
getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal));
2341+
if (auto ordinal = opaqueDecl->getAnonymousOpaqueParamOrdinal(repr)){
2342+
diagnoseDisallowedExistential(repr);
2343+
return getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal);
2344+
}
23422345
}
23432346
}
23442347

@@ -2358,10 +2361,12 @@ NeverNullType TypeResolver::resolveType(TypeRepr *repr,
23582361
// evaluation of an `OpaqueResultTypeRequest`.
23592362
auto opaqueRepr = cast<OpaqueReturnTypeRepr>(repr);
23602363
auto *DC = getDeclContext();
2364+
2365+
bool isInExistential = diagnoseDisallowedExistential(opaqueRepr);
2366+
23612367
if (auto opaqueDecl = dyn_cast<OpaqueTypeDecl>(DC)) {
23622368
if (auto ordinal = opaqueDecl->getAnonymousOpaqueParamOrdinal(opaqueRepr))
2363-
return diagnoseDisallowedExistential(opaqueRepr,
2364-
getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal));
2369+
return getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal);
23652370
}
23662371

23672372
// Check whether any of the generic parameters in the context represents
@@ -2371,17 +2376,18 @@ NeverNullType TypeResolver::resolveType(TypeRepr *repr,
23712376
if (auto genericParams = genericContext->getGenericParams()) {
23722377
for (auto genericParam : *genericParams) {
23732378
if (genericParam->getOpaqueTypeRepr() == opaqueRepr)
2374-
return diagnoseDisallowedExistential(opaqueRepr,
2375-
genericParam->getDeclaredInterfaceType());
2379+
return genericParam->getDeclaredInterfaceType();
23762380
}
23772381
}
23782382
}
23792383
}
2380-
2381-
// We are not inside an `OpaqueTypeDecl`, so diagnose an error.
2382-
if (!(options & TypeResolutionFlags::SilenceErrors)) {
2383-
diagnose(opaqueRepr->getOpaqueLoc(),
2384-
diag::unsupported_opaque_type);
2384+
2385+
if (!isInExistential){
2386+
// We are not inside an `OpaqueTypeDecl`, so diagnose an error.
2387+
if (!(options & TypeResolutionFlags::SilenceErrors)) {
2388+
diagnose(opaqueRepr->getOpaqueLoc(),
2389+
diag::unsupported_opaque_type);
2390+
}
23852391
}
23862392

23872393
// Try to resolve the constraint upper bound type as a placeholder.
@@ -4074,8 +4080,8 @@ TypeResolver::resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
40744080
// Check whether this type is an implicit opaque result type.
40754081
if (auto *opaqueDecl = dyn_cast<OpaqueTypeDecl>(getDeclContext())) {
40764082
if (auto ordinal = opaqueDecl->getAnonymousOpaqueParamOrdinal(repr)) {
4077-
return diagnoseDisallowedExistential(
4078-
repr, getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal));
4083+
diagnoseDisallowedExistential(repr);
4084+
return getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal);
40794085
}
40804086
}
40814087

test/type/opaque_parameterized_existential.swift

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,39 +9,24 @@ protocol P<T> {
99
associatedtype T
1010
}
1111

12-
extension Never: P { typealias T = Never }
12+
struct S: P {
13+
typealias T = Self
14+
}
1315

1416
// 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}}
16-
// expected-error@-1{{cannot infer underlying type for opaque result 'any P<some P>' from return expression}}
17-
18-
// I do not like them nested here
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 underlying type for opaque result 'any P<[some P]>' from return expression}}
21-
17+
func test() -> any P<some P> { S() } // expected-error {{'some' types cannot be used in constraints on existential types}}
2218
// I do not like them under questions
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 underlying type for opaque result 'any P<(some P)??>' from return expression}}
25-
19+
func test() -> any P<(some P)??> { S() } // expected-error {{'some' types cannot be used in constraints on existential types}}
2620
// I do not like meta-type intentions
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 underlying type for opaque result '(any P<some P>).Type' from return expression}}
29-
21+
func test() -> (any P<some P>).Type { S() } // expected-error {{'some' types cannot be used in constraints on existential types}}
3022
// I do not like them (meta)static-ly
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 underlying type for opaque result 'any P<some P>.Type' from return expression}}
33-
23+
func test() -> any P<some P>.Type { S() } // expected-error {{'some' types cannot be used in constraints on existential types}}
3424
// I do not like them tupled-three
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 underlying type for opaque result '(Int, any P<some P>, Int)' from return expression}}
37-
25+
func test() -> (Int, any P<some P>, Int) { S() } // expected-error {{'some' types cannot be used in constraints on existential types}}
3826
// I do not like them in generics
3927
struct Wrapper<T> {}
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 underlying type for opaque result 'any P<Wrapper<some P>>' from return expression}}
42-
28+
func test() -> any P<Wrapper<some P>> { S() } // expected-error {{'some' types cannot be used in constraints on existential types}}
4329
// Your attempts to nest them put me in hysterics.
44-
func test(_ x: any P<some P>) {} // expected-error {{'some' types cannot be used in constraints on existential types}}
45-
30+
func test(_ x: any P<some P>) { } // expected-error {{'some' types cannot be used in constraints on existential types}}
4631
// No, I do not like nested some type params,
4732
// I do not like them Σam-i-am

0 commit comments

Comments
 (0)