Skip to content

Commit 0a40452

Browse files
committed
[Sema] Adjust Diagnostics/IDE to not assume that parameters always have types
1 parent d62be44 commit 0a40452

File tree

6 files changed

+59
-34
lines changed

6 files changed

+59
-34
lines changed

lib/AST/Decl.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2139,8 +2139,10 @@ Type ValueDecl::getInterfaceType() const {
21392139
}
21402140

21412141
void ValueDecl::setInterfaceType(Type type) {
2142-
if (!type.isNull() && isa<ParamDecl>(this)) {
2143-
assert(!type->is<InOutType>() && "caller did not pass a base type");
2142+
if (!type.isNull()) {
2143+
assert(!type->hasTypeVariable() && "Type variable in interface type");
2144+
if (isa<ParamDecl>(this))
2145+
assert(!type->is<InOutType>() && "caller did not pass a base type");
21442146
}
21452147
// lldb creates global typealiases with archetypes in them.
21462148
// FIXME: Add an isDebugAlias() flag, like isDebugVar().
@@ -2153,9 +2155,8 @@ void ValueDecl::setInterfaceType(Type type) {
21532155
isa<AbstractClosureExpr>(getDeclContext()))) {
21542156
assert(!type->hasArchetype() &&
21552157
"Archetype in interface type");
2156-
assert(!type->hasTypeVariable() &&
2157-
"Archetype in interface type");
21582158
}
2159+
21592160
TypeAndAccess.setPointer(type);
21602161
}
21612162

lib/IDE/CodeCompletion.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,6 +2019,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
20192019
auto *GenericSig = VD->getInnermostDeclContext()
20202020
->getGenericSignatureOfContext();
20212021

2022+
assert(VD->hasValidSignature());
20222023
Type T = VD->getInterfaceType();
20232024

