Skip to content

Commit 6cbb494

Browse files
committed
AST: Give all ValueDecls an interface type
Previously, getInterfaceType() would return getType() if no interface type was set. Instead, always set an interface type explicitly. Eventually we want to remove getType() altogether, and this brings us one step closer to this goal. Note that ParamDecls are excempt from this treatment, because they don't have a proper interface type yet. Cleaning this up requires more effort.
1 parent 530478c commit 6cbb494

22 files changed

+184
-95
lines changed

lib/AST/Decl.cpp

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2259,6 +2259,7 @@ GenericTypeParamDecl::GenericTypeParamDecl(DeclContext *dc, Identifier name,
22592259
auto &ctx = dc->getASTContext();
22602260
auto type = new (ctx, AllocationArena::Permanent) GenericTypeParamType(this);
22612261
setType(MetatypeType::get(type, ctx));
2262+
setInterfaceType(MetatypeType::get(type, ctx));
22622263
}
22632264

22642265
SourceRange GenericTypeParamDecl::getSourceRange() const {
@@ -4625,26 +4626,54 @@ SourceRange EnumElementDecl::getSourceRange() const {
46254626

46264627
bool EnumElementDecl::computeType() {
46274628
EnumDecl *ED = getParentEnum();
4628-
Type resultTy = ED->getDeclaredTypeInContext();
4629+
{
4630+
Type resultTy = ED->getDeclaredTypeInContext();
4631+
4632+
if (resultTy->hasError()) {
4633+
setType(resultTy);
4634+
setInterfaceType(resultTy);
4635+
return false;
4636+
}
4637+
4638+
Type argTy = MetatypeType::get(resultTy);
4639+
4640+
// The type of the enum element is either (T) -> T or (T) -> ArgType -> T.
4641+
if (getArgumentType())
4642+
resultTy = FunctionType::get(getArgumentType(), resultTy);
4643+
4644+
if (ED->isGenericContext())
4645+
resultTy = PolymorphicFunctionType::get(argTy, resultTy,
4646+
ED->getGenericParamsOfContext());
4647+
else
4648+
resultTy = FunctionType::get(argTy, resultTy);
46294649

4630-
if (resultTy->hasError()) {
46314650
setType(resultTy);
4632-
return false;
46334651
}
4652+
{
4653+
Type resultTy = ED->getDeclaredInterfaceType();
4654+
4655+
if (resultTy->hasError()) {
4656+
setInterfaceType(resultTy);
4657+
return false;
4658+
}
4659+
4660+
Type argTy = MetatypeType::get(resultTy);
46344661

4635-
Type argTy = MetatypeType::get(resultTy);
4662+
// The type of the enum element is either (T) -> T or (T) -> ArgType -> T.
4663+
if (auto inputTy = getArgumentType())
4664+
resultTy = FunctionType::get(
4665+
ArchetypeBuilder::mapTypeOutOfContext(ED, inputTy), resultTy);
46364666

4637-
// The type of the enum element is either (T) -> T or (T) -> ArgType -> T.
4638-
if (getArgumentType())
4639-
resultTy = FunctionType::get(getArgumentType(), resultTy);
4667+
if (auto *genericSig = ED->getGenericSignatureOfContext())
4668+
resultTy = GenericFunctionType::get(genericSig, argTy, resultTy,
4669+
AnyFunctionType::ExtInfo());
4670+
else
4671+
resultTy = FunctionType::get(argTy, resultTy);
46404672

4641-
if (ED->isGenericContext())
4642-
resultTy = PolymorphicFunctionType::get(argTy, resultTy,
4643-
ED->getGenericParamsOfContext());
4644-
else
4645-
resultTy = FunctionType::get(argTy, resultTy);
4673+
// Record the interface type.
4674+
setInterfaceType(resultTy);
4675+
}
46464676

4647-
setType(resultTy);
46484677
return true;
46494678
}
46504679

lib/AST/Module.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ void BuiltinUnit::LookupCache::lookupValue(
8484
/*genericparams*/nullptr,
8585
const_cast<BuiltinUnit*>(&M));
8686
TAD->computeType();
87+
TAD->setInterfaceType(TAD->getType());
8788
TAD->setAccessibility(Accessibility::Public);
8889
Entry = TAD;
8990
}
@@ -346,6 +347,7 @@ ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx)
346347
ctx.addDestructorCleanup(*this);
347348
setImplicit();
348349
setType(ModuleType::get(this));
350+
setInterfaceType(ModuleType::get(this));
349351
setAccessibility(Accessibility::Public);
350352
}
351353

