Skip to content

Commit 05f8cef

Browse files
authored
Merge pull request #6570 from rudkx/type-accessors-for-exprs
2 parents 5b3cac2 + 36b0739 commit 05f8cef

File tree

4 files changed

+62
-14
lines changed

4 files changed

+62
-14
lines changed

include/swift/AST/Expr.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -538,13 +538,20 @@ class alignas(8) Expr {
538538
///
539539
/// This distinguishes static references to types, like Int, from metatype
540540
/// values, "someTy: Any.Type".
541-
bool isTypeReference() const;
541+
bool isTypeReference(llvm::function_ref<Type(const Expr &)> getType
542+
= [](const Expr &E) -> Type {
543+
return E.getType();
544+
}) const;
542545

543546
/// Determine whether this expression refers to a statically-derived metatype.
544547
///
545548
/// This implies `isTypeReference`, but also requires that the referenced type
546549
/// is not an archetype or dependent type.
547-
bool isStaticallyDerivedMetatype() const;
550+
bool isStaticallyDerivedMetatype(
551+
llvm::function_ref<Type(const Expr &)> getType
552+
= [](const Expr &E) -> Type {
553+
return E.getType();
554+
}) const;
548555

549556
/// isImplicit - Determines whether this expression was implicitly-generated,
550557
/// rather than explicitly written in the AST.
@@ -1324,7 +1331,14 @@ class TypeExpr : public Expr {
13241331

13251332
// The type of a TypeExpr is always a metatype type. Return the instance
13261333
// type, ErrorType if an error, or null if not set yet.
1327-
Type getInstanceType() const;
1334+
Type getInstanceType(llvm::function_ref<bool(const Expr &)> hasType
1335+
= [](const Expr &E) -> bool {
1336+
return !!E.getType();
1337+
},
1338+
llvm::function_ref<Type(const Expr &)> getType
1339+
= [](const Expr &E) -> Type {
1340+
return E.getType();
1341+
}) const;
13281342

13291343
// Create an implicit TypeExpr, which has no location information.
13301344
static TypeExpr *createImplicit(Type Ty, ASTContext &C) {

lib/AST/Expr.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -567,9 +567,10 @@ void Expr::forEachChildExpr(const std::function<Expr*(Expr*)> &callback) {
567567
this->walk(ChildWalker(callback));
568568
}
569569

570-
bool Expr::isTypeReference() const {
570+
bool Expr::
571+
isTypeReference(llvm::function_ref<Type(const Expr &)> getType) const {
571572
// If the result isn't a metatype, there's nothing else to do.
572-
if (!getType()->is<AnyMetatypeType>())
573+
if (!getType(*this)->is<AnyMetatypeType>())
573574
return false;
574575

575576
const Expr *expr = this;
@@ -600,13 +601,14 @@ bool Expr::isTypeReference() const {
600601

601602
}
602603

603-
bool Expr::isStaticallyDerivedMetatype() const {
604+
bool Expr::isStaticallyDerivedMetatype(
605+
llvm::function_ref<Type(const Expr &)> getType) const {
604606
// The type must first be a type reference.
605-
if (!isTypeReference())
607+
if (!isTypeReference(getType))
606608
return false;
607609

608610
// Archetypes are never statically derived.
609-
return !getType()->getAs<AnyMetatypeType>()->getInstanceType()
611+
return !getType(*this)->getAs<AnyMetatypeType>()->getInstanceType()
610612
->is<ArchetypeType>();
611613
}
612614

@@ -1890,14 +1892,16 @@ TypeExpr::TypeExpr(Type Ty)
18901892

18911893
// The type of a TypeExpr is always a metatype type. Return the instance
18921894
// type or null if not set yet.
1893-
Type TypeExpr::getInstanceType() const {
1894-
if (!getType())
1895+
Type TypeExpr::getInstanceType(
1896+
llvm::function_ref<bool(const Expr &)> hasType,
1897+
llvm::function_ref<Type(const Expr &)> getType) const {
1898+
if (!hasType(*this))
18951899
return Type();
18961900

1897-
if (auto metaType = getType()->getAs<MetatypeType>())
1901+
if (auto metaType = getType(*this)->getAs<MetatypeType>())
18981902
return metaType->getInstanceType();
18991903

1900-
return ErrorType::get(getType()->getASTContext());
1904+
return ErrorType::get(getType(*this)->getASTContext());
19011905
}
19021906

19031907

lib/Sema/CSApply.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,20 @@ void ConstraintSystem::propagateLValueAccessKind(Expr *E,
272272
allowOverwrite);
273273
}
274274

275+
bool ConstraintSystem::isTypeReference(Expr *E) {
276+
return E->isTypeReference([&](const Expr &E) -> Type { return getType(&E); });
277+
}
278+
279+
bool ConstraintSystem::isStaticallyDerivedMetatype(Expr *E) {
280+
return E->isStaticallyDerivedMetatype(
281+
[&](const Expr &E) -> Type { return getType(&E); });
282+
}
283+
284+
Type ConstraintSystem::getInstanceType(TypeExpr *E) {
285+
return E->getInstanceType([&](const Expr &E) -> bool { return hasType(&E); },
286+
[&](const Expr &E) -> Type { return getType(&E); });
287+
}
288+
275289
namespace {
276290

277291
/// \brief Rewrites an expression by applying the solution of a constraint
@@ -6478,7 +6492,7 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
64786492

64796493
// If the metatype value isn't a type expression, the user should reference
64806494
// '.init' explicitly, for clarity.
6481-
if (!fn->isTypeReference()) {
6495+
if (!cs.isTypeReference(fn)) {
64826496
cs.TC.diagnose(apply->getArg()->getStartLoc(),
64836497
diag::missing_init_on_metatype_initialization)
64846498
.fixItInsert(apply->getArg()->getStartLoc(), ".init");

lib/Sema/ConstraintSystem.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1774,12 +1774,28 @@ class ConstraintSystem {
17741774
bool isAnyHashableType(Type t);
17751775

17761776
/// Call Expr::propagateLValueAccessKind on the given expression,
1777-
/// using a custom accessor for the type on the expression which
1777+
/// using a custom accessor for the type on the expression that
17781778
/// reads the type from the ConstraintSystem expression type map.
17791779
void propagateLValueAccessKind(Expr *E,
17801780
AccessKind accessKind,
17811781
bool allowOverwrite = false);
17821782

1783+
/// Call Expr::isTypeReference on the given expression, using a
1784+
/// custom accessor for the type on the expression that reads the
1785+
/// type from the ConstraintSystem expression type map.
1786+
bool isTypeReference(Expr *E);
1787+
1788+
/// Call Expr::isIsStaticallyDerivedMetatype on the given
1789+
/// expression, using a custom accessor for the type on the
1790+
/// expression that reads the type from the ConstraintSystem
1791+
/// expression type map.
1792+
bool isStaticallyDerivedMetatype(Expr *E);
1793+
1794+
/// Call Expr::getInstanceType on the given expression, using a
1795+
/// custom accessor for the type on the expression that reads the
1796+
/// type from the ConstraintSystem expression type map.
1797+
Type getInstanceType(TypeExpr *E);
1798+
17831799
private:
17841800
/// Introduce the constraints associated with the given type variable
17851801
/// into the worklist.

0 commit comments

Comments
 (0)