Skip to content

Strip TypeLoc out of Patterns #32301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 32 additions & 57 deletions include/swift/AST/Pattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include "swift/Basic/LLVM.h"
#include "swift/AST/Type.h"
#include "swift/AST/Types.h"
#include "swift/AST/TypeLoc.h"
#include "swift/AST/TypeAlignments.h"
#include "swift/Basic/InlineBitfield.h"
#include "swift/Basic/OptionSet.h"
Expand All @@ -35,6 +34,7 @@ namespace swift {
class Expr;
enum class CheckedCastKind : unsigned;
class TypeExpr;
class TypeLoc;

/// PatternKind - The classification of different kinds of
/// value-matching pattern.
Expand Down Expand Up @@ -470,19 +470,14 @@ class IsPattern : public Pattern {
CheckedCastKind CastKind;

/// The type being checked for.
TypeLoc CastType;
TypeExpr *CastType;

public:
IsPattern(SourceLoc IsLoc, TypeLoc CastTy,
Pattern *SubPattern,
CheckedCastKind Kind)
: Pattern(PatternKind::Is),
IsLoc(IsLoc),
SubPattern(SubPattern),
CastKind(Kind),
CastType(CastTy) {
assert(IsLoc.isValid() == CastTy.hasLocation());
}
IsPattern(SourceLoc IsLoc, TypeExpr *CastTy, Pattern *SubPattern,
CheckedCastKind Kind);

static IsPattern *createImplicit(ASTContext &Ctx, Type castTy,
Pattern *SubPattern, CheckedCastKind Kind);

CheckedCastKind getCastKind() const { return CastKind; }
void setCastKind(CheckedCastKind kind) { CastKind = kind; }
Expand All @@ -493,16 +488,11 @@ class IsPattern : public Pattern {
void setSubPattern(Pattern *p) { SubPattern = p; }

SourceLoc getLoc() const { return IsLoc; }
SourceRange getSourceRange() const {
SourceLoc beginLoc =
SubPattern ? SubPattern->getSourceRange().Start : IsLoc;
SourceLoc endLoc =
(isImplicit() ? beginLoc : CastType.getSourceRange().End);
return { beginLoc, endLoc };
}
SourceRange getSourceRange() const;

TypeLoc &getCastTypeLoc() { return CastType; }
TypeLoc getCastTypeLoc() const { return CastType; }
void setCastType(Type castTy);
Type getCastType() const;
TypeRepr *getCastTypeRepr() const;

static bool classof(const Pattern *P) {
return P->getKind() == PatternKind::Is;
Expand All @@ -513,35 +503,31 @@ class IsPattern : public Pattern {
/// case, then the value is extracted. If there is a subpattern, it is then
/// matched against the associated value for the case.
class EnumElementPattern : public Pattern {
TypeLoc ParentType;
TypeExpr *ParentType;
SourceLoc DotLoc;
DeclNameLoc NameLoc;
DeclNameRef Name;
PointerUnion<EnumElementDecl *, Expr*> ElementDeclOrUnresolvedOriginalExpr;
Pattern /*nullable*/ *SubPattern;

public:
EnumElementPattern(TypeLoc ParentType, SourceLoc DotLoc, DeclNameLoc NameLoc,
DeclNameRef Name, EnumElementDecl *Element,
Pattern *SubPattern)
: Pattern(PatternKind::EnumElement),
ParentType(ParentType), DotLoc(DotLoc), NameLoc(NameLoc), Name(Name),
ElementDeclOrUnresolvedOriginalExpr(Element),
SubPattern(SubPattern) { }
EnumElementPattern(TypeExpr *ParentType, SourceLoc DotLoc,
DeclNameLoc NameLoc, DeclNameRef Name,
EnumElementDecl *Element, Pattern *SubPattern)
: Pattern(PatternKind::EnumElement), ParentType(ParentType),
DotLoc(DotLoc), NameLoc(NameLoc), Name(Name),
ElementDeclOrUnresolvedOriginalExpr(Element), SubPattern(SubPattern) {
assert(ParentType && "Missing parent type?");
}

/// Create an unresolved EnumElementPattern for a `.foo` pattern relying on
/// contextual type.
EnumElementPattern(SourceLoc DotLoc,
DeclNameLoc NameLoc,
DeclNameRef Name,
Pattern *SubPattern,
Expr *UnresolvedOriginalExpr)
: Pattern(PatternKind::EnumElement),
ParentType(), DotLoc(DotLoc), NameLoc(NameLoc), Name(Name),
ElementDeclOrUnresolvedOriginalExpr(UnresolvedOriginalExpr),
SubPattern(SubPattern) {

}
EnumElementPattern(SourceLoc DotLoc, DeclNameLoc NameLoc, DeclNameRef Name,
Pattern *SubPattern, Expr *UnresolvedOriginalExpr)
: Pattern(PatternKind::EnumElement), ParentType(nullptr), DotLoc(DotLoc),
NameLoc(NameLoc), Name(Name),
ElementDeclOrUnresolvedOriginalExpr(UnresolvedOriginalExpr),
SubPattern(SubPattern) {}

bool hasSubPattern() const { return SubPattern; }

Expand All @@ -553,10 +539,6 @@ class EnumElementPattern : public Pattern {
return SubPattern;
}

bool isParentTypeImplicit() {
return !ParentType.hasLocation();
}

void setSubPattern(Pattern *p) { SubPattern = p; }

DeclNameRef getName() const { return Name; }
Expand All @@ -577,21 +559,14 @@ class EnumElementPattern : public Pattern {

DeclNameLoc getNameLoc() const { return NameLoc; }
SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
SourceLoc getStartLoc() const {
return ParentType.hasLocation() ? ParentType.getSourceRange().Start :
DotLoc.isValid() ? DotLoc
: NameLoc.getBaseNameLoc();
}
SourceLoc getEndLoc() const {
if (SubPattern && SubPattern->getSourceRange().isValid()) {
return SubPattern->getSourceRange().End;
}
return NameLoc.getEndLoc();
}
SourceLoc getStartLoc() const;
SourceLoc getEndLoc() const;
SourceRange getSourceRange() const { return {getStartLoc(), getEndLoc()}; }

TypeLoc &getParentType() { return ParentType; }
TypeLoc getParentType() const { return ParentType; }
TypeRepr *getParentTypeRepr() const;

void setParentType(Type ty);
Type getParentType() const;

static bool classof(const Pattern *P) {
return P->getKind() == PatternKind::EnumElement;
Expand Down
9 changes: 4 additions & 5 deletions lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,17 +479,17 @@ namespace {
void visitTypedPattern(TypedPattern *P) {
printCommon(P, "pattern_typed") << '\n';
printRec(P->getSubPattern());
if (P->getTypeLoc().getTypeRepr()) {
if (auto *repr = P->getTypeRepr()) {
OS << '\n';
printRec(P->getTypeLoc().getTypeRepr());
printRec(repr);
}
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

void visitIsPattern(IsPattern *P) {
printCommon(P, "pattern_is")
<< ' ' << getCheckedCastKindName(P->getCastKind()) << ' ';
P->getCastTypeLoc().getType().print(OS);
P->getCastType().print(OS);
if (auto sub = P->getSubPattern()) {
OS << '\n';
printRec(sub);
Expand All @@ -514,8 +514,7 @@ namespace {
void visitEnumElementPattern(EnumElementPattern *P) {
printCommon(P, "pattern_enum_element");
OS << ' ';
P->getParentType().getType().print(
PrintWithColorRAII(OS, TypeColor).getOS());
P->getParentType().print(PrintWithColorRAII(OS, TypeColor).getOS());
PrintWithColorRAII(OS, IdentifierColor) << '.' << P->getName();
if (P->hasSubPattern()) {
OS << '\n';
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1158,7 +1158,7 @@ void PrintAST::printPattern(const Pattern *pattern) {
case PatternKind::Is: {
auto isa = cast<IsPattern>(pattern);
Printer << tok::kw_is << " ";
isa->getCastTypeLoc().getType().print(Printer, Options);
isa->getCastType().print(Printer, Options);
break;
}

Expand Down
9 changes: 5 additions & 4 deletions lib/AST/ASTWalker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1691,14 +1691,15 @@ Pattern *Traversal::visitIsPattern(IsPattern *P) {
}
}
if (!P->isImplicit())
if (doIt(P->getCastTypeLoc()))
return nullptr;
if (auto *TR = P->getCastTypeRepr())
if (doIt(TR))
return nullptr;
return P;
}

Pattern *Traversal::visitEnumElementPattern(EnumElementPattern *P) {
if (!P->isParentTypeImplicit())
if (doIt(P->getParentType()))
if (auto *TR = P->getParentTypeRepr())
if (doIt(TR))
return nullptr;

if (!P->hasSubPattern())
Expand Down
16 changes: 10 additions & 6 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1860,7 +1860,7 @@ bool PatternBindingDecl::isDefaultInitializable(unsigned i) const {
// If the pattern is typed as optional (or tuples thereof), it is
// default initializable.
if (const auto typedPattern = dyn_cast<TypedPattern>(entry.getPattern())) {
if (const auto typeRepr = typedPattern->getTypeLoc().getTypeRepr()) {
if (const auto typeRepr = typedPattern->getTypeRepr()) {
if (::isDefaultInitializable(typeRepr, ctx))
return true;
} else if (typedPattern->isImplicit()) {
Expand All @@ -1870,11 +1870,15 @@ bool PatternBindingDecl::isDefaultInitializable(unsigned i) const {
//
// All lazy storage is implicitly default initializable, though, because
// lazy backing storage is optional.
if (const auto *varDecl = typedPattern->getSingleVar())
if (const auto *varDecl = typedPattern->getSingleVar()) {
// Lazy storage is never user accessible.
if (!varDecl->isUserAccessible())
if (typedPattern->getTypeLoc().getType()->getOptionalObjectType())
if (!varDecl->isUserAccessible()) {
if (typedPattern->hasType() &&
typedPattern->getType()->getOptionalObjectType()) {
return true;
}
}
}
}
}

Expand Down Expand Up @@ -2841,7 +2845,7 @@ OpaqueReturnTypeRepr *ValueDecl::getOpaqueResultTypeRepr() const {
assert(NP->getDecl() == VD);
(void) NP;

returnRepr = TP->getTypeLoc().getTypeRepr();
returnRepr = TP->getTypeRepr();
}
}
} else {
Expand Down Expand Up @@ -5586,7 +5590,7 @@ SourceRange VarDecl::getTypeSourceRangeForDiagnostics() const {
if (auto *VP = dyn_cast<VarPattern>(Pat))
Pat = VP->getSubPattern();
if (auto *TP = dyn_cast<TypedPattern>(Pat))
if (auto typeRepr = TP->getTypeLoc().getTypeRepr())
if (auto typeRepr = TP->getTypeRepr())
return typeRepr->getSourceRange();

return SourceRange();
Expand Down
65 changes: 65 additions & 0 deletions lib/AST/Pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,37 @@ SourceRange TypedPattern::getSourceRange() const {
PatTypeRepr->getSourceRange().End };
}

IsPattern::IsPattern(SourceLoc IsLoc, TypeExpr *CastTy, Pattern *SubPattern,
CheckedCastKind Kind)
: Pattern(PatternKind::Is), IsLoc(IsLoc), SubPattern(SubPattern),
CastKind(Kind), CastType(CastTy) {
assert(IsLoc.isValid() == CastTy->getLoc().isValid());
}

IsPattern *IsPattern::createImplicit(ASTContext &Ctx, Type castTy,
Pattern *SubPattern,
CheckedCastKind Kind) {
assert(castTy);
auto *CastTE = TypeExpr::createImplicit(castTy, Ctx);
auto *ip = new (Ctx) IsPattern(SourceLoc(), CastTE, SubPattern, Kind);
ip->setImplicit();
return ip;
}

SourceRange IsPattern::getSourceRange() const {
SourceLoc beginLoc = SubPattern ? SubPattern->getSourceRange().Start : IsLoc;
SourceLoc endLoc = (isImplicit() ? beginLoc : CastType->getEndLoc());
return {beginLoc, endLoc};
}

Type IsPattern::getCastType() const { return CastType->getInstanceType(); }
void IsPattern::setCastType(Type type) {
assert(type);
CastType->setType(MetatypeType::get(type));
}

TypeRepr *IsPattern::getCastTypeRepr() const { return CastType->getTypeRepr(); }

/// Construct an ExprPattern.
ExprPattern::ExprPattern(Expr *e, bool isResolved, Expr *matchExpr,
VarDecl *matchVar)
Expand All @@ -449,6 +480,40 @@ ExprPattern::ExprPattern(Expr *e, bool isResolved, Expr *matchExpr,
assert(!matchExpr || e->isImplicit() == matchExpr->isImplicit());
}

SourceLoc EnumElementPattern::getStartLoc() const {
return (ParentType && !ParentType->isImplicit())
? ParentType->getSourceRange().Start
: DotLoc.isValid() ? DotLoc : NameLoc.getBaseNameLoc();
}

SourceLoc EnumElementPattern::getEndLoc() const {
if (SubPattern && SubPattern->getSourceRange().isValid()) {
return SubPattern->getSourceRange().End;
}
return NameLoc.getEndLoc();
}

TypeRepr *EnumElementPattern::getParentTypeRepr() const {
if (!ParentType)
return nullptr;
return ParentType->getTypeRepr();
}

Type EnumElementPattern::getParentType() const {
if (!ParentType)
return Type();
return ParentType->getInstanceType();
}

void EnumElementPattern::setParentType(Type type) {
assert(type);
if (ParentType) {
ParentType->setType(MetatypeType::get(type));
} else {
ParentType = TypeExpr::createImplicit(type, type->getASTContext());
}
}

SourceLoc ExprPattern::getLoc() const {
return getSubExpr()->getLoc();
}
Expand Down
7 changes: 1 addition & 6 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5694,12 +5694,7 @@ Parser::parseDeclVarGetSet(Pattern *pattern, ParseDeclOptions Flags,
if (!PrimaryVar)
return nullptr;

TypeLoc TyLoc;
if (auto *TP = dyn_cast<TypedPattern>(pattern)) {
TyLoc = TP->getTypeLoc();
}

if (!TyLoc.hasLocation()) {
if (!isa<TypedPattern>(pattern)) {
if (accessors.Get || accessors.Set || accessors.Address ||
accessors.MutableAddress) {
SourceLoc locAfterPattern = pattern->getLoc().getAdvancedLoc(
Expand Down
6 changes: 3 additions & 3 deletions lib/Parse/ParsePattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1184,9 +1184,9 @@ ParserResult<Pattern> Parser::parseMatchingPattern(bool isExprBasic) {
ParserResult<TypeRepr> castType = parseType();
if (castType.isNull() || castType.hasCodeCompletion())
return nullptr;
return makeParserResult(new (Context) IsPattern(isLoc, castType.get(),
nullptr,
CheckedCastKind::Unresolved));
auto *CastTE = new (Context) TypeExpr(castType.get());
return makeParserResult(new (Context) IsPattern(
isLoc, CastTE, nullptr, CheckedCastKind::Unresolved));
}

// matching-pattern ::= expr
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,7 @@ copyOrInitValueInto(SILGenFunction &SGF, SILLocation loc,

// Try to perform the cast to the destination type, producing an optional that
// indicates whether we succeeded.
auto destType = OptionalType::get(pattern->getCastTypeLoc().getType());
auto destType = OptionalType::get(pattern->getCastType());

value =
emitConditionalCheckedCast(SGF, loc, value, pattern->getType(), destType,
Expand Down
Loading