Skip to content

Commit e508fb3

Browse files
committed
[Sema] Introduce placeholder handler to TypeResolver
For now, don't do anything useful in clients. Specifying a placeholder type is still an error
1 parent d78d95e commit e508fb3

14 files changed

+183
-68
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3542,6 +3542,9 @@ ERROR(generic_type_requires_arguments,none,
35423542
NOTE(descriptive_generic_type_declared_here,none,
35433543
"%0 declared here", (StringRef))
35443544

3545+
ERROR(placeholder_type_not_allowed,none,
3546+
"you cannot use a placeholder type here", ())
3547+
35453548
WARNING(use_of_void_pointer,none,
35463549
"Unsafe%0Pointer<Void> has been replaced by Unsafe%0RawPointer", (StringRef))
35473550

lib/Sema/CSGen.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,8 +1293,11 @@ namespace {
12931293
const ConstraintLocatorBuilder &locator) {
12941294
// Introduce type variables for unbound generics.
12951295
const auto opener = OpenUnboundGenericType(CS, locator);
1296-
const auto result = TypeResolution::forContextual(CS.DC, resCtx, opener)
1297-
.resolveType(repr);
1296+
// TODO: Handle placeholders here.
1297+
const auto result =
1298+
TypeResolution::forContextual(CS.DC, resCtx, opener,
1299+
/*placeholderHandler*/ nullptr)
1300+
.resolveType(repr);
12981301
if (result->hasError()) {
12991302
return Type();
13001303
}
@@ -1558,7 +1561,9 @@ namespace {
15581561
const auto resolution = TypeResolution::forContextual(
15591562
CS.DC, options,
15601563
// Introduce type variables for unbound generics.
1561-
OpenUnboundGenericType(CS, locator));
1564+
// TODO: Handle placeholder types
1565+
OpenUnboundGenericType(CS, locator),
1566+
/*placeholderHandler*/ nullptr);
15621567
const auto result = resolution.resolveType(specializations[i]);
15631568
if (result->hasError())
15641569
return Type();

lib/Sema/CSSolver.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,9 +1015,11 @@ void ConstraintSystem::shrink(Expr *expr) {
10151015
TypeResolution::forContextual(
10161016
CS.DC, None,
10171017
// FIXME: Should we really be unconditionally complaining
1018-
// about unbound generics here? For example:
1018+
// about unbound generics and placeholders here? For
1019+
// example:
10191020
// let foo: [Array<Float>] = [[0], [1], [2]] as [Array]
1020-
/*unboundTyOpener*/ nullptr)
1021+
// let foo: [Array<Float>] = [[0], [1], [2]] as [Array<_>]
1022+
/*unboundTyOpener*/ nullptr, /*placeholderHandler*/ nullptr)
10211023
.resolveType(typeRepr);
10221024

10231025
// Looks like coercion type is invalid, let's skip this sub-tree.

lib/Sema/ConstraintSystem.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,8 @@ Type ConstraintSystem::openUnboundGenericType(
693693
// call to BoundGenericType::get().
694694
return TypeChecker::applyUnboundGenericArguments(
695695
decl, parentTy, SourceLoc(),
696-
TypeResolution::forContextual(DC, None, /*unboundTyOpener*/ nullptr),
696+
TypeResolution::forContextual(DC, None, /*unboundTyOpener*/ nullptr,
697+
/*placeholderHandler*/ nullptr),
697698
arguments);
698699
}
699700

@@ -1213,7 +1214,8 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
12131214
auto type = TypeChecker::resolveTypeInContext(
12141215
typeDecl, nullptr,
12151216
TypeResolution::forContextual(useDC, TypeResolverContext::InExpression,
1216-
/*unboundTyOpener*/ nullptr),
1217+
/*unboundTyOpener*/ nullptr,
1218+
/*placeholderHandler*/ nullptr),
12171219
/*isSpecialized=*/false);
12181220

12191221
checkNestedTypeConstraints(*this, type, locator);
@@ -2230,7 +2232,8 @@ FunctionType::ExtInfo ConstraintSystem::closureEffects(ClosureExpr *expr) {
22302232
if (auto castTypeRepr = isp->getCastTypeRepr()) {
22312233
castType = TypeResolution::forContextual(
22322234
DC, TypeResolverContext::InExpression,
2233-
/*unboundTyOpener*/ nullptr)
2235+
/*unboundTyOpener*/ nullptr,
2236+
/*placeholderHandler*/ nullptr)
22342237
.resolveType(castTypeRepr);
22352238
} else {
22362239
castType = isp->getCastType();

lib/Sema/DerivedConformanceDifferentiable.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,11 @@ void getInheritedProtocols(Decl *decl, SmallPtrSetImpl<ProtocolDecl *> &protos)
372372

373373
for (auto loc : inheritedTypeLocs) {
374374
if (loc.getTypeRepr())
375-
handleInheritedType(TypeResolution::forStructural(
376-
cast<DeclContext>(decl), None, /*unboundTyOpener*/ nullptr)
377-
.resolveType(loc.getTypeRepr()));
375+
handleInheritedType(
376+
TypeResolution::forStructural(cast<DeclContext>(decl), None,
377+
/*unboundTyOpener*/ nullptr,
378+
/*placeholderHandler*/ nullptr)
379+
.resolveType(loc.getTypeRepr()));
378380
else
379381
handleInheritedType(loc.getType());
380382
}

lib/Sema/PreCheckExpr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,6 +1370,10 @@ TypeExpr *PreCheckExpression::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) {
13701370
// FIXME: Don't let unbound generic types escape type resolution.
13711371
// For now, just return the unbound generic type.
13721372
return unboundTy;
1373+
}, /*placeholderHandler*/ [&]() {
1374+
// FIXME: Don't let placeholder types escape type resolution.
1375+
// For now, just return the placeholder type.
1376+
return getASTContext().ThePlaceholderType;
13731377
});
13741378
const auto BaseTy = resolution.resolveType(InnerTypeRepr);
13751379

