Skip to content

Commit 5427191

Browse files
authored
Merge pull request #63221 from angela-laar/verifier-failure-implicit-some
[NameLookup] Opaque Type Collector should skip existential types
2 parents bbd7946 + cba7389 commit 5427191

9 files changed

+373
-68
lines changed

lib/AST/ASTScopeCreation.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,7 @@ namespace {
928928
}
929929
}
930930

931-
return decl->getGenericParams();
931+
return decl->getParsedGenericParams();
932932
}
933933
}
934934

lib/AST/NameLookup.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2798,7 +2798,6 @@ bool TypeRepr::isProtocol(DeclContext *dc){
27982798
auto &ctx = dc->getASTContext();
27992799
return findIf([&ctx, dc](TypeRepr *ty) {
28002800
return declsAreProtocols(directReferencesForTypeRepr(ctx.evaluator, ctx, ty, dc));
2801-
28022801
});
28032802
}
28042803

@@ -2847,20 +2846,13 @@ CollectedOpaqueReprs swift::collectOpaqueReturnTypeReprs(TypeRepr *r, ASTContext
28472846
return Action::Continue();
28482847

28492848
if (auto existential = dyn_cast<ExistentialTypeRepr>(repr)) {
2850-
auto meta = dyn_cast<MetatypeTypeRepr>(existential->getConstraint());
2851-
auto generic = dyn_cast<GenericIdentTypeRepr>(existential->getConstraint());
2852-
if(generic)
2853-
Reprs.push_back(existential);
2854-
return Action::VisitChildrenIf(meta || generic);
2849+
return Action::SkipChildren();
28552850
} else if (auto compositionRepr = dyn_cast<CompositionTypeRepr>(repr)) {
28562851
if (!compositionRepr->isTypeReprAny())
28572852
Reprs.push_back(compositionRepr);
28582853
return Action::SkipChildren();
28592854
} else if (auto generic = dyn_cast<GenericIdentTypeRepr>(repr)) {
2860-
// prevent any P<some P>
2861-
if (!Reprs.empty() && isa<ExistentialTypeRepr>(Reprs.front())){
2862-
Reprs.clear();
2863-
}
2855+
return Action::Continue();
28642856
} else if (auto declRefTR = dyn_cast<DeclRefTypeRepr>(repr)) {
28652857
if (declRefTR->isProtocol(dc))
28662858
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: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator,
7979
.diagnose(repr->getLoc(), diag::opaque_type_in_protocol_requirement)
8080
.fixItInsert(fixitLoc, result)
8181
.fixItReplace(repr->getSourceRange(), placeholder);
82+
repr->setInvalid();
8283

8384
return nullptr;
8485
}
@@ -136,6 +137,11 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator,
136137
}
137138
} else {
138139
opaqueReprs = collectOpaqueReturnTypeReprs(repr, ctx, dc);
140+
141+
if (opaqueReprs.empty()) {
142+
return nullptr;
143+
}
144+
139145
SmallVector<GenericTypeParamType *, 2> genericParamTypes;
140146
SmallVector<Requirement, 2> requirements;
141147
for (unsigned i = 0; i < opaqueReprs.size(); ++i) {
@@ -157,6 +163,7 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator,
157163
.diagnose(currentRepr->getLoc(), diag::opaque_of_optional_rewrite)
158164
.fixItReplaceChars(currentRepr->getStartLoc(),
159165
currentRepr->getEndLoc(), stream.str());
166+
repr->setInvalid();
160167
return nullptr;
161168
}
162169
}
@@ -194,6 +201,7 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator,
194201
// Error out if the constraint type isn't a class or existential type.
195202
ctx.Diags.diagnose(currentRepr->getLoc(),
196203
diag::opaque_type_invalid_constraint);
204+
currentRepr->setInvalid();
197205
return nullptr;
198206
}
199207

@@ -241,6 +249,7 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator,
241249
ctx.Diags.diagnose(repr->getLoc(),
242250
diag::opaque_type_in_parameter,
243251
false, interfaceType);
252+
repr->setInvalid();
244253
return true;
245254
}
246255
}
@@ -469,8 +478,15 @@ void TypeChecker::checkReferencedGenericParams(GenericContext *dc) {
469478
continue;
470479
}
471480
// Produce an error that this generic parameter cannot be bound.
472-
paramDecl->diagnose(diag::unreferenced_generic_parameter,
473-
paramDecl->getNameStr());
481+
if (paramDecl->isImplicit()) {
482+
paramDecl->getASTContext().Diags
483+
.diagnose(paramDecl->getOpaqueTypeRepr()->getLoc(),
484+
diag::unreferenced_generic_parameter,
485+
paramDecl->getNameStr());
486+
} else {
487+
paramDecl->diagnose(diag::unreferenced_generic_parameter,
488+
paramDecl->getNameStr());
489+
}
474490
}
475491
}
476492
}