lib/ClangImporter/ImportDecl.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ createVarWithPattern(ASTContext &cxt, DeclContext *dc, Identifier name, Type ty,
126126
/*IsLet*/ isLet, SourceLoc(), name, ty, dc);
127127
if (isImplicit)
128128
var->setImplicit();
129+
var->setInterfaceType(ty);
129130
var->setAccessibility(Accessibility::Public);
130131
var->setSetterAccessibility(setterAccessibility);
131132

@@ -1197,6 +1198,7 @@ static void makeStructRawValuedWithBridge(
11971198
auto computedVar = new (cxt) VarDecl(
11981199
/*static*/ false,
11991200
/*IsLet*/ false, SourceLoc(), computedVarName, bridgedType, structDecl);
1201+
computedVar->setInterfaceType(bridgedType);
12001202
computedVar->setImplicit();
12011203
computedVar->setAccessibility(Accessibility::Public);
12021204
computedVar->setSetterAccessibility(Accessibility::Private);
@@ -1512,6 +1514,7 @@ static bool addErrorDomain(NominalTypeDecl *swiftDecl,
15121514
auto errorDomainPropertyDecl = new (C) VarDecl(
15131515
isStatic,
15141516
/*isLet=*/false, SourceLoc(), C.Id_nsErrorDomain, stringTy, swiftDecl);
1517+
errorDomainPropertyDecl->setInterfaceType(stringTy);
15151518
errorDomainPropertyDecl->setAccessibility(Accessibility::Public);
15161519

15171520
swiftDecl->addMember(errorDomainPropertyDecl);
@@ -1921,6 +1924,7 @@ namespace {
19211924
underlying->getDeclaredInterfaceType()),
19221925
/*genericparams*/nullptr, DC);
19231926
typealias->computeType();
1927+
typealias->setInterfaceType(typealias->getType());
19241928

19251929
Impl.SpecialTypedefNames[Decl->getCanonicalDecl()] =
19261930
MappedTypeNameKind::DefineAndUse;
@@ -1946,6 +1950,7 @@ namespace {
19461950
proto->getDeclaredInterfaceType()),
19471951
/*genericparams*/nullptr, DC);
19481952
typealias->computeType();
1953+
typealias->setInterfaceType(typealias->getType());
19491954

19501955
Impl.SpecialTypedefNames[Decl->getCanonicalDecl()] =
19511956
MappedTypeNameKind::DefineAndUse;
@@ -2014,6 +2019,7 @@ namespace {
20142019
TypeLoc::withoutLoc(SwiftType),
20152020
/*genericparams*/nullptr, DC);
20162021
Result->computeType();
2022+
Result->setInterfaceType(Result->getType());
20172023

20182024
// Make Objective-C's 'id' unavailable.
20192025
ASTContext &ctx = DC->getASTContext();
@@ -2189,6 +2195,7 @@ namespace {
21892195
errorWrapper);
21902196
nsErrorProp->setImplicit();
21912197
nsErrorProp->setAccessibility(Accessibility::Public);
2198+
nsErrorProp->setInterfaceType(nsErrorType);
21922199