@@ -1897,6 +1901,10 @@ Expr *PreCheckExpression::simplifyTypeConstructionWithLiteralArg(Expr *E) {
18971901
// FIXME: Don't let unbound generic types escape type resolution.
18981902
// For now, just return the unbound generic type.
18991903
return unboundTy;
1904+
}, /*placeholderHandler*/ [&]() {
1905+
// FIXME: Don't let placeholder types escape type resolution.
1906+
// For now, just return the placeholder type.
1907+
return getASTContext().ThePlaceholderType;
19001908
});
19011909
const auto result = resolution.resolveType(typeExpr->getTypeRepr());
19021910
if (result->hasError())

lib/Sema/TypeCheckAttr.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2720,9 +2720,11 @@ ResolveTypeEraserTypeRequest::evaluate(Evaluator &evaluator,
27202720
TypeEraserAttr *attr) const {
27212721
if (auto *typeEraserRepr = attr->getParsedTypeEraserTypeRepr()) {
27222722
return TypeResolution::forContextual(PD, None,
2723-
// Unbound generics are not allowed
2724-
// within this attribute.
2725-
/*unboundTyOpener*/ nullptr)
2723+
// Unbound generics and placeholders
2724+
// are not allowed within this
2725+
// attribute.
2726+
/*unboundTyOpener*/ nullptr,
2727+
/*placeholderHandler*/ nullptr)
27262728
.resolveType(typeEraserRepr);
27272729
} else {
27282730
auto *LazyResolver = attr->Resolver;
@@ -2904,7 +2906,8 @@ void AttributeChecker::visitImplementsAttr(ImplementsAttr *attr) {
29042906

29052907
Type T = attr->getProtocolType();
29062908
if (!T && attr->getProtocolTypeRepr()) {
2907-
T = TypeResolution::forContextual(DC, None, /*unboundTyOpener*/ nullptr)
2909+
T = TypeResolution::forContextual(DC, None, /*unboundTyOpener*/ nullptr,
2910+
/*placeholderHandler*/ nullptr)
29082911
.resolveType(attr->getProtocolTypeRepr());
29092912
}
29102913

@@ -4698,7 +4701,8 @@ static bool typeCheckDerivativeAttr(ASTContext &Ctx, Decl *D,
46984701
TypeResolutionOptions(None) | TypeResolutionFlags::AllowModule;
46994702
baseType =
47004703
TypeResolution::forContextual(derivative->getDeclContext(), options,
4701-
/*unboundTyOpener*/ nullptr)
4704+
/*unboundTyOpener*/ nullptr,
4705+
/*placeholderHandler*/ nullptr)
47024706
.resolveType(baseTypeRepr);
47034707
}
47044708
if (baseType && baseType->hasError())
@@ -5269,7 +5273,8 @@ void AttributeChecker::visitTransposeAttr(TransposeAttr *attr) {
52695273
Type baseType;
52705274
if (attr->getBaseTypeRepr()) {
52715275
baseType = TypeResolution::forContextual(transpose->getDeclContext(), None,
5272-
/*unboundTyOpener*/ nullptr)
5276+
/*unboundTyOpener*/ nullptr,
5277+
/*placeholderHandler*/ nullptr)
52735278
.resolveType(attr->getBaseTypeRepr());
52745279
}
52755280
auto lookupOptions =

lib/Sema/TypeCheckDecl.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -953,8 +953,10 @@ DefaultDefinitionTypeRequest::evaluate(Evaluator &evaluator,
953953
TypeRepr *defaultDefinition = assocType->getDefaultDefinitionTypeRepr();
954954
if (defaultDefinition) {
955955
return TypeResolution::forInterface(assocType->getDeclContext(), None,
956-
// Diagnose unbound generics.
957-
/*unboundTyOpener*/ nullptr)
956+
// Diagnose unbound generics and
957+
// placeholders.
958+
/*unboundTyOpener*/ nullptr,
959+
/*placeholderHandler*/ nullptr)
958960
.resolveType(defaultDefinition);
959961
}
960962

@@ -1523,7 +1525,8 @@ static NominalTypeDecl *resolveSingleNominalTypeDecl(
15231525
TypeResolution::forInterface(DC, options,
15241526
// FIXME: Should unbound generics be allowed
15251527
// to appear amongst designated types?
1526-
/*unboundTyOpener*/ nullptr)
1528+
/*unboundTyOpener*/ nullptr,
1529+
/*placeholderHandler*/ nullptr)
15271530
.resolveType(TyR);
15281531

15291532
if (result->hasError())
@@ -1828,9 +1831,11 @@ UnderlyingTypeRequest::evaluate(Evaluator &evaluator,
18281831
return ErrorType::get(typeAlias->getASTContext());
18291832
}
18301833

1831-
const auto result = TypeResolution::forInterface(typeAlias, options,
1832-
/*unboundTyOpener*/ nullptr)
1833-
.resolveType(underlyingRepr);
1834+
const auto result =
1835+
TypeResolution::forInterface(typeAlias, options,
1836+
/*unboundTyOpener*/ nullptr,
1837+
/*placeholderHandler*/ nullptr)
1838+
.resolveType(underlyingRepr);
18341839

18351840
if (result->hasError()) {
18361841
typeAlias->setInvalid();
@@ -2085,7 +2090,8 @@ ResultTypeRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
20852090
const auto options =
20862091
TypeResolutionOptions(TypeResolverContext::FunctionResult);
20872092
auto *const dc = decl->getInnermostDeclContext();
2088-
return TypeResolution::forInterface(dc, options, /*unboundTyOpener*/ nullptr)
2093+
return TypeResolution::forInterface(dc, options, /*unboundTyOpener*/ nullptr,
2094+
/*placeholderHandler*/ nullptr)
20892095
.resolveType(resultTyRepr);
20902096
}
20912097

@@ -2162,9 +2168,11 @@ ParamSpecifierRequest::evaluate(Evaluator &evaluator,
21622168

21632169
static Type validateParameterType(ParamDecl *decl) {
21642170
auto *dc = decl->getDeclContext();
2171+
auto &ctx = dc->getASTContext();
21652172

21662173
TypeResolutionOptions options(None);
21672174
OpenUnboundGenericTypeFn unboundTyOpener = nullptr;
2175+
HandlePlaceholderTypeReprFn placeholderHandler = nullptr;
21682176
if (isa<AbstractClosureExpr>(dc)) {
21692177
options = TypeResolutionOptions(TypeResolverContext::ClosureExpr);
21702178
options |= TypeResolutionFlags::AllowUnspecifiedTypes;
@@ -2173,6 +2181,11 @@ static Type validateParameterType(ParamDecl *decl) {
21732181
// For now, just return the unbound generic type.
21742182
return unboundTy;
21752183
};
2184+
placeholderHandler = [&]() {
2185+
// FIXME: Don't let placeholder types escape type resolution.
2186+
// For now, just return the placeholder type.
2187+
return ctx.ThePlaceholderType;
2188+
};
21762189
} else if (isa<AbstractFunctionDecl>(dc)) {
21772190
options = TypeResolutionOptions(TypeResolverContext::AbstractFunctionDecl);
21782191
} else if (isa<SubscriptDecl>(dc)) {
@@ -2194,10 +2207,10 @@ static Type validateParameterType(ParamDecl *decl) {
21942207
options |= TypeResolutionFlags::AllowUsableFromInline;
21952208

21962209
const auto resolution =
2197-
TypeResolution::forInterface(dc, options, unboundTyOpener);
2210+
TypeResolution::forInterface(dc, options, unboundTyOpener,
2211+
placeholderHandler);
21982212
auto Ty = resolution.resolveType(decl->getTypeRepr());
21992213

2200-
auto &ctx = dc->getASTContext();
22012214
if (Ty->hasError()) {
22022215
decl->setInvalid();
22032216
return ErrorType::get(ctx);
@@ -2769,6 +2782,10 @@ ExtendedTypeRequest::evaluate(Evaluator &eval, ExtensionDecl *ext) const {
27692782
// FIXME: Don't let unbound generic types escape type resolution.
27702783
// For now, just return the unbound generic type.
27712784
return unboundTy;
2785+
}, /*placeholderHandler*/ [&]() {
2786+
// FIXME: Don't let placeholder types escape type resolution.
2787+
// For now, just return the placeholder type.
2788+
return ext->getASTContext().ThePlaceholderType;
27722789
});
27732790

27742791
const auto extendedType = resolution.resolveType(extendedRepr);

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,10 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator,
132132
// type. Pass along the error type if resolving the repr failed.
133133
auto constraintType = TypeResolution::forInterface(
134134
dc, TypeResolverContext::GenericRequirement,
135-
// Unbound generics are meaningless in opaque types.
136-
/*unboundTyOpener*/ nullptr)
135+
// Unbound generics and placeholders are meaningless
136+
// in opaque types.
137+
/*unboundTyOpener*/ nullptr,
138+
/*placeholderHandler*/ nullptr)
137139
.resolveType(repr->getConstraint());
138140

139141
if (constraintType->hasError())
@@ -666,7 +668,8 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
666668

667669
const auto resolution =
668670
TypeResolution::forStructural(GC, baseOptions,
669-
/*unboundTyOpener*/ nullptr);
671+
/*unboundTyOpener*/ nullptr,
672+
/*placeholderHandler*/ nullptr);
670673
auto params = func ? func->getParameters() : subscr->getIndices();
671674
for (auto param : *params) {
672675
auto *typeRepr = param->getTypeRepr();
@@ -910,12 +913,14 @@ RequirementRequest::evaluate(Evaluator &evaluator,
910913
switch (stage) {
911914
case TypeResolutionStage::Structural:
912915
resolution = TypeResolution::forStructural(owner.dc, options,
913-
/*unboundTyOpener*/ nullptr);
916+
/*unboundTyOpener*/ nullptr,
917+
/*placeholderHandler*/ nullptr);
914918
break;
915919

916920
case TypeResolutionStage::Interface:
917921
resolution = TypeResolution::forInterface(owner.dc, options,
918-
/*unboundTyOpener*/ nullptr);
922+
/*unboundTyOpener*/ nullptr,
923+
/*placeholderHandler*/ nullptr);
919924
break;
920925

921926
case TypeResolutionStage::Contextual:
@@ -961,9 +966,11 @@ Type StructuralTypeRequest::evaluate(Evaluator &evaluator,
961966
return ErrorType::get(ctx);
962967
}
963968

964-
const auto type = TypeResolution::forStructural(typeAlias, options,
965-
/*unboundTyOpener*/ nullptr)
966-
.resolveType(underlyingTypeRepr);
969+
const auto type =
970+
TypeResolution::forStructural(typeAlias, options,
971+
/*unboundTyOpener*/ nullptr,
972+
/*placeholderHandler*/ nullptr)
973+
.resolveType(underlyingTypeRepr);
967974

968975
auto genericSig = typeAlias->getGenericSignature();
969976
SubstitutionMap subs;

lib/Sema/TypeCheckPattern.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,10 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
472472
// FIXME: Don't let unbound generic types escape type resolution.
473473
// For now, just return the unbound generic type.
474474
return unboundTy;
475+
}, /*placeholderHandler*/ [&]() {
476+
// FIXME: Don't let placeholder types escape type resolution.
477+
// For now, just return the placeholder type.
478+
return Context.ThePlaceholderType;
475479
});
476480
const auto ty = resolution.resolveType(repr);
477481
auto *enumDecl = dyn_cast_or_null<EnumDecl>(ty->getAnyNominal());
@@ -589,6 +593,10 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
589593
// FIXME: Don't let unbound generic types escape type resolution.
590594
// For now, just return the unbound generic type.
591595
return unboundTy;
596+
}, /*placeholderHandler*/ [&]() {
597+
// FIXME: Don't let placeholder types escape type resolution.
598+
// For now, just return the placeholder type.
599+
return Context.ThePlaceholderType;
592600
}).resolveType(prefixRepr);
593601
auto *enumDecl = dyn_cast_or_null<EnumDecl>(enumTy->getAnyNominal());
594602
if (!enumDecl)
@@ -785,16 +793,23 @@ Type PatternTypeRequest::evaluate(Evaluator &evaluator,
785793
// that type.
786794
case PatternKind::Typed: {
787795
OpenUnboundGenericTypeFn unboundTyOpener = nullptr;
796+
HandlePlaceholderTypeReprFn placeholderHandler = nullptr;
788797
if (pattern.allowsInference()) {
789798
unboundTyOpener = [](auto unboundTy) {
790799
// FIXME: Don't let unbound generic types escape type resolution.
791800
// For now, just return the unbound generic type.
792801
return unboundTy;
793802
};
803+
placeholderHandler = [&] {
804+
// FIXME: Don't let placeholder types escape type resolution.
805+
// For now, just return the placeholder type.
806+
return Context.ThePlaceholderType;
807+
};
794808
}
795809
return validateTypedPattern(
796810
cast<TypedPattern>(P),
797-
TypeResolution::forContextual(dc, options, unboundTyOpener));
811+
TypeResolution::forContextual(dc, options, unboundTyOpener,
812+
placeholderHandler));
798813
}
799814