20242025
if (*ExprType) {
@@ -2105,6 +2106,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
21052106
addLeadingDot(Builder);
21062107
Builder.addTextChunk(Name);
21072108
setClangDeclKeywords(VD, Pairs, Builder);
2109+
2110+
if (!VD->hasValidSignature())
2111+
return;
2112+
21082113
// Add a type annotation.
21092114
Type VarType = getTypeOfMember(VD);
21102115
if (VD->getName() != Ctx.Id_self && VD->isInOut()) {

lib/Sema/CSDiag.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2479,11 +2479,11 @@ typeCheckArbitrarySubExprIndependently(Expr *subExpr, TCCOptions options) {
24792479
// none of its arguments are type variables. If so, these type variables
24802480
// would be accessible to name lookup of the subexpression and may thus leak
24812481
// in. Reset them to UnresolvedTypes for safe measures.
2482-
for (auto param : *CE->getParameters()) {
2483-
auto VD = param;
2484-
if (VD->getType()->hasTypeVariable() || VD->getType()->hasError()) {
2485-
VD->setType(CS.getASTContext().TheUnresolvedType);
2486-
VD->setInterfaceType(VD->getType());
2482+
for (auto *param : *CE->getParameters()) {
2483+
if (param->hasValidSignature()) {
2484+
auto type = param->getType();
2485+
assert(!type->hasTypeVariable() && !type->hasError());
2486+
(void)type;
24872487
}
24882488
}
24892489
}
@@ -8647,7 +8647,8 @@ diagnoseAmbiguousMultiStatementClosure(ClosureExpr *closure) {
86478647
resultExpr->forEachChildExpr([&](Expr *childExpr) -> Expr *{
86488648
if (auto DRE = dyn_cast<DeclRefExpr>(childExpr)) {
86498649
if (auto param = dyn_cast<ParamDecl>(DRE->getDecl())) {
8650-
auto paramType = param->hasType() ? param->getType() : Type();
8650+
auto paramType =
8651+
param->hasValidSignature() ? param->getType() : Type();
86518652
if (!paramType || paramType->hasTypeVariable()) {
86528653
hasUnresolvedParams = true;
86538654
return nullptr;

lib/Sema/CSGen.cpp

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,30 +1341,45 @@ namespace {
13411341
}
13421342
}
13431343

1344+
// If we're referring to an invalid declaration, don't type-check.
1345+
//
1346+
// FIXME: If the decl is in error, we get no information from this.
1347+
// We may, alternatively, want to use a type variable in that case,
1348+
// and possibly infer the type of the variable that way.
1349+
CS.getTypeChecker().validateDecl(E->getDecl());
1350+
if (E->getDecl()->isInvalid()) {
1351+
CS.setType(E, E->getDecl()->getInterfaceType());
1352+
return nullptr;
1353+
}
1354+
1355+
auto locator = CS.getConstraintLocator(E);
1356+
13441357
if (auto *param = dyn_cast<ParamDecl>(E->getDecl())) {
1345-
if (param->hasInterfaceType()) {
1346-
auto type = param->getInterfaceType();
1347-
if (type->hasTypeParameter())
1348-
type = param->getDeclContext()->mapTypeIntoContext(type);
1358+
// This can only happen when failure diangostics is trying
1359+
// to type-check expressions inside of a single-statement
1360+
// closure which refer to anonymous parameters, in this case
1361+
// let's either use type as written or allocate a fresh type
1362+
// variable, just like we do for closure type.
1363+
if (!CS.hasType(param)) {
1364+
Type paramType;
1365+
if (param->hasInterfaceType()) {
1366+
paramType = param->getInterfaceType();
1367+
if (paramType->hasTypeParameter())
1368+
paramType =
1369+
param->getDeclContext()->mapTypeIntoContext(paramType);
1370+
1371+
if (paramType->hasUnboundGenericType())
1372+
paramType = CS.openUnboundGenericType(paramType, locator);
1373+
1374+
CS.setFavoredType(E, paramType.getPointer());
1375+
} else {
1376+
paramType = CS.createTypeVariable(locator, TVO_CanBindToLValue);
1377+
}
13491378

1350-
CS.setType(param, type);
1351-
CS.setFavoredType(E, type.getPointer());
1352-
}
1353-
} else {
1354-
// If we're referring to an invalid declaration, don't type-check.
1355-
//
1356-
// FIXME: If the decl is in error, we get no information from this.
1357-
// We may, alternatively, want to use a type variable in that case,
1358-
// and possibly infer the type of the variable that way.
1359-
CS.getTypeChecker().validateDecl(E->getDecl());
1360-
if (E->getDecl()->isInvalid()) {
1361-
CS.setType(E, E->getDecl()->getInterfaceType());
1362-
return nullptr;
1379+
CS.setType(param, paramType);
13631380
}
13641381
}
13651382

1366-
auto locator = CS.getConstraintLocator(E);
1367-
13681383
// Create an overload choice referencing this declaration and immediately
13691384
// resolve it. This records the overload for use later.
13701385
auto tv = CS.createTypeVariable(locator,

lib/Sema/CalleeCandidateInfo.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,13 @@ static bool isSubstitutableFor(Type type, ArchetypeType *archetype,
5858

5959
UncurriedCandidate::UncurriedCandidate(ValueDecl *decl, unsigned level)
6060
: declOrExpr(decl), level(level), substituted(false) {
61-
62-
if (auto *PD = dyn_cast<ParamDecl>(decl))
63-
entityType = PD->getType();
64-
else {
61+
62+
if (auto *PD = dyn_cast<ParamDecl>(decl)) {
63+
if (PD->hasValidSignature())
64+
entityType = PD->getType();
65+
else
66+
entityType = PD->getASTContext().TheUnresolvedType;
67+
} else {
6568
entityType = decl->getInterfaceType();
6669
auto *DC = decl->getInnermostDeclContext();
6770
if (auto *GFT = entityType->getAs<GenericFunctionType>()) {

lib/Sema/TypeCheckDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3976,7 +3976,7 @@ void TypeChecker::validateDecl(ValueDecl *D) {
39763976
}
39773977

39783978
auto type = PD->getInterfaceType();
3979-
if (type->hasError() || type->hasUnresolvedType())
3979+
if (type->hasError())
39803980
PD->markInvalid();
39813981
break;
39823982
}

0 commit comments

Comments
 (0)