Skip to content

Commit 0c474eb

Browse files
committed
Sema: Move some code from preCheckExpression() pass to static methods on TypeExpr
This is just an NFC refactoring to simplify the pre-check pass a little bit.
1 parent 76a0055 commit 0c474eb

File tree

4 files changed

+133
-75
lines changed

4 files changed

+133
-75
lines changed

include/swift/AST/Expr.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1382,12 +1382,37 @@ class TypeExpr : public Expr {
13821382
static TypeExpr *createImplicitHack(SourceLoc Loc, Type Ty, ASTContext &C);
13831383

13841384

1385-
/// Return a TypeExpr for a TypeDecl and the specified location.
1385+
/// Create a TypeExpr for a TypeDecl at the specified location.
13861386
static TypeExpr *createForDecl(SourceLoc Loc, TypeDecl *D,
13871387
bool isImplicit);
1388+
1389+
/// Create a TypeExpr for a member TypeDecl of the given parent TypeDecl.
1390+
static TypeExpr *createForMemberDecl(SourceLoc ParentNameLoc,
1391+
TypeDecl *Parent,
1392+
SourceLoc NameLoc,
1393+
TypeDecl *Decl);
1394+
1395+
/// Create a TypeExpr for a member TypeDecl of the given parent IdentTypeRepr.
1396+
static TypeExpr *createForMemberDecl(IdentTypeRepr *ParentTR,
1397+
SourceLoc NameLoc,
1398+
TypeDecl *Decl);
1399+
1400+
/// Create a TypeExpr for a generic TypeDecl with the given arguments applied
1401+
/// at the specified location.
13881402
static TypeExpr *createForSpecializedDecl(SourceLoc Loc, TypeDecl *D,
13891403
ArrayRef<TypeRepr*> args,
13901404
SourceRange angleLocs);
1405+
1406+
/// Create a TypeExpr from an IdentTypeRepr with the given arguments applied
1407+
/// at the specified location.
1408+
///
1409+
/// Returns nullptr if the reference cannot be formed, which is a hack due
1410+
/// to limitations in how we model generic typealiases.
1411+
static TypeExpr *createForSpecializedDecl(IdentTypeRepr *ParentTR,
1412+
ArrayRef<TypeRepr*> Args,
1413+
SourceRange AngleLocs,
1414+
ASTContext &C);
1415+
13911416
TypeLoc &getTypeLoc() { return Info; }
13921417
TypeLoc getTypeLoc() const { return Info; }
13931418
TypeRepr *getTypeRepr() const { return Info.getTypeRepr(); }

lib/AST/Expr.cpp

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1959,7 +1959,6 @@ Type TypeExpr::getInstanceType(
19591959
}
19601960

19611961

1962-
/// Return a TypeExpr for a simple identifier and the specified location.
19631962
TypeExpr *TypeExpr::createForDecl(SourceLoc Loc, TypeDecl *Decl,
19641963
bool isImplicit) {
19651964
ASTContext &C = Decl->getASTContext();
@@ -1972,6 +1971,52 @@ TypeExpr *TypeExpr::createForDecl(SourceLoc Loc, TypeDecl *Decl,
19721971
return result;
19731972
}
19741973

1974+
TypeExpr *TypeExpr::createForMemberDecl(SourceLoc ParentNameLoc,
1975+
TypeDecl *Parent,
1976+
SourceLoc NameLoc,
1977+
TypeDecl *Decl) {
1978+
ASTContext &C = Decl->getASTContext();
1979+
assert(ParentNameLoc.isValid());
1980+
assert(NameLoc.isValid());
1981+
1982+
// Create a new list of components.
1983+
SmallVector<ComponentIdentTypeRepr *, 2> Components;
1984+
1985+
// The first component is the parent type.
1986+
auto *ParentComp = new (C) SimpleIdentTypeRepr(ParentNameLoc,
1987+
Parent->getName());
1988+
ParentComp->setValue(Parent);
1989+
Components.push_back(ParentComp);
1990+
1991+
// The second component is the member we just found.
1992+
auto *NewComp = new (C) SimpleIdentTypeRepr(NameLoc,
1993+
Decl->getName());
1994+
NewComp->setValue(Decl);
1995+
Components.push_back(NewComp);
1996+
1997+
auto *NewTypeRepr = IdentTypeRepr::create(C, Components);
1998+
return new (C) TypeExpr(TypeLoc(NewTypeRepr, Type()));
1999+
}
2000+
2001+
TypeExpr *TypeExpr::createForMemberDecl(IdentTypeRepr *ParentTR,
2002+
SourceLoc NameLoc,
2003+
TypeDecl *Decl) {
2004+
ASTContext &C = Decl->getASTContext();
2005+
2006+
// Create a new list of components.
2007+
SmallVector<ComponentIdentTypeRepr *, 2> Components;
2008+
for (auto *Component : ParentTR->getComponentRange())
2009+
Components.push_back(Component);
2010+
2011+
// Add a new component for the member we just found.
2012+
auto *NewComp = new (C) SimpleIdentTypeRepr(NameLoc, Decl->getName());
2013+
NewComp->setValue(Decl);
2014+
Components.push_back(NewComp);
2015+
2016+
auto *NewTypeRepr = IdentTypeRepr::create(C, Components);
2017+
return new (C) TypeExpr(TypeLoc(NewTypeRepr, Type()));
2018+
}
2019+
19752020
TypeExpr *TypeExpr::createForSpecializedDecl(SourceLoc Loc, TypeDecl *D,
19762021
ArrayRef<TypeRepr*> args,
19772022
SourceRange AngleLocs) {
@@ -1983,6 +2028,57 @@ TypeExpr *TypeExpr::createForSpecializedDecl(SourceLoc Loc, TypeDecl *D,
19832028
return new (C) TypeExpr(TypeLoc(Repr, Type()));
19842029
}
19852030

2031+
TypeExpr *TypeExpr::createForSpecializedDecl(IdentTypeRepr *ParentTR,
2032+
ArrayRef<TypeRepr*> Args,
2033+
SourceRange AngleLocs,
2034+
ASTContext &C) {
2035+
// Create a new list of components.
2036+
SmallVector<ComponentIdentTypeRepr *, 2> components;
2037+
for (auto *component : ParentTR->getComponentRange()) {
2038+
components.push_back(component);
2039+
}
2040+
2041+
auto *last = components.back();
2042+
components.pop_back();
2043+
2044+
if (isa<SimpleIdentTypeRepr>(last) &&
2045+
last->getBoundDecl()) {
2046+
if (isa<TypeAliasDecl>(last->getBoundDecl())) {
2047+
// If any of our parent types are unbound, bail out and let
2048+
// the constraint solver can infer generic parameters for them.
2049+
//
2050+
// This is because a type like GenericClass.GenericAlias<Int>
2051+
// cannot be represented directly.
2052+
//
2053+
// This also means that [GenericClass.GenericAlias<Int>]()
2054+
// won't parse correctly, whereas if we fully specialize
2055+
// GenericClass, it does.
2056+
//
2057+
// FIXME: Once we can model generic typealiases properly, rip
2058+
// this out.
2059+
for (auto *component : components) {
2060+
auto *componentDecl = dyn_cast_or_null<GenericTypeDecl>(
2061+
component->getBoundDecl());
2062+
2063+
if (isa<SimpleIdentTypeRepr>(component) &&
2064+
componentDecl &&
2065+
componentDecl->isGeneric())
2066+
return nullptr;
2067+
}
2068+
}
2069+
2070+
auto *genericComp = new (C) GenericIdentTypeRepr(
2071+
last->getIdLoc(), last->getIdentifier(),
2072+
Args, AngleLocs);
2073+
genericComp->setValue(last->getBoundDecl());
2074+
components.push_back(genericComp);
2075+
2076+
auto *genericRepr = IdentTypeRepr::create(C, components);
2077+
return new (C) TypeExpr(TypeLoc(genericRepr, Type()));
2078+
}
2079+
2080+
return nullptr;
2081+
}
19862082

19872083
// Create an implicit TypeExpr, with location information even though it
19882084
// shouldn't have one. This is presently used to work around other location

lib/Sema/CSGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1537,7 +1537,7 @@ namespace {
15371537
if (BoundGenericType *bgt
15381538
= meta->getInstanceType()->getAs<BoundGenericType>()) {
15391539
ArrayRef<Type> typeVars = bgt->getGenericArgs();
1540-
ArrayRef<TypeLoc> specializations = expr->getUnresolvedParams();
1540+
MutableArrayRef<TypeLoc> specializations = expr->getUnresolvedParams();
15411541

15421542
// If we have too many generic arguments, complain.
15431543
if (specializations.size() > typeVars.size()) {

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 9 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,22 +1060,9 @@ TypeExpr *PreCheckExpression::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) {
10601060
// If there is no nested type with this name, we have a lookup of
10611061
// a non-type member, so leave the expression as-is.
10621062
if (Result.size() == 1) {
1063-
// Create a new list of components.
1064-
SmallVector<ComponentIdentTypeRepr *, 2> Components;
1065-
1066-
// The first component is the parent type.
1067-
auto *ParentComp = new (TC.Context) SimpleIdentTypeRepr(
1068-
DRE->getNameLoc().getBaseNameLoc(), TD->getName());
1069-
ParentComp->setValue(TD);
1070-
Components.push_back(ParentComp);
1071-
1072-
// The second component is the member we just found.
1073-
auto *NewComp = new (TC.Context) SimpleIdentTypeRepr(NameLoc, Name);
1074-
NewComp->setValue(Result.front().first);
1075-
Components.push_back(NewComp);
1076-
1077-
auto *NewTypeRepr = IdentTypeRepr::create(TC.Context, Components);
1078-
return new (TC.Context) TypeExpr(TypeLoc(NewTypeRepr, Type()));
1063+
return TypeExpr::createForMemberDecl(
1064+
DRE->getNameLoc().getBaseNameLoc(), TD,
1065+
NameLoc, Result.front().first);
10791066
}
10801067
}
10811068

@@ -1146,18 +1133,7 @@ TypeExpr *PreCheckExpression::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) {
11461133
BaseTy->hasUnboundGenericType())
11471134
return nullptr;
11481135

1149-
// Create a new list of components.
1150-
SmallVector<ComponentIdentTypeRepr *, 2> Components;
1151-
for (auto *Component : ITR->getComponentRange())
1152-
Components.push_back(Component);
1153-
1154-
// Add a new component for the member we just found.
1155-
auto *NewComp = new (TC.Context) SimpleIdentTypeRepr(NameLoc, Name);
1156-
NewComp->setValue(NewDecl);
1157-
Components.push_back(NewComp);
1158-
1159-
auto *NewTypeRepr = IdentTypeRepr::create(TC.Context, Components);
1160-
return new (TC.Context) TypeExpr(TypeLoc(NewTypeRepr, Type()));
1136+
return TypeExpr::createForMemberDecl(ITR, NameLoc, NewDecl);
11611137
}
11621138
}
11631139
}
@@ -1190,50 +1166,11 @@ TypeExpr *PreCheckExpression::simplifyUnresolvedSpecializeExpr(
11901166
// Or a TypeExpr that we already resolved.
11911167
if (auto *te = dyn_cast<TypeExpr>(us->getSubExpr())) {
11921168
if (auto *ITR = dyn_cast_or_null<IdentTypeRepr>(te->getTypeRepr())) {
1193-
// Create a new list of components.
1194-
SmallVector<ComponentIdentTypeRepr *, 2> components;
1195-
for (auto *component : ITR->getComponentRange()) {
1196-
components.push_back(component);
1197-
}
1198-
1199-
auto *last = components.back();
1200-
components.pop_back();
1201-
1202-
if (isa<SimpleIdentTypeRepr>(last) &&
1203-
last->getBoundDecl()) {
1204-
if (isa<TypeAliasDecl>(last->getBoundDecl())) {
1205-
// If any of our parent types are unbound, bail out and let
1206-
// the constraint solver can infer generic parameters for them.
1207-
//
1208-
// This is because a type like GenericClass.GenericAlias<Int>
1209-
// cannot be represented directly.
1210-
//
1211-
// This also means that [GenericClass.GenericAlias<Int>]()
1212-
// won't parse correctly, whereas if we fully specialize
1213-
// GenericClass, it does.
1214-
//
1215-
// FIXME: Once we can model generic typealiases properly, rip
1216-
// this out.
1217-
for (auto *component : components) {
1218-
auto *componentDecl = dyn_cast_or_null<GenericTypeDecl>(
1219-
component->getBoundDecl());
1220-
1221-
if (isa<SimpleIdentTypeRepr>(component) &&
1222-
componentDecl &&
1223-
componentDecl->isGeneric())
1224-
return nullptr;
1225-
}
1226-
}
1227-
1228-
auto *genericComp = new (TC.Context) GenericIdentTypeRepr(
1229-
last->getIdLoc(), last->getIdentifier(),
1230-
TC.Context.AllocateCopy(genericArgs), angleRange);
1231-
genericComp->setValue(last->getBoundDecl());
1232-
components.push_back(genericComp);
1233-
1234-
auto *genericRepr = IdentTypeRepr::create(TC.Context, components);
1235-
return new (TC.Context) TypeExpr(TypeLoc(genericRepr, Type()));
1236-
}
1169+
return TypeExpr::createForSpecializedDecl(
1170+
ITR,
1171+
TC.Context.AllocateCopy(genericArgs),
1172+
angleRange,
1173+
TC.Context);
12371174
}
12381175
}
12391176

0 commit comments

Comments
 (0)