21932200
// Create a pattern binding to describe the variable.
21942201
Pattern *nsErrorPattern = createTypedNamedPattern(nsErrorProp);
@@ -2256,6 +2263,7 @@ namespace {
22562263
rawValue->setImplicit();
22572264
rawValue->setAccessibility(Accessibility::Public);
22582265
rawValue->setSetterAccessibility(Accessibility::Private);
2266+
rawValue->setInterfaceType(underlyingType);
22592267

22602268
// Create a pattern binding to describe the variable.
22612269
Pattern *varPattern = createTypedNamedPattern(rawValue);
@@ -2282,6 +2290,7 @@ namespace {
22822290
errorWrapper->getDeclaredInterfaceType()),
22832291
/*genericSignature=*/nullptr, enumDecl);
22842292
alias->computeType();
2293+
alias->setInterfaceType(alias->getType());
22852294
enumDecl->addMember(alias);
22862295

22872296
// Add the 'Code' enum to the error wrapper.
@@ -2775,6 +2784,7 @@ namespace {
27752784
/*static*/ false, /*IsLet*/ false,
27762785
Impl.importSourceLoc(decl->getLocStart()),
27772786
name, type, dc);
2787+
result->setInterfaceType(type);
27782788

27792789
// If this is a Swift 2 stub, mark is as such.
27802790
if (swift3Name)
@@ -2965,6 +2975,7 @@ namespace {
29652975
/*static*/ false, /*IsLet*/ false,
29662976
Impl.importSourceLoc(decl->getLocation()),
29672977
name, type, dc);
2978+
result->setInterfaceType(type);
29682979

29692980
// Handle attributes.
29702981
if (decl->hasAttr<clang::IBOutletAttr>())
@@ -3037,6 +3048,7 @@ namespace {
30373048
Impl.shouldImportGlobalAsLet(decl->getType()),
30383049
Impl.importSourceLoc(decl->getLocation()),
30393050
name, type, dc);
3051+
result->setInterfaceType(type);
30403052

30413053
// If imported as member, the member should be final.
30423054
if (dc->getAsClassOrClassExtensionContext())
@@ -4111,6 +4123,7 @@ namespace {
41114123
/*genericparams=*/nullptr, dc);
41124124

41134125
typealias->computeType();
4126+
typealias->setInterfaceType(typealias->getType());
41144127

41154128
return typealias;
41164129
}
@@ -4347,6 +4360,7 @@ Decl *SwiftDeclConverter::importSwift2TypeAlias(const clang::NamedDecl *decl,
43474360
Impl.importSourceLoc(decl->getLocation()),
43484361
TypeLoc::withoutLoc(underlyingType), genericParams, dc);
43494362
alias->computeType();
4363+
alias->setInterfaceType(alias->getType());
43504364
alias->setGenericEnvironment(genericEnv);
43514365

43524366
// Record that this is the Swift 2 version of this declaration.
@@ -4927,6 +4941,7 @@ SwiftDeclConverter::getImplicitProperty(ImportedName importedName,
49274941
auto property = Impl.createDeclWithClangNode<VarDecl>(
49284942
getter, Accessibility::Public, isStatic,
49294943
/*isLet=*/false, SourceLoc(), propertyName, swiftPropertyType, dc);
4944+
property->setInterfaceType(swiftPropertyType);
49304945

49314946
// Note that we've formed this property.
49324947
Impl.FunctionsAsProperties[getter] = property;
@@ -7047,6 +7062,8 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
70477062
VarDecl(isStatic, /*IsLet*/ false, SourceLoc(), name, type, dc);
70487063
}
70497064

7065+
var->setInterfaceType(type);
7066+
70507067
// Form the argument patterns.
70517068
SmallVector<ParameterList*, 3> getterArgs;
70527069