800815
// A wildcard or name pattern cannot appear by itself in a context
@@ -848,16 +863,23 @@ Type PatternTypeRequest::evaluate(Evaluator &evaluator,
848863
auto somePat = cast<OptionalSomePattern>(P);
849864
if (somePat->isImplicit() && isa<TypedPattern>(somePat->getSubPattern())) {
850865
OpenUnboundGenericTypeFn unboundTyOpener = nullptr;
866+
HandlePlaceholderTypeReprFn placeholderHandler = nullptr;
851867
if (pattern.allowsInference()) {
852868
unboundTyOpener = [](auto unboundTy) {
853869
// FIXME: Don't let unbound generic types escape type resolution.
854870
// For now, just return the unbound generic type.
855871
return unboundTy;
856872
};
873+
placeholderHandler = [&]() {
874+
// FIXME: Don't let placeholder types escape type resolution.
875+
// For now, just return the placeholder type.
876+
return Context.ThePlaceholderType;
877+
};
857878
}
858879
TypedPattern *TP = cast<TypedPattern>(somePat->getSubPattern());
859880
const auto type = validateTypedPattern(
860-
TP, TypeResolution::forContextual(dc, options, unboundTyOpener));
881+
TP, TypeResolution::forContextual(dc, options, unboundTyOpener,
882+
placeholderHandler));
861883
if (type && !type->hasError()) {
862884
return OptionalType::get(type);
863885
}
@@ -1264,8 +1286,10 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern,
12641286
const auto castType =
12651287
TypeResolution::forContextual(dc, TypeResolverContext::InExpression,
12661288
// FIXME: Should we really unconditionally
1267-
// complain about unbound generics here?
1268-
/*unboundTyOpener*/ nullptr)
1289+
// complain about unbound generics and
1290+
// placeholders here?
1291+
/*unboundTyOpener*/ nullptr,
1292+
/*placeholderHandler*/ nullptr)
12691293
.resolveType(IP->getCastTypeRepr());
12701294
if (castType->hasError())
12711295
return nullptr;

0 commit comments

Comments
 (0)