[AST] Drop const qualifier from {get/set}Type callbacks

This commit is contained in:
Pavel Yaskevich
2020-04-28 11:49:10 -07:00
parent bd09d0c776
commit a483b344ee
5 changed files with 145 additions and 154 deletions

View File

@@ -475,22 +475,24 @@ public:
/// ///
/// This distinguishes static references to types, like Int, from metatype /// This distinguishes static references to types, like Int, from metatype
/// values, "someTy: Any.Type". /// values, "someTy: Any.Type".
bool isTypeReference(llvm::function_ref<Type(const Expr *)> getType = bool isTypeReference(
[](const Expr *E) -> Type { return E->getType(); }, llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
llvm::function_ref<Decl *(const Expr *)> getDecl = return E->getType();
[](const Expr *E) -> Decl * { },
return nullptr; llvm::function_ref<Decl *(Expr *)> getDecl = [](Expr *E) -> Decl * {
}) const; return nullptr;
}) const;
/// Determine whether this expression refers to a statically-derived metatype. /// Determine whether this expression refers to a statically-derived metatype.
/// ///
/// This implies `isTypeReference`, but also requires that the referenced type /// This implies `isTypeReference`, but also requires that the referenced type
/// is not an archetype or dependent type. /// is not an archetype or dependent type.
bool isStaticallyDerivedMetatype( bool isStaticallyDerivedMetatype(
llvm::function_ref<Type(const Expr *)> getType = llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
[](const Expr *E) -> Type { return E->getType(); }, return E->getType();
llvm::function_ref<bool(const Expr *)> isTypeReference = },
[](const Expr *E) { return E->isTypeReference(); }) const; llvm::function_ref<bool(Expr *)> isTypeReference =
[](Expr *E) { return E->isTypeReference(); }) const;
/// isImplicit - Determines whether this expression was implicitly-generated, /// isImplicit - Determines whether this expression was implicitly-generated,
/// rather than explicitly written in the AST. /// rather than explicitly written in the AST.
@@ -538,11 +540,12 @@ public:
SWIFT_DEBUG_DUMP; SWIFT_DEBUG_DUMP;
void dump(raw_ostream &OS, unsigned Indent = 0) const; void dump(raw_ostream &OS, unsigned Indent = 0) const;
void dump(raw_ostream &OS, llvm::function_ref<Type(const Expr *)> getType, void dump(raw_ostream &OS, llvm::function_ref<Type(Expr *)> getType,
llvm::function_ref<Type(const TypeLoc &)> getTypeOfTypeLoc, llvm::function_ref<Type(TypeLoc &)> getTypeOfTypeLoc,
llvm::function_ref<Type(const KeyPathExpr *E, unsigned index)> getTypeOfKeyPathComponent, llvm::function_ref<Type(KeyPathExpr *E, unsigned index)>
getTypeOfKeyPathComponent,
unsigned Indent = 0) const; unsigned Indent = 0) const;
void print(ASTPrinter &Printer, const PrintOptions &Opts) const; void print(ASTPrinter &Printer, const PrintOptions &Opts) const;
// Only allow allocation of Exprs using the allocator in ASTContext // Only allow allocation of Exprs using the allocator in ASTContext
@@ -1183,9 +1186,9 @@ public:
/// ///
/// Note: prefer to use the second entry point, which separates out /// Note: prefer to use the second entry point, which separates out
/// arguments/labels/etc. /// arguments/labels/etc.
static ObjectLiteralExpr * static ObjectLiteralExpr *create(ASTContext &ctx, SourceLoc poundLoc,
create(ASTContext &ctx, SourceLoc poundLoc, LiteralKind kind, Expr *arg, LiteralKind kind, Expr *arg, bool implicit,
bool implicit, llvm::function_ref<Type(const Expr *)> getType); llvm::function_ref<Type(Expr *)> getType);
/// Create a new object literal expression. /// Create a new object literal expression.
static ObjectLiteralExpr *create(ASTContext &ctx, SourceLoc poundLoc, static ObjectLiteralExpr *create(ASTContext &ctx, SourceLoc poundLoc,
@@ -1778,11 +1781,12 @@ public:
/// ///
/// Note: do not create new callers to this entry point; use the entry point /// Note: do not create new callers to this entry point; use the entry point
/// that takes separate index arguments. /// that takes separate index arguments.
static DynamicSubscriptExpr * static DynamicSubscriptExpr *create(
create(ASTContext &ctx, Expr *base, Expr *index, ConcreteDeclRef decl, ASTContext &ctx, Expr *base, Expr *index, ConcreteDeclRef decl,
bool implicit, bool implicit,
llvm::function_ref<Type(const Expr *)> getType = llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
[](const Expr *E) -> Type { return E->getType(); }); return E->getType();
});
/// getIndex - Retrieve the index of the subscript expression, i.e., the /// getIndex - Retrieve the index of the subscript expression, i.e., the
/// "offset" into the base value. /// "offset" into the base value.
@@ -2355,12 +2359,13 @@ public:
/// ///
/// Note: do not create new callers to this entry point; use the entry point /// Note: do not create new callers to this entry point; use the entry point
/// that takes separate index arguments. /// that takes separate index arguments.
static SubscriptExpr * static SubscriptExpr *create(
create(ASTContext &ctx, Expr *base, Expr *index, ASTContext &ctx, Expr *base, Expr *index,
ConcreteDeclRef decl = ConcreteDeclRef(), bool implicit = false, ConcreteDeclRef decl = ConcreteDeclRef(), bool implicit = false,
AccessSemantics semantics = AccessSemantics::Ordinary, AccessSemantics semantics = AccessSemantics::Ordinary,
llvm::function_ref<Type(const Expr *)> getType = llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
[](const Expr *E) -> Type { return E->getType(); }); return E->getType();
});
/// Create a new subscript. /// Create a new subscript.
static SubscriptExpr *create(ASTContext &ctx, Expr *base, static SubscriptExpr *create(ASTContext &ctx, Expr *base,
@@ -3599,10 +3604,8 @@ public:
enum : unsigned { InvalidDiscriminator = 0xFFFF }; enum : unsigned { InvalidDiscriminator = 0xFFFF };
/// Retrieve the result type of this closure. /// Retrieve the result type of this closure.
Type getResultType(llvm::function_ref<Type(const Expr *)> getType = Type getResultType(llvm::function_ref<Type(Expr *)> getType =
[](const Expr *E) -> Type { [](Expr *E) -> Type { return E->getType(); }) const;
return E->getType();
}) const;
/// Return whether this closure is throwing when fully applied. /// Return whether this closure is throwing when fully applied.
bool isBodyThrowing() const; bool isBodyThrowing() const;
@@ -4263,12 +4266,13 @@ public:
/// Create a new call expression. /// Create a new call expression.
/// ///
/// Note: prefer to use the entry points that separate out the arguments. /// Note: prefer to use the entry points that separate out the arguments.
static CallExpr * static CallExpr *create(
create(ASTContext &ctx, Expr *fn, Expr *arg, ArrayRef<Identifier> argLabels, ASTContext &ctx, Expr *fn, Expr *arg, ArrayRef<Identifier> argLabels,
ArrayRef<SourceLoc> argLabelLocs, bool hasTrailingClosure, ArrayRef<SourceLoc> argLabelLocs, bool hasTrailingClosure, bool implicit,
bool implicit, Type type = Type(), Type type = Type(),
llvm::function_ref<Type(const Expr *)> getType = llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
[](const Expr *E) -> Type { return E->getType(); }); return E->getType();
});
/// Create a new implicit call expression without any source-location /// Create a new implicit call expression without any source-location
/// information. /// information.
@@ -4277,11 +4281,12 @@ public:
/// \param args The call arguments, not including a trailing closure (if any). /// \param args The call arguments, not including a trailing closure (if any).
/// \param argLabels The argument labels, whose size must equal args.size(), /// \param argLabels The argument labels, whose size must equal args.size(),
/// or which must be empty. /// or which must be empty.
static CallExpr * static CallExpr *createImplicit(
createImplicit(ASTContext &ctx, Expr *fn, ArrayRef<Expr *> args, ASTContext &ctx, Expr *fn, ArrayRef<Expr *> args,
ArrayRef<Identifier> argLabels, ArrayRef<Identifier> argLabels,
llvm::function_ref<Type(const Expr *)> getType = llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
[](const Expr *E) -> Type { return E->getType(); }) { return E->getType();
}) {
return create(ctx, fn, SourceLoc(), args, argLabels, { }, SourceLoc(), return create(ctx, fn, SourceLoc(), args, argLabels, { }, SourceLoc(),
/*trailingClosure=*/nullptr, /*implicit=*/true, getType); /*trailingClosure=*/nullptr, /*implicit=*/true, getType);
} }
@@ -4295,12 +4300,13 @@ public:
/// \param argLabelLocs The locations of the argument labels, whose size must /// \param argLabelLocs The locations of the argument labels, whose size must
/// equal args.size() or which must be empty. /// equal args.size() or which must be empty.
/// \param trailingClosure The trailing closure, if any. /// \param trailingClosure The trailing closure, if any.
static CallExpr * static CallExpr *create(
create(ASTContext &ctx, Expr *fn, SourceLoc lParenLoc, ArrayRef<Expr *> args, ASTContext &ctx, Expr *fn, SourceLoc lParenLoc, ArrayRef<Expr *> args,
ArrayRef<Identifier> argLabels, ArrayRef<SourceLoc> argLabelLocs, ArrayRef<Identifier> argLabels, ArrayRef<SourceLoc> argLabelLocs,
SourceLoc rParenLoc, Expr *trailingClosure, bool implicit, SourceLoc rParenLoc, Expr *trailingClosure, bool implicit,
llvm::function_ref<Type(const Expr *)> getType = llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
[](const Expr *E) -> Type { return E->getType(); }); return E->getType();
});
SourceLoc getStartLoc() const { SourceLoc getStartLoc() const {
SourceLoc fnLoc = getFn()->getStartLoc(); SourceLoc fnLoc = getFn()->getStartLoc();
@@ -5622,18 +5628,15 @@ inline const SourceLoc *CollectionExpr::getTrailingSourceLocs() const {
/// ///
/// \param argLabelLocs The argument label locations, which might be updated by /// \param argLabelLocs The argument label locations, which might be updated by
/// this function. /// this function.
Expr *packSingleArgument(ASTContext &ctx, SourceLoc lParenLoc, Expr *packSingleArgument(
ArrayRef<Expr *> args, ASTContext &ctx, SourceLoc lParenLoc, ArrayRef<Expr *> args,
ArrayRef<Identifier> &argLabels, ArrayRef<Identifier> &argLabels, ArrayRef<SourceLoc> &argLabelLocs,
ArrayRef<SourceLoc> &argLabelLocs, SourceLoc rParenLoc, Expr *trailingClosure, bool implicit,
SourceLoc rParenLoc, SmallVectorImpl<Identifier> &argLabelsScratch,
Expr *trailingClosure, bool implicit, SmallVectorImpl<SourceLoc> &argLabelLocsScratch,
SmallVectorImpl<Identifier> &argLabelsScratch, llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
SmallVectorImpl<SourceLoc> &argLabelLocsScratch, return E->getType();
llvm::function_ref<Type(const Expr *)> getType = });
[](const Expr *E) -> Type {
return E->getType();
});
void simple_display(llvm::raw_ostream &out, const ClosureExpr *CE); void simple_display(llvm::raw_ostream &out, const ClosureExpr *CE);
void simple_display(llvm::raw_ostream &out, const DefaultArgumentExpr *expr); void simple_display(llvm::raw_ostream &out, const DefaultArgumentExpr *expr);

View File

@@ -1774,15 +1774,16 @@ namespace {
class PrintExpr : public ExprVisitor<PrintExpr> { class PrintExpr : public ExprVisitor<PrintExpr> {
public: public:
raw_ostream &OS; raw_ostream &OS;
llvm::function_ref<Type(const Expr *)> GetTypeOfExpr; llvm::function_ref<Type(Expr *)> GetTypeOfExpr;
llvm::function_ref<Type(const TypeLoc &)> GetTypeOfTypeLoc; llvm::function_ref<Type(TypeLoc &)> GetTypeOfTypeLoc;
llvm::function_ref<Type(const KeyPathExpr *E, unsigned index)> GetTypeOfKeyPathComponent; llvm::function_ref<Type(KeyPathExpr *E, unsigned index)>
GetTypeOfKeyPathComponent;
unsigned Indent; unsigned Indent;
PrintExpr(raw_ostream &os, PrintExpr(raw_ostream &os, llvm::function_ref<Type(Expr *)> getTypeOfExpr,
llvm::function_ref<Type(const Expr *)> getTypeOfExpr, llvm::function_ref<Type(TypeLoc &)> getTypeOfTypeLoc,
llvm::function_ref<Type(const TypeLoc &)> getTypeOfTypeLoc, llvm::function_ref<Type(KeyPathExpr *E, unsigned index)>
llvm::function_ref<Type(const KeyPathExpr *E, unsigned index)> getTypeOfKeyPathComponent, getTypeOfKeyPathComponent,
unsigned indent) unsigned indent)
: OS(os), GetTypeOfExpr(getTypeOfExpr), : OS(os), GetTypeOfExpr(getTypeOfExpr),
GetTypeOfTypeLoc(getTypeOfTypeLoc), GetTypeOfTypeLoc(getTypeOfTypeLoc),
@@ -2864,21 +2865,19 @@ void Expr::dump() const {
llvm::errs() << "\n"; llvm::errs() << "\n";
} }
void Expr::dump(raw_ostream &OS, void Expr::dump(raw_ostream &OS, llvm::function_ref<Type(Expr *)> getTypeOfExpr,
llvm::function_ref<Type(const Expr *)> getTypeOfExpr, llvm::function_ref<Type(TypeLoc &)> getTypeOfTypeLoc,
llvm::function_ref<Type(const TypeLoc &)> getTypeOfTypeLoc, llvm::function_ref<Type(KeyPathExpr *E, unsigned index)>
llvm::function_ref<Type(const KeyPathExpr *E, unsigned index)> getTypeOfKeyPathComponent, getTypeOfKeyPathComponent,
unsigned Indent) const { unsigned Indent) const {
PrintExpr(OS, getTypeOfExpr, getTypeOfTypeLoc, getTypeOfKeyPathComponent, Indent) PrintExpr(OS, getTypeOfExpr, getTypeOfTypeLoc, getTypeOfKeyPathComponent, Indent)
.visit(const_cast<Expr *>(this)); .visit(const_cast<Expr *>(this));
} }
void Expr::dump(raw_ostream &OS, unsigned Indent) const { void Expr::dump(raw_ostream &OS, unsigned Indent) const {
auto getTypeOfExpr = [](const Expr *E) -> Type { return E->getType(); }; auto getTypeOfExpr = [](Expr *E) -> Type { return E->getType(); };
auto getTypeOfTypeLoc = [](const TypeLoc &TL) -> Type { auto getTypeOfTypeLoc = [](TypeLoc &TL) -> Type { return TL.getType(); };
return TL.getType(); auto getTypeOfKeyPathComponent = [](KeyPathExpr *E, unsigned index) -> Type {
};
auto getTypeOfKeyPathComponent = [](const KeyPathExpr *E, unsigned index) -> Type {
return E->getComponents()[index].getComponentType(); return E->getComponents()[index].getComponentType();
}; };
dump(OS, getTypeOfExpr, getTypeOfTypeLoc, getTypeOfKeyPathComponent, Indent); dump(OS, getTypeOfExpr, getTypeOfTypeLoc, getTypeOfKeyPathComponent, Indent);

View File

@@ -458,14 +458,14 @@ void Expr::forEachChildExpr(llvm::function_ref<Expr *(Expr *)> callback) {
this->walk(ChildWalker(callback)); this->walk(ChildWalker(callback));
} }
bool Expr::isTypeReference( bool Expr::isTypeReference(llvm::function_ref<Type(Expr *)> getType,
llvm::function_ref<Type(const Expr *)> getType, llvm::function_ref<Decl *(Expr *)> getDecl) const {
llvm::function_ref<Decl *(const Expr *)> getDecl) const { Expr *expr = const_cast<Expr *>(this);
// If the result isn't a metatype, there's nothing else to do. // If the result isn't a metatype, there's nothing else to do.
if (!getType(this)->is<AnyMetatypeType>()) if (!getType(expr)->is<AnyMetatypeType>())
return false; return false;
const Expr *expr = this;
do { do {
// Skip syntax. // Skip syntax.
expr = expr->getSemanticsProvidingExpr(); expr = expr->getSemanticsProvidingExpr();
@@ -504,15 +504,15 @@ bool Expr::isTypeReference(
} }
bool Expr::isStaticallyDerivedMetatype( bool Expr::isStaticallyDerivedMetatype(
llvm::function_ref<Type(const Expr *)> getType, llvm::function_ref<Type(Expr *)> getType,
llvm::function_ref<bool(const Expr *)> isTypeReference) const { llvm::function_ref<bool(Expr *)> isTypeReference) const {
// The expression must first be a type reference. // The expression must first be a type reference.
if (!isTypeReference(this)) if (!isTypeReference(const_cast<Expr *>(this)))
return false; return false;
auto type = getType(this) auto type = getType(const_cast<Expr *>(this))
->castTo<AnyMetatypeType>() ->castTo<AnyMetatypeType>()
->getInstanceType(); ->getInstanceType();
// Archetypes are never statically derived. // Archetypes are never statically derived.
if (type->is<ArchetypeType>()) if (type->is<ArchetypeType>())
@@ -883,7 +883,7 @@ static ArrayRef<Identifier> getArgumentLabelsFromArgument(
Expr *arg, SmallVectorImpl<Identifier> &scratch, Expr *arg, SmallVectorImpl<Identifier> &scratch,
SmallVectorImpl<SourceLoc> *sourceLocs = nullptr, SmallVectorImpl<SourceLoc> *sourceLocs = nullptr,
bool *hasTrailingClosure = nullptr, bool *hasTrailingClosure = nullptr,
llvm::function_ref<Type(const Expr *)> getType = [](const Expr *E) -> Type { llvm::function_ref<Type(Expr *)> getType = [](Expr *E) -> Type {
return E->getType(); return E->getType();
}) { }) {
if (sourceLocs) sourceLocs->clear(); if (sourceLocs) sourceLocs->clear();
@@ -934,13 +934,13 @@ static ArrayRef<Identifier> getArgumentLabelsFromArgument(
// FIXME: Shouldn't get here. // FIXME: Shouldn't get here.
scratch.clear(); scratch.clear();
scratch.push_back(Identifier()); scratch.push_back(Identifier());
return scratch; return scratch;
} }
/// Compute the type of an argument to a call (or call-like) AST /// Compute the type of an argument to a call (or call-like) AST
static void static void
computeSingleArgumentType(ASTContext &ctx, Expr *arg, bool implicit, computeSingleArgumentType(ASTContext &ctx, Expr *arg, bool implicit,
llvm::function_ref<Type(const Expr *)> getType) { llvm::function_ref<Type(Expr *)> getType) {
// Propagate 'implicit' to the argument. // Propagate 'implicit' to the argument.
if (implicit) { if (implicit) {
arg->setImplicit(true); arg->setImplicit(true);
@@ -970,16 +970,15 @@ computeSingleArgumentType(ASTContext &ctx, Expr *arg, bool implicit,
arg->setType(TupleType::get(typeElements, ctx)); arg->setType(TupleType::get(typeElements, ctx));
} }
Expr * Expr *swift::packSingleArgument(ASTContext &ctx, SourceLoc lParenLoc,
swift::packSingleArgument(ASTContext &ctx, SourceLoc lParenLoc, ArrayRef<Expr *> args,
ArrayRef<Expr *> args, ArrayRef<Identifier> &argLabels,
ArrayRef<Identifier> &argLabels, ArrayRef<SourceLoc> &argLabelLocs,
ArrayRef<SourceLoc> &argLabelLocs, SourceLoc rParenLoc, Expr *trailingClosure,
SourceLoc rParenLoc, bool implicit,
Expr *trailingClosure, bool implicit, SmallVectorImpl<Identifier> &argLabelsScratch,
SmallVectorImpl<Identifier> &argLabelsScratch, SmallVectorImpl<SourceLoc> &argLabelLocsScratch,
SmallVectorImpl<SourceLoc> &argLabelLocsScratch, llvm::function_ref<Type(Expr *)> getType) {
llvm::function_ref<Type(const Expr *)> getType) {
// Clear out our scratch space. // Clear out our scratch space.
argLabelsScratch.clear(); argLabelsScratch.clear();
argLabelLocsScratch.clear(); argLabelLocsScratch.clear();
@@ -1081,7 +1080,7 @@ ObjectLiteralExpr::ObjectLiteralExpr(SourceLoc PoundLoc, LiteralKind LitKind,
ObjectLiteralExpr * ObjectLiteralExpr *
ObjectLiteralExpr::create(ASTContext &ctx, SourceLoc poundLoc, LiteralKind kind, ObjectLiteralExpr::create(ASTContext &ctx, SourceLoc poundLoc, LiteralKind kind,
Expr *arg, bool implicit, Expr *arg, bool implicit,
llvm::function_ref<Type(const Expr *)> getType) { llvm::function_ref<Type(Expr *)> getType) {
// Inspect the argument to dig out the argument labels, their location, and // Inspect the argument to dig out the argument labels, their location, and
// whether there is a trailing closure. // whether there is a trailing closure.
SmallVector<Identifier, 4> argLabelsScratch; SmallVector<Identifier, 4> argLabelsScratch;
@@ -1459,11 +1458,10 @@ SubscriptExpr::SubscriptExpr(Expr *base, Expr *index,
initializeCallArguments(argLabels, argLabelLocs, hasTrailingClosure); initializeCallArguments(argLabels, argLabelLocs, hasTrailingClosure);
} }
SubscriptExpr * SubscriptExpr *SubscriptExpr::create(ASTContext &ctx, Expr *base, Expr *index,
SubscriptExpr::create(ASTContext &ctx, Expr *base, Expr *index, ConcreteDeclRef decl, bool implicit,
ConcreteDeclRef decl, bool implicit, AccessSemantics semantics,
AccessSemantics semantics, llvm::function_ref<Type(Expr *)> getType) {
llvm::function_ref<Type(const Expr *)> getType) {
// Inspect the argument to dig out the argument labels, their location, and // Inspect the argument to dig out the argument labels, their location, and
// whether there is a trailing closure. // whether there is a trailing closure.
SmallVector<Identifier, 4> argLabelsScratch; SmallVector<Identifier, 4> argLabelsScratch;
@@ -1528,7 +1526,7 @@ DynamicSubscriptExpr::DynamicSubscriptExpr(Expr *base, Expr *index,
DynamicSubscriptExpr * DynamicSubscriptExpr *
DynamicSubscriptExpr::create(ASTContext &ctx, Expr *base, Expr *index, DynamicSubscriptExpr::create(ASTContext &ctx, Expr *base, Expr *index,
ConcreteDeclRef decl, bool implicit, ConcreteDeclRef decl, bool implicit,
llvm::function_ref<Type(const Expr *)> getType) { llvm::function_ref<Type(Expr *)> getType) {
// Inspect the argument to dig out the argument labels, their location, and // Inspect the argument to dig out the argument labels, their location, and
// whether there is a trailing closure. // whether there is a trailing closure.
SmallVector<Identifier, 4> argLabelsScratch; SmallVector<Identifier, 4> argLabelsScratch;
@@ -1652,7 +1650,7 @@ CallExpr *CallExpr::create(ASTContext &ctx, Expr *fn, Expr *arg,
ArrayRef<Identifier> argLabels, ArrayRef<Identifier> argLabels,
ArrayRef<SourceLoc> argLabelLocs, ArrayRef<SourceLoc> argLabelLocs,
bool hasTrailingClosure, bool implicit, Type type, bool hasTrailingClosure, bool implicit, Type type,
llvm::function_ref<Type(const Expr *)> getType) { llvm::function_ref<Type(Expr *)> getType) {
SmallVector<Identifier, 4> argLabelsScratch; SmallVector<Identifier, 4> argLabelsScratch;
SmallVector<SourceLoc, 4> argLabelLocsScratch; SmallVector<SourceLoc, 4> argLabelLocsScratch;
if (argLabels.empty()) { if (argLabels.empty()) {
@@ -1678,7 +1676,7 @@ CallExpr *CallExpr::create(ASTContext &ctx, Expr *fn, SourceLoc lParenLoc,
ArrayRef<SourceLoc> argLabelLocs, ArrayRef<SourceLoc> argLabelLocs,
SourceLoc rParenLoc, Expr *trailingClosure, SourceLoc rParenLoc, Expr *trailingClosure,
bool implicit, bool implicit,
llvm::function_ref<Type(const Expr *)> getType) { llvm::function_ref<Type(Expr *)> getType) {
SmallVector<Identifier, 4> argLabelsScratch; SmallVector<Identifier, 4> argLabelsScratch;
SmallVector<SourceLoc, 4> argLabelLocsScratch; SmallVector<SourceLoc, 4> argLabelLocsScratch;
Expr *arg = packSingleArgument(ctx, lParenLoc, args, argLabels, argLabelLocs, Expr *arg = packSingleArgument(ctx, lParenLoc, args, argLabels, argLabelLocs,
@@ -1787,11 +1785,12 @@ void AbstractClosureExpr::setParameterList(ParameterList *P) {
} }
Type AbstractClosureExpr::getResultType( Type AbstractClosureExpr::getResultType(
llvm::function_ref<Type(const Expr *)> getType) const { llvm::function_ref<Type(Expr *)> getType) const {
if (getType(this)->hasError()) auto *E = const_cast<AbstractClosureExpr *>(this);
return getType(this); if (getType(E)->hasError())
return getType(E);
return getType(this)->castTo<FunctionType>()->getResult(); return getType(E)->castTo<FunctionType>()->getResult();
} }
bool AbstractClosureExpr::isBodyThrowing() const { bool AbstractClosureExpr::isBodyThrowing() const {

View File

@@ -114,7 +114,7 @@ ConstraintLocator *Solution::getCalleeLocator(ConstraintLocator *locator,
auto &cs = getConstraintSystem(); auto &cs = getConstraintSystem();
return cs.getCalleeLocator( return cs.getCalleeLocator(
locator, lookThroughApply, locator, lookThroughApply,
[&](const Expr *expr) -> Type { return getType(expr); }, [&](Expr *expr) -> Type { return getType(expr); },
[&](Type type) -> Type { return simplifyType(type)->getRValueType(); }, [&](Type type) -> Type { return simplifyType(type)->getRValueType(); },
[&](ConstraintLocator *locator) -> Optional<SelectedOverload> { [&](ConstraintLocator *locator) -> Optional<SelectedOverload> {
return getOverloadChoiceIfAvailable(locator); return getOverloadChoiceIfAvailable(locator);
@@ -122,7 +122,7 @@ ConstraintLocator *Solution::getCalleeLocator(ConstraintLocator *locator,
} }
ConstraintLocator * ConstraintLocator *
Solution::getConstraintLocator(TypedNode anchor, Solution::getConstraintLocator(ASTNode anchor,
ArrayRef<LocatorPathElt> path) const { ArrayRef<LocatorPathElt> path) const {
auto &cs = getConstraintSystem(); auto &cs = getConstraintSystem();
return cs.getConstraintLocator(anchor, path); return cs.getConstraintLocator(anchor, path);
@@ -153,10 +153,10 @@ getImplicitMemberReferenceAccessSemantics(Expr *base, VarDecl *member,
/// This extends functionality of `Expr::isTypeReference` with /// This extends functionality of `Expr::isTypeReference` with
/// support for `UnresolvedDotExpr` and `UnresolvedMemberExpr`. /// support for `UnresolvedDotExpr` and `UnresolvedMemberExpr`.
/// This method could be used on not yet fully type-checked AST. /// This method could be used on not yet fully type-checked AST.
bool ConstraintSystem::isTypeReference(const Expr *E) { bool ConstraintSystem::isTypeReference(Expr *E) {
return E->isTypeReference( return E->isTypeReference(
[&](const Expr *E) -> Type { return simplifyType(getType(E)); }, [&](Expr *E) -> Type { return simplifyType(getType(E)); },
[&](const Expr *E) -> Decl * { [&](Expr *E) -> Decl * {
if (auto *UDE = dyn_cast<UnresolvedDotExpr>(E)) { if (auto *UDE = dyn_cast<UnresolvedDotExpr>(E)) {
return findResolvedMemberRef( return findResolvedMemberRef(
getConstraintLocator(UDE, ConstraintLocator::Member)); getConstraintLocator(UDE, ConstraintLocator::Member));
@@ -175,13 +175,13 @@ bool ConstraintSystem::isTypeReference(const Expr *E) {
}); });
} }
bool ConstraintSystem::isStaticallyDerivedMetatype(const Expr *E) { bool ConstraintSystem::isStaticallyDerivedMetatype(Expr *E) {
return E->isStaticallyDerivedMetatype( return E->isStaticallyDerivedMetatype(
[&](const Expr *E) -> Type { return simplifyType(getType(E)); }, [&](Expr *E) -> Type { return simplifyType(getType(E)); },
[&](const Expr *E) -> bool { return isTypeReference(E); }); [&](Expr *E) -> bool { return isTypeReference(E); });
} }
Type ConstraintSystem::getInstanceType(const TypeExpr *E) { Type ConstraintSystem::getInstanceType(TypeExpr *E) {
if (!hasType(E)) if (!hasType(E))
return Type(); return Type();
@@ -192,7 +192,7 @@ Type ConstraintSystem::getInstanceType(const TypeExpr *E) {
} }
Type ConstraintSystem::getResultType(const AbstractClosureExpr *E) { Type ConstraintSystem::getResultType(const AbstractClosureExpr *E) {
return E->getResultType([&](const Expr *E) -> Type { return getType(E); }); return E->getResultType([&](Expr *E) -> Type { return getType(E); });
} }
static bool buildObjCKeyPathString(KeyPathExpr *E, static bool buildObjCKeyPathString(KeyPathExpr *E,
@@ -882,9 +882,9 @@ namespace {
// the base is implicit or not. This helps maintain some invariants around // the base is implicit or not. This helps maintain some invariants around
// source ranges. // source ranges.
if (selfParamRef->isImplicit()) { if (selfParamRef->isImplicit()) {
selfCall = selfCall =
CallExpr::createImplicit(context, ref, selfOpenedRef, { }, CallExpr::createImplicit(context, ref, selfOpenedRef, {},
[&](const Expr *E) { return cs.getType(E); }); [&](Expr *E) { return cs.getType(E); });
selfCall->setType(refTy->getResult()); selfCall->setType(refTy->getResult());
cs.cacheType(selfCall); cs.cacheType(selfCall);
@@ -1778,9 +1778,7 @@ namespace {
if (!index) if (!index)
return nullptr; return nullptr;
auto getType = [&](const Expr *E) -> Type { auto getType = [&](Expr *E) -> Type { return cs.getType(E); };
return cs.getType(E);
};
// Handle dynamic lookup. // Handle dynamic lookup.
if (choice.getKind() == OverloadChoiceKind::DeclViaDynamic || if (choice.getKind() == OverloadChoiceKind::DeclViaDynamic ||
@@ -1968,7 +1966,7 @@ namespace {
anchor = SubscriptExpr::create( anchor = SubscriptExpr::create(
ctx, dotExpr, origComponent.getIndexExpr(), ConcreteDeclRef(), ctx, dotExpr, origComponent.getIndexExpr(), ConcreteDeclRef(),
/*implicit=*/true, AccessSemantics::Ordinary, /*implicit=*/true, AccessSemantics::Ordinary,
[&](const Expr *expr) { return simplifyType(cs.getType(expr)); }); [&](Expr *expr) { return simplifyType(cs.getType(expr)); });
} else { } else {
return nullptr; return nullptr;
} }
@@ -2742,9 +2740,7 @@ namespace {
if (!result) if (!result)
return nullptr; return nullptr;
auto getType = [&](const Expr *E) -> Type { auto getType = [&](Expr *E) -> Type { return cs.getType(E); };
return cs.getType(E);
};
// If there was an argument, apply it. // If there was an argument, apply it.
if (auto arg = expr->getArgument()) { if (auto arg = expr->getArgument()) {
@@ -3242,7 +3238,7 @@ namespace {
// solver was allowed to return free or unresolved types, which can // solver was allowed to return free or unresolved types, which can
// happen while running diagnostics on one of the expressions. // happen while running diagnostics on one of the expressions.
if (!overload) { if (!overload) {
const auto *base = expr->getBase(); auto *base = expr->getBase();
auto &de = cs.getASTContext().Diags; auto &de = cs.getASTContext().Diags;
auto baseType = cs.getType(base); auto baseType = cs.getType(base);
@@ -7237,9 +7233,7 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
OpaqueValueExpr(apply->getFn()->getSourceRange(), Type()); OpaqueValueExpr(apply->getFn()->getSourceRange(), Type());
cs.setType(escapable, escapableParams[0].getOldType()); cs.setType(escapable, escapableParams[0].getOldType());
auto getType = [&](const Expr *E) -> Type { auto getType = [&](Expr *E) -> Type { return cs.getType(E); };
return cs.getType(E);
};
auto callSubExpr = CallExpr::createImplicit(ctx, body, auto callSubExpr = CallExpr::createImplicit(ctx, body,
{escapable}, {}, getType); {escapable}, {}, getType);
@@ -7294,10 +7288,8 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
auto opaqueValue = auto opaqueValue =
new (ctx) OpaqueValueExpr(apply->getSourceRange(), openedTy); new (ctx) OpaqueValueExpr(apply->getSourceRange(), openedTy);
cs.setType(opaqueValue, openedTy); cs.setType(opaqueValue, openedTy);
auto getType = [&](const Expr *E) -> Type { auto getType = [&](Expr *E) -> Type { return cs.getType(E); };
return cs.getType(E);
};
auto callSubExpr = CallExpr::createImplicit(ctx, body, {opaqueValue}, {}, getType); auto callSubExpr = CallExpr::createImplicit(ctx, body, {opaqueValue}, {}, getType);
cs.cacheSubExprTypes(callSubExpr); cs.cacheSubExprTypes(callSubExpr);
@@ -7809,7 +7801,7 @@ namespace {
explicit CompareExprSourceLocs(SourceManager &sourceMgr) explicit CompareExprSourceLocs(SourceManager &sourceMgr)
: sourceMgr(sourceMgr) { } : sourceMgr(sourceMgr) { }
bool operator()(TypedNode lhs, TypedNode rhs) const { bool operator()(ASTNode lhs, ASTNode rhs) const {
if (static_cast<bool>(lhs) != static_cast<bool>(rhs)) { if (static_cast<bool>(lhs) != static_cast<bool>(rhs)) {
return static_cast<bool>(lhs); return static_cast<bool>(lhs);
} }
@@ -7829,15 +7821,14 @@ namespace {
/// able to emit an error message, or false if none of the fixits worked out. /// able to emit an error message, or false if none of the fixits worked out.
bool ConstraintSystem::applySolutionFixes(const Solution &solution) { bool ConstraintSystem::applySolutionFixes(const Solution &solution) {
/// Collect the fixes on a per-expression basis. /// Collect the fixes on a per-expression basis.
llvm::SmallDenseMap<TypedNode, SmallVector<ConstraintFix *, 4>> llvm::SmallDenseMap<ASTNode, SmallVector<ConstraintFix *, 4>> fixesPerAnchor;
fixesPerAnchor;
for (auto *fix : solution.Fixes) { for (auto *fix : solution.Fixes) {
fixesPerAnchor[fix->getAnchor()].push_back(fix); fixesPerAnchor[fix->getAnchor()].push_back(fix);
} }
// Collect all of the expressions that have fixes, and sort them by // Collect all of the expressions that have fixes, and sort them by
// source ordering. // source ordering.
SmallVector<TypedNode, 4> orderedAnchors; SmallVector<ASTNode, 4> orderedAnchors;
for (const auto &fix : fixesPerAnchor) { for (const auto &fix : fixesPerAnchor) {
orderedAnchors.push_back(fix.getFirst()); orderedAnchors.push_back(fix.getFirst());
} }
@@ -8416,7 +8407,7 @@ ProtocolConformanceRef Solution::resolveConformance(
return ProtocolConformanceRef::forInvalid(); return ProtocolConformanceRef::forInvalid();
} }
Type Solution::getType(TypedNode node) const { Type Solution::getType(ASTNode node) const {
auto result = nodeTypes.find(node); auto result = nodeTypes.find(node);
if (result != nodeTypes.end()) if (result != nodeTypes.end())
return result->second; return result->second;

View File

@@ -188,7 +188,7 @@ Expr *ConstraintLocatorBuilder::trySimplifyToExpr() const {
// Locators are not guaranteed to have an anchor // Locators are not guaranteed to have an anchor
// if constraint system is used to verify generic // if constraint system is used to verify generic
// requirements. // requirements.
if (!anchor.is<const Expr *>()) if (!anchor.is<Expr *>())
return nullptr; return nullptr;
ArrayRef<LocatorPathElt> path = pathBuffer; ArrayRef<LocatorPathElt> path = pathBuffer;
@@ -3021,18 +3021,17 @@ void ConstraintSystem::dump(Expr *E) const {
} }
void ConstraintSystem::print(raw_ostream &out, Expr *E) const { void ConstraintSystem::print(raw_ostream &out, Expr *E) const {
auto getTypeOfExpr = [&](const Expr *E) -> Type { auto getTypeOfExpr = [&](Expr *E) -> Type {
if (hasType(E)) if (hasType(E))
return getType(E); return getType(E);
return Type(); return Type();
}; };
auto getTypeOfTypeLoc = [&](const TypeLoc &TL) -> Type { auto getTypeOfTypeLoc = [&](TypeLoc &TL) -> Type {
if (hasType(TL)) if (hasType(TL))
return getType(TL); return getType(TL);
return Type(); return Type();
}; };
auto getTypeOfKeyPathComponent = auto getTypeOfKeyPathComponent = [&](KeyPathExpr *KP, unsigned I) -> Type {
[&](const KeyPathExpr *KP, unsigned I) -> Type {
if (hasType(KP, I)) if (hasType(KP, I))
return getType(KP, I); return getType(KP, I);
return Type(); return Type();