lib/Sema/TypeCheckPattern.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ validateTypedPattern(TypedPattern *TP, DeclContext *dc,
732732
auto *Repr = TP->getTypeRepr();
733733
if (Repr && (Repr->hasOpaque() ||
734734
(Context.LangOpts.hasFeature(Feature::ImplicitSome) &&
735-
Repr->isProtocol(dc)))) {
735+
!collectOpaqueReturnTypeReprs(Repr, Context, dc).empty()))) {
736736
auto named = dyn_cast<NamedPattern>(
737737
TP->getSubPattern()->getSemanticsProvidingPattern());
738738
if (!named) {

lib/Sema/TypeCheckType.cpp

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ TypeChecker::getDynamicBridgedThroughObjCClass(DeclContext *dc,
360360
}
361361

362362
/// Retrieve the identity form of the opaque type archetype type.
363-
static Type getIdentityOpaqueTypeArchetypeType(
363+
static Type getOpaqueArchetypeIdentity(
364364
OpaqueTypeDecl *opaqueDecl, unsigned ordinal) {
365365
auto outerGenericSignature = opaqueDecl->getNamingDecl()
366366
->getInnermostDeclContext()
@@ -418,8 +418,7 @@ Type TypeResolution::resolveTypeInContext(TypeDecl *typeDecl,
418418
if (auto opaqueDecl = dyn_cast<OpaqueTypeDecl>(getDeclContext())) {
419419
if (genericParam->getDepth() ==
420420
opaqueDecl->getOpaqueGenericParams().front()->getDepth()) {
421-
return getIdentityOpaqueTypeArchetypeType(
422-
opaqueDecl, genericParam->getIndex());
421+
return getOpaqueArchetypeIdentity(opaqueDecl, genericParam->getIndex());
423422
}
424423
}
425424

@@ -1990,8 +1989,11 @@ namespace {
19901989
return diags.diagnose(std::forward<ArgTypes>(Args)...);
19911990
}
19921991

1993-
Type diagnoseDisallowedExistential(TypeRepr *repr, Type type);
19941992
bool diagnoseMoveOnly(TypeRepr *repr, Type genericArgTy);
1993+
1994+
bool diagnoseDisallowedExistential(TypeRepr *repr);
1995+
1996+
bool diagnoseInvalidPlaceHolder(OpaqueReturnTypeRepr *repr);
19951997

19961998
NeverNullType resolveOpenedExistentialArchetype(
19971999
TypeAttributes &attrs, TypeRepr *repr,
@@ -2205,7 +2207,7 @@ static Type evaluateTypeResolution(const TypeResolution *resolution,
22052207
return result;
22062208
}
22072209

2208-
Type TypeResolver::diagnoseDisallowedExistential(TypeRepr *repr, Type type) {
2210+
bool TypeResolver::diagnoseDisallowedExistential(TypeRepr *repr) {
22092211
auto options = resolution.getOptions();
22102212
if (!(options & TypeResolutionFlags::SilenceErrors) &&
22112213
options.contains(TypeResolutionFlags::DisallowOpaqueTypes)) {
@@ -2217,9 +2219,18 @@ Type TypeResolver::diagnoseDisallowedExistential(TypeRepr *repr, Type type) {
22172219
// FIXME: We shouldn't have to invalid the type repr here, but not
22182220
// doing so causes a double-diagnostic.
22192221
repr->setInvalid();
2222+
return true;
2223+
} else {
2224+
return false;
22202225
}
2226+
}
22212227

2222-
return type;
2228+
bool TypeResolver::diagnoseInvalidPlaceHolder(OpaqueReturnTypeRepr *repr) {
2229+
if (repr->getConstraint()->isInvalid()){
2230+
if (isa<PlaceholderTypeRepr>(repr->getConstraint()))
2231+
return true;
2232+
}
2233+
return false;
22232234
}
22242235

22252236
/// Checks the given type, assuming that it appears as an argument for a
@@ -2336,9 +2347,10 @@ NeverNullType TypeResolver::resolveType(TypeRepr *repr,
23362347
auto *DC = getDeclContext();
23372348
if (getASTContext().LangOpts.hasFeature(Feature::ImplicitSome)) {
23382349
if (auto opaqueDecl = dyn_cast<OpaqueTypeDecl>(DC)) {
2339-
if (auto ordinal = opaqueDecl->getAnonymousOpaqueParamOrdinal(repr))
2340-
return diagnoseDisallowedExistential(repr,
2341-
getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal));
2350+
if (auto ordinal = opaqueDecl->getAnonymousOpaqueParamOrdinal(repr)){
2351+
diagnoseDisallowedExistential(repr);
2352+
return getOpaqueArchetypeIdentity(opaqueDecl, *ordinal);
2353+
}
23422354
}
23432355
}
23442356

@@ -2358,10 +2370,15 @@ NeverNullType TypeResolver::resolveType(TypeRepr *repr,
23582370
// evaluation of an `OpaqueResultTypeRequest`.
23592371
auto opaqueRepr = cast<OpaqueReturnTypeRepr>(repr);
23602372
auto *DC = getDeclContext();
2373+
2374+
bool isInExistential = diagnoseDisallowedExistential(opaqueRepr);
2375+
bool hasInvalidPlaceholder = diagnoseInvalidPlaceHolder(opaqueRepr);
2376+
23612377
if (auto opaqueDecl = dyn_cast<OpaqueTypeDecl>(DC)) {
2362-
if (auto ordinal = opaqueDecl->getAnonymousOpaqueParamOrdinal(opaqueRepr))
2363-
return diagnoseDisallowedExistential(opaqueRepr,
2364-
getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal));
2378+
if (auto ordinal = opaqueDecl->getAnonymousOpaqueParamOrdinal(opaqueRepr)){
2379+
return !isInExistential ? getOpaqueArchetypeIdentity(opaqueDecl, *ordinal)
2380+
: ErrorType::get(getASTContext());
2381+
}
23652382
}
23662383

23672384
// Check whether any of the generic parameters in the context represents
@@ -2371,19 +2388,18 @@ NeverNullType TypeResolver::resolveType(TypeRepr *repr,
23712388
if (auto genericParams = genericContext->getGenericParams()) {
23722389
for (auto genericParam : *genericParams) {
23732390
if (genericParam->getOpaqueTypeRepr() == opaqueRepr)
2374-
return diagnoseDisallowedExistential(opaqueRepr,
2375-
genericParam->getDeclaredInterfaceType());
2391+
return genericParam->getDeclaredInterfaceType();
23762392
}
23772393
}
23782394
}
23792395
}
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);
2396+
if (!repr->isInvalid() && !hasInvalidPlaceholder){
2397+
// We are not inside an `OpaqueTypeDecl`, so diagnose an error.
2398+
if (!(options & TypeResolutionFlags::SilenceErrors)) {
2399+
diagnose(opaqueRepr->getOpaqueLoc(),
2400+
diag::unsupported_opaque_type);
2401+
}
23852402
}
2386-
23872403
// Try to resolve the constraint upper bound type as a placeholder.
23882404
options |= TypeResolutionFlags::SilenceErrors;
23892405
auto constraintType = resolveType(opaqueRepr->getConstraint(),
@@ -2447,9 +2463,10 @@ NeverNullType TypeResolver::resolveType(TypeRepr *repr,
24472463
return ty;
24482464

24492465
// Complain if we're allowed to and bail out with an error.
2450-
if (!options.contains(TypeResolutionFlags::SilenceErrors))
2466+
if (!options.contains(TypeResolutionFlags::SilenceErrors)) {
24512467
ctx.Diags.diagnose(repr->getLoc(),
24522468
diag::placeholder_type_not_allowed);
2469+
}
24532470

24542471
return ErrorType::get(resolution.getASTContext());
24552472
}
@@ -4074,8 +4091,8 @@ TypeResolver::resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
40744091
// Check whether this type is an implicit opaque result type.
40754092
if (auto *opaqueDecl = dyn_cast<OpaqueTypeDecl>(getDeclContext())) {
40764093
if (auto ordinal = opaqueDecl->getAnonymousOpaqueParamOrdinal(repr)) {
4077-
return diagnoseDisallowedExistential(
4078-
repr, getIdentityOpaqueTypeArchetypeType(opaqueDecl, *ordinal));
4094+
diagnoseDisallowedExistential(repr);
4095+
return getOpaqueArchetypeIdentity(opaqueDecl, *ordinal);
40794096
}
40804097
}
40814098

@@ -4706,6 +4723,7 @@ TypeResolver::resolveExistentialType(ExistentialTypeRepr *repr,
47064723
if (constraintType->hasError())
47074724
return ErrorType::get(getASTContext());
47084725

4726+
//TO-DO: generalize this and emit the same erorr for some P?
47094727
if (!constraintType->isConstraintType()) {
47104728
// Emit a tailored diagnostic for the incorrect optional
47114729
// syntax 'any P?' with a fix-it to add parenthesis.

0 commit comments

Comments
 (0)