@@ -7148,6 +7165,7 @@ createUnavailableDecl(Identifier name, DeclContext *dc, Type type,
71487165
auto var = createDeclWithClangNode<VarDecl>(ClangN, Accessibility::Public,
71497166
isStatic, /*IsLet*/ false,
71507167
SourceLoc(), name, type, dc);
7168+
var->setInterfaceType(type);
71517169
markUnavailable(var, UnavailableMessage);
71527170

71537171
return var;

lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5315,6 +5315,7 @@ ParserStatus Parser::parseDeclSubscript(ParseDeclOptions Flags,
53155315

53165316
if (Invalid) {
53175317
Subscript->setType(ErrorType::get(Context));
5318+
Subscript->setInterfaceType(ErrorType::get(Context));
53185319
Subscript->setInvalid();
53195320
}
53205321

lib/Sema/CSDiag.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3199,8 +3199,10 @@ namespace {
31993199
for (auto patternElt : PatternTypes)
32003200
patternElt.first->setType(patternElt.second);
32013201

3202-
for (auto paramDeclElt : ParamDeclTypes)
3202+
for (auto paramDeclElt : ParamDeclTypes) {
32033203
paramDeclElt.first->overwriteType(paramDeclElt.second);
3204+
paramDeclElt.first->setInterfaceType(Type());
3205+
}
32043206

32053207
for (auto CSE : CollectionSemanticExprs)
32063208
CSE.first->setSemanticExpr(CSE.second);

lib/Sema/CodeSynthesis.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,6 +1440,7 @@ void TypeChecker::completePropertyBehaviorAccessors(VarDecl *VD,
14401440
ArrayRef<Substitution> SelfInterfaceSubs,
14411441
ArrayRef<Substitution> SelfContextSubs) {
14421442
auto selfTy = SelfContextSubs[0].getReplacement();
1443+
auto selfIfaceTy = SelfInterfaceSubs[0].getReplacement();
14431444

14441445
SmallVector<ASTNode, 3> bodyStmts;
14451446

@@ -1469,6 +1470,8 @@ void TypeChecker::completePropertyBehaviorAccessors(VarDecl *VD,
14691470
SourceLoc(),
14701471
Context.getIdentifier("tempSelf"),
14711472
selfTy, fromAccessor);
1473+
var->setInterfaceType(selfIfaceTy);
1474+
14721475
auto varPat = new (Context) NamedPattern(var);
14731476
auto pbd = PatternBindingDecl::create(Context, SourceLoc(),
14741477
StaticSpellingKind::None,

lib/Sema/ConstraintSystem.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,8 +771,11 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
771771
}
772772

773773
// Determine the type of the value, opening up that type if necessary.
774+
bool wantInterfaceType = true;
775+
if (isa<VarDecl>(value))
776+
wantInterfaceType = !value->getDeclContext()->isLocalContext();
774777
Type valueType = TC.getUnopenedTypeOfReference(value, Type(), DC, base,
775-
/*wantInterfaceType=*/true);
778+
wantInterfaceType);
776779

777780
// If this is a let-param whose type is a type variable, this is an untyped
778781
// closure param that may be bound to an inout type later. References to the

lib/Sema/DerivedConformanceEquatableHashable.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ static DeclRefExpr *convertEnumToIndex(SmallVectorImpl<ASTNode> &stmts,
6767
auto indexVar = new (C) VarDecl(/*static*/false, /*let*/false,
6868
SourceLoc(), C.getIdentifier(indexName),
6969
intType, funcDecl);
70+
indexVar->setInterfaceType(intType);
7071
indexVar->setImplicit();
7172

7273
// generate: var indexVar
@@ -445,6 +446,7 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl,
445446
SourceLoc(), C.Id_hashValue,
446447
intType, parentDC);
447448
hashValueDecl->setImplicit();
449+
hashValueDecl->setInterfaceType(intType);
448450
hashValueDecl->makeComputed(SourceLoc(), getterDecl,
449451
nullptr, nullptr, SourceLoc());
450452
hashValueDecl->setAccessibility(getterDecl->getFormalAccess());

lib/Sema/PlaygroundTransform.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,7 @@ class Instrumenter {
913913
MaybeLoadInitExpr->getType(),
914914
TypeCheckDC);
915915

916+
VD->setInterfaceType(VD->getType());
916917
VD->setImplicit();
917918

918919
NamedPattern *NP = new (Context) NamedPattern(VD, /*implicit*/true);

lib/Sema/TypeCheckAttr.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1641,6 +1641,7 @@ void TypeChecker::checkNoEscapeAttr(ParamDecl *PD, NoEscapeAttr *attr) {
16411641

16421642
void TypeChecker::checkOwnershipAttr(VarDecl *var, OwnershipAttr *attr) {
16431643
Type type = var->getType();
1644+
Type interfaceType = var->getInterfaceType();
16441645

16451646
// Just stop if we've already processed this declaration.
16461647
if (type->is<ReferenceStorageType>())
@@ -1699,7 +1700,10 @@ void TypeChecker::checkOwnershipAttr(VarDecl *var, OwnershipAttr *attr) {
16991700
}
17001701

17011702
// Change the type to the appropriate reference storage type.
1702-
var->overwriteType(ReferenceStorageType::get(type, ownershipKind, Context));
1703+
var->overwriteType(ReferenceStorageType::get(
1704+
type, ownershipKind, Context));
1705+
var->setInterfaceType(ReferenceStorageType::get(
1706+
interfaceType, ownershipKind, Context));
17031707
}
17041708

17051709
Optional<Diag<>>

lib/Sema/TypeCheckCaptures.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,9 @@ class FindCapturedVars : public ASTWalker {
320320
if (!validateForwardCapture(DRE->getDecl()))
321321
return { false, DRE };
322322

323-
bool isInOut = D->hasType() && D->getInterfaceType()->is<InOutType>();
323+
bool isInOut = (isa<ParamDecl>(D) &&
324+
D->hasType() &&
325+
D->getType()->is<InOutType>());
324326
bool isNested = false;
325327
if (auto f = AFR.getAbstractFunctionDecl())
326328
isNested = f->getDeclContext()->isLocalContext();
@@ -642,9 +644,11 @@ void TypeChecker::computeCaptures(AnyFunctionRef AFR) {
642644

643645
unsigned inoutCount = 0;
644646
for (auto C: Captures) {
645-
if (auto type = C.getDecl()->getInterfaceType())
646-
if (isa<InOutType>(type.getPointer()))
647-
inoutCount++;
647+
if (auto PD = dyn_cast<ParamDecl>(C.getDecl()))
648+
if (PD->hasType())
649+
if (auto type = PD->getType())
650+
if (isa<InOutType>(type.getPointer()))
651+
inoutCount++;
648652
}
649653

650654
if (inoutCount > 0) {

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,7 @@ void CleanupIllFormedExpressionRAII::doIt(Expr *expr, ASTContext &Context) {
12901290
if (auto VD = dyn_cast<ValueDecl>(D)) {
12911291
if (VD->hasType() && VD->getType()->hasTypeVariable()) {
12921292
VD->overwriteType(ErrorType::get(context));
1293+
VD->setInterfaceType(ErrorType::get(context));
12931294
VD->setInvalid();
12941295
}
12951296
}
@@ -1897,6 +1898,7 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
18971898
return;
18981899

18991900
var->overwriteType(ErrorType::get(Context));
1901+
var->setInterfaceType(ErrorType::get(Context));
19001902
var->setInvalid();
19011903
});
19021904
}
@@ -2227,6 +2229,7 @@ bool TypeChecker::typeCheckStmtCondition(StmtCondition &cond, DeclContext *dc,
22272229
if (var->hasType() && !var->getType()->hasError())
22282230
return;
22292231
var->overwriteType(ErrorType::get(Context));
2232+
var->setInterfaceType(ErrorType::get(Context));
22302233
var->setInvalid();
22312234
});
22322235
};
@@ -2280,6 +2283,7 @@ bool TypeChecker::typeCheckExprPattern(ExprPattern *EP, DeclContext *DC,
22802283
Context.getIdentifier("$match"),
22812284
rhsType,
22822285
DC);
2286+
matchVar->setInterfaceType(rhsType);
22832287

22842288
matchVar->setImplicit();
22852289
EP->setMatchVar(matchVar);

0 commit comments

Comments
 (0)