Skip to content

Commit 7ed1882

Browse files
committed
Remodel the Interface for Implicit TypeExprs
Make it slightly easier to enforce the invariant that implicit TypeExpr nodes have a contextual type set.
1 parent 09db290 commit 7ed1882

File tree

8 files changed

+68
-55
lines changed

8 files changed

+68
-55
lines changed

include/swift/AST/Expr.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,9 +1359,10 @@ class TypeExpr : public Expr {
13591359

13601360

13611361
/// Create a TypeExpr for a TypeDecl at the specified location.
1362-
static TypeExpr *createForDecl(DeclNameLoc Loc, TypeDecl *D,
1363-
DeclContext *DC,
1364-
bool isImplicit);
1362+
static TypeExpr *createForDecl(DeclNameLoc Loc, TypeDecl *D, DeclContext *DC);
1363+
1364+
static TypeExpr *createImplicitForDecl(DeclNameLoc Loc, TypeDecl *D,
1365+
DeclContext *DC, Type ty);
13651366

13661367
/// Create a TypeExpr for a member TypeDecl of the given parent TypeDecl.
13671368
static TypeExpr *createForMemberDecl(DeclNameLoc ParentNameLoc,

lib/AST/Expr.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1950,19 +1950,25 @@ Type TypeExpr::getInstanceType(
19501950
return ErrorType::get(getType(this)->getASTContext());
19511951
}
19521952

1953-
19541953
TypeExpr *TypeExpr::createForDecl(DeclNameLoc Loc, TypeDecl *Decl,
1955-
DeclContext *DC,
1956-
bool isImplicit) {
1954+
DeclContext *DC) {
19571955
ASTContext &C = Decl->getASTContext();
1958-
assert(Loc.isValid() || isImplicit);
1956+
assert(Loc.isValid());
19591957
auto *Repr = new (C) SimpleIdentTypeRepr(Loc, Decl->createNameRef());
19601958
Repr->setValue(Decl, DC);
19611959
auto result = new (C) TypeExpr(Repr);
1962-
if (isImplicit) {
1963-
result->setType(DC->mapTypeIntoContext(Decl->getInterfaceType()));
1964-
result->setImplicit();
1965-
}
1960+
return result;
1961+
}
1962+
1963+
TypeExpr *TypeExpr::createImplicitForDecl(DeclNameLoc Loc, TypeDecl *Decl,
1964+
DeclContext *DC, Type ty) {
1965+
ASTContext &C = Decl->getASTContext();
1966+
auto *Repr = new (C) SimpleIdentTypeRepr(Loc, Decl->createNameRef());
1967+
Repr->setValue(Decl, DC);
1968+
auto result = new (C) TypeExpr(Repr);
1969+
assert(ty && !ty->hasTypeParameter());
1970+
result->setType(ty);
1971+
result->setImplicit();
19661972
return result;
19671973
}
19681974

lib/Parse/ParseExpr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2306,7 +2306,7 @@ Expr *Parser::parseExprIdentifier() {
23062306
// global or local declarations here.
23072307
assert(!TD->getDeclContext()->isTypeContext() ||
23082308
isa<GenericTypeParamDecl>(TD));
2309-
E = TypeExpr::createForDecl(loc, TD, /*DC*/nullptr, /*implicit*/false);
2309+
E = TypeExpr::createForDecl(loc, TD, /*DC*/ nullptr);
23102310
} else {
23112311
E = new (Context) DeclRefExpr(D, loc, /*Implicit=*/false);
23122312
}

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@ namespace {
10431043
// reference.
10441044
if (auto *TD = dyn_cast<TypeDecl>(member)) {
10451045
Type refType = simplifyType(openedType);
1046-
auto ref = TypeExpr::createForDecl(memberLoc, TD, cs.DC, /*isImplicit=*/false);
1046+
auto ref = TypeExpr::createForDecl(memberLoc, TD, cs.DC);
10471047
cs.setType(ref, refType);
10481048
auto *result = new (context) DotSyntaxBaseIgnoredExpr(
10491049
base, dotLoc, ref, refType);

lib/Sema/DerivedConformanceAdditiveArithmetic.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ deriveBodyMathOperator(AbstractFunctionDecl *funcDecl, MathOperator op) {
9393
auto *initDRE =
9494
new (C) DeclRefExpr(memberwiseInitDecl, DeclNameLoc(), /*Implicit*/ true);
9595
initDRE->setFunctionRefKind(FunctionRefKind::SingleApply);
96-
auto *nominalTypeExpr = TypeExpr::createForDecl(DeclNameLoc(), nominal,
97-
funcDecl, /*Implicit*/ true);
96+
auto *nominalTypeExpr = TypeExpr::createImplicitForDecl(
97+
DeclNameLoc(), nominal, funcDecl,
98+
funcDecl->mapTypeIntoContext(nominal->getInterfaceType()));
9899
auto *initExpr = new (C) ConstructorRefCallExpr(initDRE, nominalTypeExpr);
99100

100101
// Get operator protocol requirement.
@@ -223,8 +224,9 @@ deriveBodyPropertyGetter(AbstractFunctionDecl *funcDecl, ProtocolDecl *proto,
223224
new (C) DeclRefExpr(memberwiseInitDecl, DeclNameLoc(), /*Implicit*/ true);
224225
initDRE->setFunctionRefKind(FunctionRefKind::SingleApply);
225226

226-
auto *nominalTypeExpr = TypeExpr::createForDecl(DeclNameLoc(), nominal,
227-
funcDecl, /*Implicit*/ true);
227+
auto *nominalTypeExpr = TypeExpr::createImplicitForDecl(
228+
DeclNameLoc(), nominal, funcDecl,
229+
funcDecl->mapTypeIntoContext(nominal->getInterfaceType()));
228230
auto *initExpr = new (C) ConstructorRefCallExpr(initDRE, nominalTypeExpr);
229231

230232
auto createMemberPropertyExpr = [&](VarDecl *member) -> Expr * {

lib/Sema/DerivedConformanceCodable.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -468,10 +468,9 @@ static CallExpr *createContainerKeyedByCall(ASTContext &C, DeclContext *DC,
468468
paramList);
469469

470470
// CodingKeys.self expr
471-
auto *codingKeysExpr = TypeExpr::createForDecl(DeclNameLoc(),
472-
param,
473-
DC,
474-
/*Implicit=*/true);
471+
auto *codingKeysExpr = TypeExpr::createImplicitForDecl(
472+
DeclNameLoc(), param, param->getDeclContext(),
473+
DC->mapTypeIntoContext(param->getInterfaceType()));
475474
auto *codingKeysMetaTypeExpr = new (C) DotSelfExpr(codingKeysExpr,
476475
SourceLoc(), SourceLoc());
477476

lib/Sema/DerivedConformanceError.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ deriveBodyBridgedNSError_enum_nsErrorDomain(AbstractFunctionDecl *domainDecl,
4242
auto self = domainDecl->getImplicitSelfDecl();
4343

4444
auto selfRef = new (C) DeclRefExpr(self, DeclNameLoc(), /*implicit*/ true);
45-
auto stringType = TypeExpr::createForDecl(DeclNameLoc(), C.getStringDecl(),
46-
domainDecl, /*implicit*/ true);
45+
auto stringType = TypeExpr::createImplicitForDecl(
46+
DeclNameLoc(), C.getStringDecl(), domainDecl,
47+
C.getStringDecl()->getInterfaceType());
4748
auto initReflectingCall =
4849
CallExpr::createImplicit(C, stringType,
4950
{ selfRef }, { C.getIdentifier("reflecting") });

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -550,8 +550,8 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
550550
if (typeContext->getSelfClassDecl())
551551
SelfType = DynamicSelfType::get(SelfType, Context);
552552
SelfType = DC->mapTypeIntoContext(SelfType);
553-
return new (Context) TypeExpr(TypeLoc(new (Context)
554-
FixedTypeRepr(SelfType, Loc)));
553+
return new (Context)
554+
TypeExpr(new (Context) FixedTypeRepr(SelfType, Loc));
555555
}
556556
}
557557

@@ -644,9 +644,14 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
644644
D->getInterfaceType());
645645
}
646646

647-
return TypeExpr::createForDecl(UDRE->getNameLoc(), D,
648-
Lookup[0].getDeclContext(),
649-
UDRE->isImplicit());
647+
auto *LookupDC = Lookup[0].getDeclContext();
648+
if (UDRE->isImplicit()) {
649+
return TypeExpr::createImplicitForDecl(
650+
UDRE->getNameLoc(), D, LookupDC,
651+
LookupDC->mapTypeIntoContext(D->getInterfaceType()));
652+
} else {
653+
return TypeExpr::createForDecl(UDRE->getNameLoc(), D, LookupDC);
654+
}
650655
}
651656

652657
if (AllDeclRefs) {
@@ -715,13 +720,15 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
715720
if (AllMemberRefs) {
716721
Expr *BaseExpr;
717722
if (auto PD = dyn_cast<ProtocolDecl>(Base)) {
718-
BaseExpr = TypeExpr::createForDecl(UDRE->getNameLoc(),
719-
PD->getGenericParams()->getParams().front(),
720-
/*DC*/nullptr,
721-
/*isImplicit=*/true);
723+
auto selfParam = PD->getGenericParams()->getParams().front();
724+
BaseExpr = TypeExpr::createImplicitForDecl(
725+
UDRE->getNameLoc(), selfParam,
726+
/*DC*/ nullptr,
727+
DC->mapTypeIntoContext(selfParam->getInterfaceType()));
722728
} else if (auto NTD = dyn_cast<NominalTypeDecl>(Base)) {
723-
BaseExpr = TypeExpr::createForDecl(UDRE->getNameLoc(), NTD, BaseDC,
724-
/*isImplicit=*/true);
729+
BaseExpr = TypeExpr::createImplicitForDecl(
730+
UDRE->getNameLoc(), NTD, BaseDC,
731+
DC->mapTypeIntoContext(NTD->getInterfaceType()));
725732
} else {
726733
BaseExpr = new (Context) DeclRefExpr(Base, UDRE->getNameLoc(),
727734
/*Implicit=*/true);
@@ -1383,15 +1390,15 @@ TypeExpr *PreCheckExpression::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) {
13831390
if (Name.isSimpleName(getASTContext().Id_Protocol)) {
13841391
auto *NewTypeRepr =
13851392
new (getASTContext()) ProtocolTypeRepr(InnerTypeRepr, NameLoc);
1386-
return new (getASTContext()) TypeExpr(TypeLoc(NewTypeRepr, Type()));
1393+
return new (getASTContext()) TypeExpr(NewTypeRepr);
13871394
}
13881395

13891396
// Fold 'T.Type' into an existential metatype if 'T' is a protocol,
13901397
// or an ordinary metatype otherwise.
13911398
if (Name.isSimpleName(getASTContext().Id_Type)) {
13921399
auto *NewTypeRepr =
13931400
new (getASTContext()) MetatypeTypeRepr(InnerTypeRepr, NameLoc);
1394-
return new (getASTContext()) TypeExpr(TypeLoc(NewTypeRepr, Type()));
1401+
return new (getASTContext()) TypeExpr(NewTypeRepr);
13951402
}
13961403

13971404
// Fold 'T.U' into a nested type.
@@ -1486,7 +1493,7 @@ TypeExpr *PreCheckExpression::simplifyTypeExpr(Expr *E) {
14861493

14871494
auto *NewTypeRepr =
14881495
new (getASTContext()) OptionalTypeRepr(InnerTypeRepr, QuestionLoc);
1489-
return new (getASTContext()) TypeExpr(TypeLoc(NewTypeRepr, Type()));
1496+
return new (getASTContext()) TypeExpr(NewTypeRepr);
14901497
}
14911498

14921499
// Fold T! into an IUO type when T is a TypeExpr.
@@ -1502,7 +1509,7 @@ TypeExpr *PreCheckExpression::simplifyTypeExpr(Expr *E) {
15021509
auto *NewTypeRepr = new (getASTContext())
15031510
ImplicitlyUnwrappedOptionalTypeRepr(InnerTypeRepr,
15041511
FVE->getExclaimLoc());
1505-
return new (getASTContext()) TypeExpr(TypeLoc(NewTypeRepr, Type()));
1512+
return new (getASTContext()) TypeExpr(NewTypeRepr);
15061513
}
15071514

15081515
// Fold (T) into a type T with parens around it.
@@ -1517,7 +1524,7 @@ TypeExpr *PreCheckExpression::simplifyTypeExpr(Expr *E) {
15171524

15181525
auto *NewTypeRepr = TupleTypeRepr::create(getASTContext(), InnerTypeRepr,
15191526
PE->getSourceRange());
1520-
return new (getASTContext()) TypeExpr(TypeLoc(NewTypeRepr, Type()));
1527+
return new (getASTContext()) TypeExpr(NewTypeRepr);
15211528
}
15221529

15231530
// Fold a tuple expr like (T1,T2) into a tuple type (T1,T2).
@@ -1550,7 +1557,7 @@ TypeExpr *PreCheckExpression::simplifyTypeExpr(Expr *E) {
15501557
}
15511558
auto *NewTypeRepr = TupleTypeRepr::create(
15521559
getASTContext(), Elts, TE->getSourceRange(), SourceLoc(), Elts.size());
1553-
return new (getASTContext()) TypeExpr(TypeLoc(NewTypeRepr, Type()));
1560+
return new (getASTContext()) TypeExpr(NewTypeRepr);
15541561
}
15551562

15561563

@@ -1566,7 +1573,7 @@ TypeExpr *PreCheckExpression::simplifyTypeExpr(Expr *E) {
15661573
auto *NewTypeRepr = new (getASTContext())
15671574
ArrayTypeRepr(TyExpr->getTypeRepr(),
15681575
SourceRange(AE->getLBracketLoc(), AE->getRBracketLoc()));
1569-
return new (getASTContext()) TypeExpr(TypeLoc(NewTypeRepr, Type()));
1576+
return new (getASTContext()) TypeExpr(NewTypeRepr);
15701577
}
15711578

15721579
// Fold [K : V] into a dictionary type.
@@ -1607,7 +1614,7 @@ TypeExpr *PreCheckExpression::simplifyTypeExpr(Expr *E) {
16071614
keyTypeRepr, valueTypeRepr,
16081615
/*FIXME:colonLoc=*/SourceLoc(),
16091616
SourceRange(DE->getLBracketLoc(), DE->getRBracketLoc()));
1610-
return new (getASTContext()) TypeExpr(TypeLoc(NewTypeRepr, Type()));
1617+
return new (getASTContext()) TypeExpr(NewTypeRepr);
16111618
}
16121619

16131620
// Reinterpret arrow expr T1 -> T2 as function type.
@@ -1699,7 +1706,7 @@ TypeExpr *PreCheckExpression::simplifyTypeExpr(Expr *E) {
16991706
auto NewTypeRepr = new (ctx)
17001707
FunctionTypeRepr(nullptr, ArgsTypeRepr, AE->getThrowsLoc(),
17011708
AE->getArrowLoc(), ResultTypeRepr);
1702-
return new (ctx) TypeExpr(TypeLoc(NewTypeRepr, Type()));
1709+
return new (ctx) TypeExpr(NewTypeRepr);
17031710
}
17041711

17051712
// Fold 'P & Q' into a composition type
@@ -1751,7 +1758,7 @@ TypeExpr *PreCheckExpression::simplifyTypeExpr(Expr *E) {
17511758
auto CompRepr = CompositionTypeRepr::create(getASTContext(), Types,
17521759
lhsExpr->getStartLoc(),
17531760
binaryExpr->getSourceRange());
1754-
return new (getASTContext()) TypeExpr(TypeLoc(CompRepr, Type()));
1761+
return new (getASTContext()) TypeExpr(CompRepr);
17551762
}
17561763
}
17571764

@@ -1926,38 +1933,35 @@ Expr *PreCheckExpression::simplifyTypeConstructionWithLiteralArg(Expr *E) {
19261933
if (!protocol)
19271934
return nullptr;
19281935

1929-
Type type;
1930-
if (typeExpr->getTypeLoc().wasValidated()) {
1931-
type = typeExpr->getTypeLoc().getType();
1936+
TypeLoc typeLoc;
1937+
if (auto precheckedTy = typeExpr->getInstanceType()) {
1938+
typeLoc = TypeLoc(typeExpr->getTypeRepr(), precheckedTy);
19321939
} else {
19331940
TypeResolutionOptions options(TypeResolverContext::InExpression);
19341941
options |= TypeResolutionFlags::AllowUnboundGenerics;
19351942

1936-
auto &typeLoc = typeExpr->getTypeLoc();
1943+
typeLoc = TypeLoc(typeExpr->getTypeRepr(), Type());
19371944
bool hadError = TypeChecker::validateType(
19381945
getASTContext(), typeLoc, TypeResolution::forContextual(DC), options);
19391946

19401947
if (hadError)
19411948
return nullptr;
1942-
1943-
type = typeLoc.getType();
19441949
}
19451950

1946-
if (!type || !type->getAnyNominal())
1951+
if (!typeLoc.getType() || !typeLoc.getType()->getAnyNominal())
19471952
return nullptr;
19481953

19491954
// Don't bother to convert deprecated selector syntax.
19501955
if (auto selectorTy = getASTContext().getSelectorType()) {
1951-
if (type->isEqual(selectorTy))
1956+
if (typeLoc.getType()->isEqual(selectorTy))
19521957
return nullptr;
19531958
}
19541959

1955-
auto *NTD = type->getAnyNominal();
1960+
auto *NTD = typeLoc.getType()->getAnyNominal();
19561961
SmallVector<ProtocolConformance *, 2> conformances;
19571962
return NTD->lookupConformance(DC->getParentModule(), protocol, conformances)
19581963
? CoerceExpr::forLiteralInit(getASTContext(), argExpr,
1959-
call->getSourceRange(),
1960-
typeExpr->getTypeLoc())
1964+
call->getSourceRange(), typeLoc)
19611965
: nullptr;
19621966
}
19631967

0 commit comments

Comments
 (0)