Skip to content

Commit ae2c6a1

Browse files
committed
[Sema] Resolve ident type to opaque result type
This is just more work to get type resolution to understand how to derive an opaque type from an IdentTypeRepr during OpaqueResultTypeRequest
1 parent b12ecdb commit ae2c6a1

File tree

5 files changed

+39
-16
lines changed

5 files changed

+39
-16
lines changed

include/swift/AST/Decl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -2904,7 +2904,7 @@ class OpaqueTypeDecl final :
29042904
/// repr `repr`, as introduce implicitly by an occurrence of "some" in return
29052905
/// position e.g. `func f() -> some P`. Returns -1 if `repr` is not found.
29062906
Optional<unsigned> getAnonymousOpaqueParamOrdinal(
2907-
OpaqueReturnTypeRepr *repr) const;
2907+
TypeRepr *repr) const;
29082908

29092909
GenericSignature getOpaqueInterfaceGenericSignature() const {
29102910
return OpaqueInterfaceGenericSignature;

lib/AST/Decl.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -3053,8 +3053,13 @@ TypeRepr *ValueDecl::getOpaqueResultTypeRepr() const {
30533053
returnRepr = SD->getElementTypeRepr();
30543054
}
30553055

3056+
auto *dc = getDeclContext();
3057+
auto &ctx = dc->getASTContext();
3058+
30563059
if (returnRepr && returnRepr->hasOpaque()) {
30573060
return returnRepr;
3061+
} else if (returnRepr && ctx.LangOpts.hasFeature(Feature::ImplicitSome) && returnRepr->isProtocol(dc)) {
3062+
return returnRepr;
30583063
} else {
30593064
return nullptr;
30603065
}
@@ -8315,7 +8320,7 @@ GenericTypeParamDecl *OpaqueTypeDecl::getExplicitGenericParam(
83158320
}
83168321

83178322
Optional<unsigned> OpaqueTypeDecl::getAnonymousOpaqueParamOrdinal(
8318-
OpaqueReturnTypeRepr *repr) const {
8323+
TypeRepr *repr) const {
83198324
assert(NamingDeclAndHasOpaqueReturnTypeRepr.getInt() &&
83208325
"can't do opaque param lookup without underlying interface repr");
83218326
auto opaqueReprs = getOpaqueReturnTypeReprs();

lib/AST/NameLookup.cpp

+6-10
Original file line numberDiff line numberDiff line change
@@ -2765,16 +2765,11 @@ static bool declsAreAssociatedTypes(ArrayRef<TypeDecl *> decls) {
27652765
return true;
27662766
}
27672767

2768-
/// Verify there are only protocols in the set of declarations.
2768+
/// Verify there is at least one protocols in the set of declarations.
27692769
static bool declsAreProtocols(ArrayRef<TypeDecl *> decls) {
27702770
if (decls.empty())
27712771
return false;
2772-
2773-
for (auto decl : decls) {
2774-
if (!isa<ProtocolDecl>(decl))
2775-
return false;
2776-
}
2777-
return true;
2772+
return llvm::any_of(decls, [&](const TypeDecl *decl) { return isa<ProtocolDecl>(decl); });;;
27782773
}
27792774

27802775
bool TypeRepr::isProtocol(DeclContext *dc){
@@ -2816,16 +2811,17 @@ CollectedOpaqueReprs swift::collectOpaqueReturnTypeReprs(TypeRepr *r, ASTContext
28162811
return false;
28172812
}
28182813

2819-
if (auto opaqueRepr = dyn_cast<OpaqueReturnTypeRepr>(repr)){
2814+
if (auto opaqueRepr = dyn_cast<OpaqueReturnTypeRepr>(repr)) {
28202815
Reprs.push_back(opaqueRepr);
28212816
if (Ctx.LangOpts.hasFeature(Feature::ImplicitSome))
28222817
return false;
28232818
}
28242819

2825-
if (Ctx.LangOpts.hasFeature(Feature::ImplicitSome)){
2826-
if (auto compositionRepr = dyn_cast<CompositionTypeRepr>(repr)){
2820+
if (Ctx.LangOpts.hasFeature(Feature::ImplicitSome)) {
2821+
if (auto compositionRepr = dyn_cast<CompositionTypeRepr>(repr)) {
28272822
if (!compositionRepr->isTypeReprAny())
28282823
Reprs.push_back(compositionRepr);
2824+
return false;
28292825
} else if (auto identRepr = dyn_cast<IdentTypeRepr>(repr)) {
28302826
if (identRepr->isProtocol(dc))
28312827
Reprs.push_back(identRepr);

lib/Sema/TypeCheckGeneric.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator,
167167
genericParamTypes.push_back(paramType);
168168

169169
TypeRepr *constraint = currentRepr;
170-
//auto constraint = currentRepr;
170+
//auto *constraint = currentRepr;
171171

172172
if (auto opaqueReturn = dyn_cast<OpaqueReturnTypeRepr>(currentRepr)){
173173
constraint = opaqueReturn->getConstraint();

lib/Sema/TypeCheckType.cpp

+25-3
Original file line numberDiff line numberDiff line change
@@ -2243,8 +2243,30 @@ NeverNullType TypeResolver::resolveType(TypeRepr *repr,
22432243
options);
22442244
case TypeReprKind::SimpleIdent:
22452245
case TypeReprKind::GenericIdent:
2246-
case TypeReprKind::CompoundIdent:
2247-
return resolveIdentifierType(cast<IdentTypeRepr>(repr), options);
2246+
case TypeReprKind::CompoundIdent: {
2247+
auto *DC = getDeclContext();
2248+
auto diagnoseDisallowedExistential = [&](Type ty) {
2249+
if (!(options & TypeResolutionFlags::SilenceErrors) &&
2250+
options.contains(TypeResolutionFlags::DisallowOpaqueTypes)) {
2251+
// We're specifically looking at an existential type `any P<some Q>`,
2252+
// so emit a tailored diagnostic. We don't emit an ErrorType here
2253+
// for better recovery.
2254+
diagnose(repr->getLoc(),
2255+
diag::unsupported_opaque_type_in_existential);
2256+
// FIXME: We shouldn't have to invalid the type repr here, but not
2257+
// doing so causes a double-diagnostic.
2258+
repr->setInvalid();
2259+
}
2260+
return ty;
2261+
};
2262+
2263+
if (auto opaqueDecl = dyn_cast<OpaqueTypeDecl>(DC)) {
2264+
if (auto ordinal = opaqueDecl->getAnonymousOpaqueParamOrdinal(repr))
2265+
return diagnoseDisallowedExistential(getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal));
2266+
} else {
2267+
return resolveIdentifierType(cast<IdentTypeRepr>(repr), options);
2268+
}
2269+
}
22482270

22492271
case TypeReprKind::Function: {
22502272
if (!(options & TypeResolutionFlags::SILType)) {
@@ -3825,7 +3847,7 @@ TypeResolver::resolveIdentifierType(IdentTypeRepr *IdType,
38253847
auto *dc = getDeclContext();
38263848
auto &ctx = getASTContext();
38273849

3828-
if ( ctx.LangOpts.hasFeature(Feature::ImplicitSome) & !options.is(TypeResolverContext::Inherited) ){
3850+
if (ctx.LangOpts.hasFeature(Feature::ImplicitSome) && options.isConstraintImplicitExistential()) {
38293851
// Check whether any of the generic parameters in the context represents
38303852
// this opaque type. If so, return that generic parameter.
38313853
if (auto declDC = dc->getAsDecl()) {

0 commit comments

Comments
 (0)