From fc9070c072d806e96a5142bfa75e89dab0785203 Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Wed, 10 Jun 2020 12:05:28 -0700 Subject: [PATCH 1/3] Strip TypeLoc from IsPattern --- include/swift/AST/Pattern.h | 30 ++++++------------ lib/AST/ASTDumper.cpp | 2 +- lib/AST/ASTPrinter.cpp | 2 +- lib/AST/ASTWalker.cpp | 5 +-- lib/AST/Pattern.cpp | 30 ++++++++++++++++++ lib/Parse/ParsePattern.cpp | 6 ++-- lib/SILGen/SILGenDecl.cpp | 2 +- lib/SILGen/SILGenPattern.cpp | 7 ++--- lib/Sema/CSGen.cpp | 10 +++--- lib/Sema/TypeCheckPattern.cpp | 59 +++++++++++++++++------------------ 10 files changed, 85 insertions(+), 68 deletions(-) diff --git a/include/swift/AST/Pattern.h b/include/swift/AST/Pattern.h index 7b11705882afb..51baeacded90c 100644 --- a/include/swift/AST/Pattern.h +++ b/include/swift/AST/Pattern.h @@ -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; } @@ -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; diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 2e3c555a7e646..1769bbce13e47 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -489,7 +489,7 @@ namespace { 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); diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 8084deab1cb23..dab5dd0bd6716 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -1158,7 +1158,7 @@ void PrintAST::printPattern(const Pattern *pattern) { case PatternKind::Is: { auto isa = cast(pattern); Printer << tok::kw_is << " "; - isa->getCastTypeLoc().getType().print(Printer, Options); + isa->getCastType().print(Printer, Options); break; } diff --git a/lib/AST/ASTWalker.cpp b/lib/AST/ASTWalker.cpp index b00602418e3f1..8732a3e548b9d 100644 --- a/lib/AST/ASTWalker.cpp +++ b/lib/AST/ASTWalker.cpp @@ -1691,8 +1691,9 @@ 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; } diff --git a/lib/AST/Pattern.cpp b/lib/AST/Pattern.cpp index a6385bc564991..a506dd02da5f2 100644 --- a/lib/AST/Pattern.cpp +++ b/lib/AST/Pattern.cpp @@ -441,6 +441,36 @@ 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) { + 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) diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp index c1631d2de3c4a..bf95b7375d0e7 100644 --- a/lib/Parse/ParsePattern.cpp +++ b/lib/Parse/ParsePattern.cpp @@ -1184,9 +1184,9 @@ ParserResult Parser::parseMatchingPattern(bool isExprBasic) { ParserResult 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 diff --git a/lib/SILGen/SILGenDecl.cpp b/lib/SILGen/SILGenDecl.cpp index ace1e9e71c359..20c4f77afeaa3 100644 --- a/lib/SILGen/SILGenDecl.cpp +++ b/lib/SILGen/SILGenDecl.cpp @@ -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, diff --git a/lib/SILGen/SILGenPattern.cpp b/lib/SILGen/SILGenPattern.cpp index ecacd2536ca7d..7bf50937aff6e 100644 --- a/lib/SILGen/SILGenPattern.cpp +++ b/lib/SILGen/SILGenPattern.cpp @@ -81,7 +81,7 @@ static void dumpPattern(const Pattern *p, llvm::raw_ostream &os) { } case PatternKind::Is: os << "is "; - cast(p)->getCastTypeLoc().getType()->print(os); + cast(p)->getCastType()->print(os); break; case PatternKind::EnumElement: { auto eep = cast(p); @@ -286,8 +286,7 @@ static Pattern *getSimilarSpecializingPattern(Pattern *p, Pattern *first) { auto pIs = cast(p); // 'is' patterns are only similar to matches to the same type. if (auto firstIs = dyn_cast(first)) { - if (firstIs->getCastTypeLoc().getType() - ->isEqual(pIs->getCastTypeLoc().getType())) + if (firstIs->getCastType()->isEqual(pIs->getCastType())) return p; } return nullptr; @@ -1581,7 +1580,7 @@ emitTupleDispatch(ArrayRef rows, ConsumableManagedValue src, } static CanType getTargetType(const RowToSpecialize &row) { - auto type = cast(row.Pattern)->getCastTypeLoc().getType(); + auto type = cast(row.Pattern)->getCastType(); return type->getCanonicalType(); } diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index dd38eb631021b..67afbdfdb513f 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -2524,7 +2524,7 @@ namespace { auto isPattern = cast(pattern); Type castType = resolveTypeReferenceInExpression( - isPattern->getCastTypeLoc(), TypeResolverContext::InExpression); + isPattern->getCastTypeRepr(), TypeResolverContext::InExpression); if (!castType) return Type(); @@ -2749,10 +2749,10 @@ namespace { // of is-patterns applied to an irrefutable pattern. pattern = pattern->getSemanticsProvidingPattern(); while (auto isp = dyn_cast(pattern)) { - if (TypeChecker::validateType( - isp->getCastTypeLoc(), - TypeResolution::forContextual( - CS.DC, TypeResolverContext::InExpression))) { + Type castType = TypeResolution::forContextual( + CS.DC, TypeResolverContext::InExpression) + .resolveType(isp->getCastTypeRepr()); + if (!castType) { return false; } diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp index 2dca6ae545e11..aed7bedfdb90b 100644 --- a/lib/Sema/TypeCheckPattern.cpp +++ b/lib/Sema/TypeCheckPattern.cpp @@ -361,10 +361,16 @@ class ResolvePattern : public ASTVisitorgetCastTypeRepr(), cast->getCastType()); Pattern *subPattern = getSubExprPattern(E->getElement(0)); - return new (Context) IsPattern(cast->getLoc(), tyLoc, subPattern, - CheckedCastKind::Unresolved); + if (cast->isImplicit()) { + return IsPattern::createImplicit(Context, cast->getCastType(), subPattern, + CheckedCastKind::Unresolved); + } + auto *TE = new (Context) TypeExpr(cast->getCastTypeRepr()); + if (auto castTy = cast->getType()) + TE->setType(MetatypeType::get(castTy)); + return new (Context) + IsPattern(cast->getLoc(), TE, subPattern, CheckedCastKind::Unresolved); } // Convert a paren expr to a pattern if it contains a pattern. @@ -614,12 +620,10 @@ Pattern *TypeChecker::resolvePattern(Pattern *P, DeclContext *DC, if (auto *TE = dyn_cast(EP->getSubExpr())) { Context.Diags.diagnose(TE->getStartLoc(), diag::type_pattern_missing_is) .fixItInsert(TE->getStartLoc(), "is "); - - P = new (Context) IsPattern(TE->getStartLoc(), - TypeLoc(TE->getTypeRepr(), - TE->getInstanceType()), - /*subpattern*/nullptr, - CheckedCastKind::Unresolved); + + P = new (Context) + IsPattern(TE->getStartLoc(), TE, + /*subpattern*/ nullptr, CheckedCastKind::Unresolved); } // Look through a TypedPattern if present. @@ -1222,11 +1226,11 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, // Type-check the type parameter. TypeResolutionOptions paramOptions(TypeResolverContext::InExpression); - TypeResolution resolution = TypeResolution::forContextual(dc, paramOptions); - if (validateType(IP->getCastTypeLoc(), resolution)) + auto castType = TypeResolution::forContextual(dc, paramOptions) + .resolveType(IP->getCastTypeRepr()); + if (!castType || castType->hasError()) return nullptr; - - auto castType = IP->getCastTypeLoc().getType(); + IP->setCastType(castType); // Determine whether we have an imbalance in the number of optionals. SmallVector inputTypeOptionals; @@ -1254,15 +1258,11 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, pattern.forSubPattern(P, /*retainTopLevle=*/true), type, options); } - CheckedCastKind castKind - = TypeChecker::typeCheckCheckedCast(type, IP->getCastTypeLoc().getType(), - type->hasError() - ? CheckedCastContextKind::None - : CheckedCastContextKind::IsPattern, - dc, - IP->getLoc(), - nullptr, - IP->getCastTypeLoc().getSourceRange()); + CheckedCastKind castKind = TypeChecker::typeCheckCheckedCast( + type, IP->getCastType(), + type->hasError() ? CheckedCastContextKind::None + : CheckedCastContextKind::IsPattern, + dc, IP->getLoc(), nullptr, IP->getCastTypeRepr()->getSourceRange()); switch (castKind) { case CheckedCastKind::Unresolved: return nullptr; @@ -1272,8 +1272,7 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, // it is "useful" because it is providing a different type to the // sub-pattern. If this is an 'is' pattern or an 'as' pattern where the // types are the same, then produce a warning. - if (!IP->getSubPattern() || - type->isEqual(IP->getCastTypeLoc().getType())) { + if (!IP->getSubPattern() || type->isEqual(IP->getCastType())) { diags.diagnose(IP->getLoc(), diag::isa_is_always_true, IP->getSubPattern() ? "as" : "is"); } @@ -1286,7 +1285,7 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, case CheckedCastKind::SetDowncast: { diags.diagnose(IP->getLoc(), diag::isa_collection_downcast_pattern_value_unimplemented, - IP->getCastTypeLoc().getType()); + IP->getCastType()); return P; } @@ -1300,8 +1299,8 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, if (Pattern *sub = IP->getSubPattern()) { sub = coercePatternToType( pattern.forSubPattern(sub, /*retainTopLevel=*/false), - IP->getCastTypeLoc().getType(), - subOptions|TypeResolutionFlags::FromNonInferredPattern); + IP->getCastType(), + subOptions | TypeResolutionFlags::FromNonInferredPattern); if (!sub) return nullptr; @@ -1528,10 +1527,8 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, // If we needed a cast, wrap the pattern in a cast pattern. if (castKind) { - auto isPattern = new (Context) IsPattern(SourceLoc(), - TypeLoc::withoutLoc(enumTy), - EEP, *castKind); - isPattern->setImplicit(); + auto isPattern = + IsPattern::createImplicit(Context, enumTy, EEP, *castKind); isPattern->setType(type); P = isPattern; } From 2371e5c260200886dbaed8442bcc5d820cf031a9 Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Wed, 10 Jun 2020 13:15:10 -0700 Subject: [PATCH 2/3] Strip TypeLoc from EnumElementPattern --- include/swift/AST/Pattern.h | 59 +++++-------- lib/AST/ASTDumper.cpp | 3 +- lib/AST/ASTWalker.cpp | 4 +- lib/AST/Pattern.cpp | 35 ++++++++ lib/Sema/CSGen.cpp | 17 ++-- lib/Sema/DerivedConformanceCodingKey.cpp | 4 +- lib/Sema/DerivedConformanceComparable.cpp | 16 ++-- .../DerivedConformanceEquatableHashable.cpp | 29 +++---- .../DerivedConformanceRawRepresentable.cpp | 6 +- lib/Sema/DerivedConformances.cpp | 6 +- lib/Sema/TypeCheckPattern.cpp | 86 +++++++++---------- test/Constraints/patterns.swift | 20 ++++- 12 files changed, 159 insertions(+), 126 deletions(-) diff --git a/include/swift/AST/Pattern.h b/include/swift/AST/Pattern.h index 51baeacded90c..a5005df8d7ddf 100644 --- a/include/swift/AST/Pattern.h +++ b/include/swift/AST/Pattern.h @@ -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" @@ -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. @@ -503,7 +503,7 @@ 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; @@ -511,27 +511,23 @@ class EnumElementPattern : public Pattern { 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; } @@ -543,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; } @@ -567,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; diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 1769bbce13e47..e8f68bfe4b95e 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -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'; diff --git a/lib/AST/ASTWalker.cpp b/lib/AST/ASTWalker.cpp index 8732a3e548b9d..4f553432aa766 100644 --- a/lib/AST/ASTWalker.cpp +++ b/lib/AST/ASTWalker.cpp @@ -1698,8 +1698,8 @@ Pattern *Traversal::visitIsPattern(IsPattern *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()) diff --git a/lib/AST/Pattern.cpp b/lib/AST/Pattern.cpp index a506dd02da5f2..97178c4eb9156 100644 --- a/lib/AST/Pattern.cpp +++ b/lib/AST/Pattern.cpp @@ -466,6 +466,7 @@ SourceRange IsPattern::getSourceRange() const { Type IsPattern::getCastType() const { return CastType->getInstanceType(); } void IsPattern::setCastType(Type type) { + assert(type); CastType->setType(MetatypeType::get(type)); } @@ -479,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(); } diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index 67afbdfdb513f..79b8d7ab346f8 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -1481,11 +1481,6 @@ namespace { Type resolveTypeReferenceInExpression(TypeRepr *repr, TypeResolverContext resCtx) { TypeLoc loc(repr); - return resolveTypeReferenceInExpression(loc, resCtx); - } - - Type resolveTypeReferenceInExpression(TypeLoc &loc, - TypeResolverContext resCtx) { TypeResolutionOptions options(resCtx); options |= TypeResolutionFlags::AllowUnboundGenerics; bool hadError = TypeChecker::validateType( @@ -2581,10 +2576,16 @@ namespace { CS.getConstraintLocator(locator), TVO_CanBindToLValue | TVO_CanBindToNoEscape); FunctionRefKind functionRefKind = FunctionRefKind::Compound; - if (!enumPattern->getParentType().isNull()) { + if (enumPattern->getParentType() || enumPattern->getParentTypeRepr()) { // Resolve the parent type. - Type parentType = resolveTypeReferenceInExpression( - enumPattern->getParentType(), TypeResolverContext::InExpression); + Type parentType = [&]() -> Type { + if (auto preTy = enumPattern->getParentType()) { + return preTy; + } + return resolveTypeReferenceInExpression( + enumPattern->getParentTypeRepr(), + TypeResolverContext::InExpression); + }(); if (!parentType) return Type(); diff --git a/lib/Sema/DerivedConformanceCodingKey.cpp b/lib/Sema/DerivedConformanceCodingKey.cpp index 7e06caaffe456..03a5a47335c59 100644 --- a/lib/Sema/DerivedConformanceCodingKey.cpp +++ b/lib/Sema/DerivedConformanceCodingKey.cpp @@ -212,8 +212,8 @@ deriveBodyCodingKey_enum_stringValue(AbstractFunctionDecl *strValDecl, void *) { } else { SmallVector cases; for (auto *elt : elements) { - auto *pat = new (C) EnumElementPattern(TypeLoc::withoutLoc(enumType), - SourceLoc(), DeclNameLoc(), + auto *baseTE = TypeExpr::createImplicit(enumType, C); + auto *pat = new (C) EnumElementPattern(baseTE, SourceLoc(), DeclNameLoc(), DeclNameRef(), elt, nullptr); pat->setImplicit(); diff --git a/lib/Sema/DerivedConformanceComparable.cpp b/lib/Sema/DerivedConformanceComparable.cpp index b43bc32ba7234..d543ffb7314a6 100644 --- a/lib/Sema/DerivedConformanceComparable.cpp +++ b/lib/Sema/DerivedConformanceComparable.cpp @@ -137,20 +137,20 @@ deriveBodyComparable_enum_hasAssociatedValues_lt(AbstractFunctionDecl *ltDecl, v SmallVector lhsPayloadVars; auto lhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(elt, 'l', ltDecl, lhsPayloadVars); - auto lhsElemPat = new (C) EnumElementPattern(TypeLoc::withoutLoc(enumType), - SourceLoc(), DeclNameLoc(), - DeclNameRef(), elt, - lhsSubpattern); + auto *lhsBaseTE = TypeExpr::createImplicit(enumType, C); + auto lhsElemPat = + new (C) EnumElementPattern(lhsBaseTE, SourceLoc(), DeclNameLoc(), + DeclNameRef(), elt, lhsSubpattern); lhsElemPat->setImplicit(); // .(let r0, let r1, ...) SmallVector rhsPayloadVars; auto rhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(elt, 'r', ltDecl, rhsPayloadVars); - auto rhsElemPat = new (C) EnumElementPattern(TypeLoc::withoutLoc(enumType), - SourceLoc(), DeclNameLoc(), - DeclNameRef(), elt, - rhsSubpattern); + auto *rhsBaseTE = TypeExpr::createImplicit(enumType, C); + auto rhsElemPat = + new (C) EnumElementPattern(rhsBaseTE, SourceLoc(), DeclNameLoc(), + DeclNameRef(), elt, rhsSubpattern); rhsElemPat->setImplicit(); auto hasBoundDecls = !lhsPayloadVars.empty(); diff --git a/lib/Sema/DerivedConformanceEquatableHashable.cpp b/lib/Sema/DerivedConformanceEquatableHashable.cpp index c55e9117207ae..dbd323d495fe0 100644 --- a/lib/Sema/DerivedConformanceEquatableHashable.cpp +++ b/lib/Sema/DerivedConformanceEquatableHashable.cpp @@ -259,20 +259,20 @@ deriveBodyEquatable_enum_hasAssociatedValues_eq(AbstractFunctionDecl *eqDecl, SmallVector lhsPayloadVars; auto lhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(elt, 'l', eqDecl, lhsPayloadVars); - auto lhsElemPat = new (C) EnumElementPattern(TypeLoc::withoutLoc(enumType), - SourceLoc(), DeclNameLoc(), - DeclNameRef(), elt, - lhsSubpattern); + auto *lhsBaseTE = TypeExpr::createImplicit(enumType, C); + auto lhsElemPat = + new (C) EnumElementPattern(lhsBaseTE, SourceLoc(), DeclNameLoc(), + DeclNameRef(), elt, lhsSubpattern); lhsElemPat->setImplicit(); // .(let r0, let r1, ...) SmallVector rhsPayloadVars; auto rhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(elt, 'r', eqDecl, rhsPayloadVars); - auto rhsElemPat = new (C) EnumElementPattern(TypeLoc::withoutLoc(enumType), - SourceLoc(), DeclNameLoc(), - DeclNameRef(), elt, - rhsSubpattern); + auto *rhsBaseTE = TypeExpr::createImplicit(enumType, C); + auto rhsElemPat = + new (C) EnumElementPattern(rhsBaseTE, SourceLoc(), DeclNameLoc(), + DeclNameRef(), elt, rhsSubpattern); rhsElemPat->setImplicit(); auto hasBoundDecls = !lhsPayloadVars.empty(); @@ -748,12 +748,12 @@ deriveBodyHashable_enum_hasAssociatedValues_hashInto( // case A, B(Int), C(String, Int) // @derived func hash(into hasher: inout Hasher) { // switch self { - // case A: + // case .A: // hasher.combine(0) - // case B(let a0): + // case .B(let a0): // hasher.combine(1) // hasher.combine(a0) - // case C(let a0, let a1): + // case .C(let a0, let a1): // hasher.combine(2) // hasher.combine(a0) // hasher.combine(a1) @@ -783,10 +783,9 @@ deriveBodyHashable_enum_hasAssociatedValues_hashInto( auto payloadPattern = DerivedConformance::enumElementPayloadSubpattern(elt, 'a', hashIntoDecl, payloadVars); - auto pat = new (C) EnumElementPattern(TypeLoc::withoutLoc(enumType), - SourceLoc(), DeclNameLoc(), - DeclNameRef(elt->getBaseIdentifier()), - elt, payloadPattern); + auto pat = new (C) EnumElementPattern( + TypeExpr::createImplicit(enumType, C), SourceLoc(), DeclNameLoc(), + DeclNameRef(elt->getBaseIdentifier()), elt, payloadPattern); pat->setImplicit(); auto labelItem = CaseLabelItem(pat); diff --git a/lib/Sema/DerivedConformanceRawRepresentable.cpp b/lib/Sema/DerivedConformanceRawRepresentable.cpp index 1a5498e649014..beb22f6af4145 100644 --- a/lib/Sema/DerivedConformanceRawRepresentable.cpp +++ b/lib/Sema/DerivedConformanceRawRepresentable.cpp @@ -108,9 +108,9 @@ deriveBodyRawRepresentable_raw(AbstractFunctionDecl *toRawDecl, void *) { SmallVector cases; for (auto elt : enumDecl->getAllElements()) { - auto pat = new (C) EnumElementPattern(TypeLoc::withoutLoc(enumType), - SourceLoc(), DeclNameLoc(), - DeclNameRef(), elt, nullptr); + auto pat = new (C) + EnumElementPattern(TypeExpr::createImplicit(enumType, C), SourceLoc(), + DeclNameLoc(), DeclNameRef(), elt, nullptr); pat->setImplicit(); auto labelItem = CaseLabelItem(pat); diff --git a/lib/Sema/DerivedConformances.cpp b/lib/Sema/DerivedConformances.cpp index 46f6ad101ce1d..1dc13ba25bea5 100644 --- a/lib/Sema/DerivedConformances.cpp +++ b/lib/Sema/DerivedConformances.cpp @@ -548,9 +548,9 @@ DeclRefExpr *DerivedConformance::convertEnumToIndex(SmallVectorImpl &st SmallVector cases; for (auto elt : enumDecl->getAllElements()) { // generate: case .: - auto pat = new (C) EnumElementPattern(TypeLoc::withoutLoc(enumType), - SourceLoc(), DeclNameLoc(), - DeclNameRef(), elt, nullptr); + auto pat = new (C) + EnumElementPattern(TypeExpr::createImplicit(enumType, C), SourceLoc(), + DeclNameLoc(), DeclNameRef(), elt, nullptr); pat->setImplicit(); pat->setType(enumType); diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp index aed7bedfdb90b..ab3058092a526 100644 --- a/lib/Sema/TypeCheckPattern.cpp +++ b/lib/Sema/TypeCheckPattern.cpp @@ -483,13 +483,13 @@ class ResolvePattern : public ASTVisitorgetName(), ude->getLoc()); if (!referencedElement) return nullptr; - - // Build a TypeRepr from the head of the full path. - TypeLoc loc(repr); - loc.setType(ty); - return new (Context) EnumElementPattern( - loc, ude->getDotLoc(), ude->getNameLoc(), ude->getName(), - referencedElement, nullptr); + + auto *base = + TypeExpr::createForMemberDecl(repr, ude->getNameLoc(), enumDecl); + base->setType(MetatypeType::get(ty)); + return new (Context) + EnumElementPattern(base, ude->getDotLoc(), ude->getNameLoc(), + ude->getName(), referencedElement, nullptr); } // A DeclRef 'E' that refers to an enum element forms an EnumElementPattern. @@ -499,9 +499,10 @@ class ResolvePattern : public ASTVisitorgetParentEnum()->getDeclaredTypeInContext()); - return new (Context) EnumElementPattern(loc, SourceLoc(), de->getNameLoc(), + auto enumTy = elt->getParentEnum()->getDeclaredTypeInContext(); + auto *base = TypeExpr::createImplicit(enumTy, Context); + + return new (Context) EnumElementPattern(base, SourceLoc(), de->getNameLoc(), elt->createNameRef(), elt, nullptr); } Pattern *visitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *ude) { @@ -515,11 +516,11 @@ class ResolvePattern : public ASTVisitorgetLoc())) { auto *enumDecl = referencedElement->getParentEnum(); auto enumTy = enumDecl->getDeclaredTypeInContext(); - TypeLoc loc = TypeLoc::withoutLoc(enumTy); + auto *base = TypeExpr::createImplicit(enumTy, Context); - return new (Context) EnumElementPattern( - loc, SourceLoc(), ude->getNameLoc(), ude->getName(), - referencedElement, nullptr); + return new (Context) + EnumElementPattern(base, SourceLoc(), ude->getNameLoc(), + ude->getName(), referencedElement, nullptr); } @@ -549,7 +550,7 @@ class ResolvePattern : public ASTVisitorgetParentEnum(); - loc = TypeLoc::withoutLoc(enumDecl->getDeclaredTypeInContext()); + baseTE = TypeExpr::createImplicit(enumDecl->getDeclaredTypeInContext(), + Context); } else { TypeResolutionOptions options = None; options |= TypeResolutionFlags::AllowUnboundGenerics; @@ -573,7 +575,8 @@ class ResolvePattern : public ASTVisitor(enumTy->getAnyNominal())) + auto *enumDecl = dyn_cast_or_null(enumTy->getAnyNominal()); + if (!enumDecl) return nullptr; referencedElement @@ -583,18 +586,19 @@ class ResolvePattern : public ASTVisitorgetNameLoc(), enumDecl); + baseTE->setType(MetatypeType::get(enumTy)); } + assert(baseTE && baseTE->getType() && "Didn't initialize base expression?"); assert(!isa(tailComponent) && "should be handled above"); auto *subPattern = getSubExprPattern(ce->getArg()); return new (Context) EnumElementPattern( - loc, SourceLoc(), tailComponent->getNameLoc(), - tailComponent->getNameRef(), referencedElement, - subPattern); + baseTE, SourceLoc(), tailComponent->getNameLoc(), + tailComponent->getNameRef(), referencedElement, subPattern); } }; @@ -1204,11 +1208,10 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, auto EP = cast(P); if (auto *NLE = dyn_cast(EP->getSubExpr())) { auto *NoneEnumElement = Context.getOptionalNoneDecl(); - P = new (Context) EnumElementPattern(TypeLoc::withoutLoc(type), - NLE->getLoc(), - DeclNameLoc(NLE->getLoc()), - NoneEnumElement->createNameRef(), - NoneEnumElement, nullptr); + auto *BaseTE = TypeExpr::createImplicit(type, Context); + P = new (Context) EnumElementPattern( + BaseTE, NLE->getLoc(), DeclNameLoc(NLE->getLoc()), + NoneEnumElement->createNameRef(), NoneEnumElement, nullptr); return TypeChecker::coercePatternToType( pattern.forSubPattern(P, /*retainTopLevel=*/true), type, options); } @@ -1238,24 +1241,25 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, SmallVector castTypeOptionals; castType->lookThroughAllOptionalTypes(castTypeOptionals); - // If we have extra optionals on the input type. Create ".Some" patterns - // wrapping the isa pattern to balance out the optionals. + // If we have extra optionals on the input type. Create ".some" patterns + // wrapping the is pattern to balance out the optionals. int numExtraOptionals = inputTypeOptionals.size()-castTypeOptionals.size(); if (numExtraOptionals > 0) { Pattern *sub = IP; - for (int i = 0; i < numExtraOptionals; ++i) { + auto extraOpts = + llvm::drop_begin(inputTypeOptionals, castTypeOptionals.size()); + for (auto extraOptTy : llvm::reverse(extraOpts)) { auto some = Context.getOptionalDecl()->getUniqueElement(/*hasVal*/true); - sub = new (Context) EnumElementPattern(TypeLoc(), - IP->getStartLoc(), - DeclNameLoc(IP->getEndLoc()), - some->createNameRef(), - nullptr, sub); + auto *base = TypeExpr::createImplicit(extraOptTy, Context); + sub = new (Context) EnumElementPattern( + base, IP->getStartLoc(), DeclNameLoc(IP->getEndLoc()), + some->createNameRef(), nullptr, sub); sub->setImplicit(); } P = sub; return coercePatternToType( - pattern.forSubPattern(P, /*retainTopLevle=*/true), type, options); + pattern.forSubPattern(P, /*retainTopLevel=*/true), type, options); } CheckedCastKind castKind = TypeChecker::typeCheckCheckedCast( @@ -1405,7 +1409,7 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, // coercing to. assert(!EEP->getParentType().isNull() && "enum with resolved element doesn't specify parent type?!"); - auto parentTy = EEP->getParentType().getType(); + auto parentTy = EEP->getParentType(); // If the type matches exactly, use it. if (parentTy->isEqual(type)) { enumTy = type; @@ -1519,12 +1523,8 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, EEP->setElementDecl(elt); EEP->setType(enumTy); - - // Ensure that the type of our TypeLoc is fully resolved. If an unbound - // generic type was spelled in the source (e.g. `case Optional.None:`) this - // will fill in the generic parameters. - EEP->getParentType().setType(enumTy); - + EEP->setParentType(enumTy); + // If we needed a cast, wrap the pattern in a cast pattern. if (castKind) { auto isPattern = diff --git a/test/Constraints/patterns.swift b/test/Constraints/patterns.swift index a3a2de3f5ee24..d0ca8f7582397 100644 --- a/test/Constraints/patterns.swift +++ b/test/Constraints/patterns.swift @@ -486,12 +486,26 @@ func rdar63510989() { } enum E { - case foo(P?) + case single(P?) + case double(P??) + case triple(P???) } func test(e: E) { - if case .foo(_ as Value) = e {} // Ok - if case .foo(let v as Value) = e {} // Ok + if case .single(_ as Value) = e {} // Ok + if case .single(let v as Value) = e {} // Ok + // expected-warning@-1 {{immutable value 'v' was never used; consider replacing with '_' or removing it}} + if case .double(_ as Value) = e {} // Ok + if case .double(let v as Value) = e {} // Ok + // expected-warning@-1 {{immutable value 'v' was never used; consider replacing with '_' or removing it}} + if case .double(let v as Value?) = e {} // Ok + // expected-warning@-1 {{immutable value 'v' was never used; consider replacing with '_' or removing it}} + if case .triple(_ as Value) = e {} // Ok + if case .triple(let v as Value) = e {} // Ok + // expected-warning@-1 {{immutable value 'v' was never used; consider replacing with '_' or removing it}} + if case .triple(let v as Value?) = e {} // Ok + // expected-warning@-1 {{immutable value 'v' was never used; consider replacing with '_' or removing it}} + if case .triple(let v as Value??) = e {} // Ok // expected-warning@-1 {{immutable value 'v' was never used; consider replacing with '_' or removing it}} } } From e1015761fb73c51ccce2536f74b4801a4fb335b5 Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Wed, 10 Jun 2020 14:53:25 -0700 Subject: [PATCH 3/3] [NFC] Reduce usage of TypedPattern::getTypeLoc --- lib/AST/ASTDumper.cpp | 4 +-- lib/AST/Decl.cpp | 16 ++++++---- lib/Parse/ParseDecl.cpp | 7 +---- lib/Sema/MiscDiagnostics.cpp | 2 +- lib/Sema/TypeCheckPattern.cpp | 58 ++++++++++++++++++----------------- 5 files changed, 44 insertions(+), 43 deletions(-) diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index e8f68bfe4b95e..4aef9bc3905ca 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -479,9 +479,9 @@ 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) << ')'; } diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 8a168cda9f395..8f3a00ffafea2 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -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(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()) { @@ -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; + } + } + } } } @@ -2841,7 +2845,7 @@ OpaqueReturnTypeRepr *ValueDecl::getOpaqueResultTypeRepr() const { assert(NP->getDecl() == VD); (void) NP; - returnRepr = TP->getTypeLoc().getTypeRepr(); + returnRepr = TP->getTypeRepr(); } } } else { @@ -5586,7 +5590,7 @@ SourceRange VarDecl::getTypeSourceRangeForDiagnostics() const { if (auto *VP = dyn_cast(Pat)) Pat = VP->getSubPattern(); if (auto *TP = dyn_cast(Pat)) - if (auto typeRepr = TP->getTypeLoc().getTypeRepr()) + if (auto typeRepr = TP->getTypeRepr()) return typeRepr->getSourceRange(); return SourceRange(); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 2f095271755d6..b13b09ceea5d1 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -5694,12 +5694,7 @@ Parser::parseDeclVarGetSet(Pattern *pattern, ParseDeclOptions Flags, if (!PrimaryVar) return nullptr; - TypeLoc TyLoc; - if (auto *TP = dyn_cast(pattern)) { - TyLoc = TP->getTypeLoc(); - } - - if (!TyLoc.hasLocation()) { + if (!isa(pattern)) { if (accessors.Get || accessors.Set || accessors.Address || accessors.MutableAddress) { SourceLoc locAfterPattern = pattern->getLoc().getAdvancedLoc( diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp index a0867506418d1..28c1b5b03e12c 100644 --- a/lib/Sema/MiscDiagnostics.cpp +++ b/lib/Sema/MiscDiagnostics.cpp @@ -3759,7 +3759,7 @@ checkImplicitPromotionsInCondition(const StmtConditionElement &cond, diag::optional_check_promotion, subExpr->getType()) .highlight(subExpr->getSourceRange()) - .fixItReplace(TP->getTypeLoc().getSourceRange(), + .fixItReplace(TP->getTypeRepr()->getSourceRange(), ooType->getString()); return; } diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp index ab3058092a526..3cee1b6d1ce01 100644 --- a/lib/Sema/TypeCheckPattern.cpp +++ b/lib/Sema/TypeCheckPattern.cpp @@ -671,44 +671,47 @@ Pattern *TypeChecker::resolvePattern(Pattern *P, DeclContext *DC, return P; } -static Type validateTypedPattern(TypeResolution resolution, - TypedPattern *TP, - TypeResolutionOptions options) { - TypeLoc TL = TP->getTypeLoc(); - - bool hadError; - +static Type validateTypedPattern(TypedPattern *TP, TypeResolution resolution) { + if (TP->hasType()) { + return TP->getType(); + } + // If the pattern declares an opaque type, and applies to a single // variable binding, then we can bind the opaque return type from the // property definition. auto &Context = resolution.getASTContext(); - auto *Repr = TL.getTypeRepr(); + auto *Repr = TP->getTypeRepr(); if (Repr && isa(Repr)) { auto named = dyn_cast( TP->getSubPattern()->getSemanticsProvidingPattern()); - if (named) { - auto *var = named->getDecl(); - auto opaqueDecl = var->getOpaqueResultTypeDecl(); - auto opaqueTy = (opaqueDecl - ? opaqueDecl->getDeclaredInterfaceType() - : ErrorType::get(Context)); - TL.setType(named->getDecl()->getDeclContext() - ->mapTypeIntoContext(opaqueTy)); - hadError = opaqueTy->hasError(); - } else { - Context.Diags.diagnose(TP->getLoc(), diag::opaque_type_unsupported_pattern); - hadError = true; + if (!named) { + Context.Diags.diagnose(TP->getLoc(), + diag::opaque_type_unsupported_pattern); + return ErrorType::get(Context); } - } else { - hadError = TypeChecker::validateType(TL, resolution); + + auto *var = named->getDecl(); + auto opaqueDecl = var->getOpaqueResultTypeDecl(); + if (!opaqueDecl) { + return ErrorType::get(Context); + } + + auto opaqueTy = opaqueDecl->getDeclaredInterfaceType(); + if (opaqueTy->hasError()) { + return ErrorType::get(Context); + } + + return named->getDecl()->getDeclContext()->mapTypeIntoContext(opaqueTy); } - if (hadError) { + auto ty = resolution.resolveType(Repr); + if (!ty || ty->hasError()) { return ErrorType::get(Context); } - assert(!dyn_cast_or_null(Repr)); - return TL.getType(); + assert(!dyn_cast_or_null(Repr) && + "Didn't resolve invalid type to error type!"); + return ty; } Type TypeChecker::typeCheckPattern(ContextualPattern pattern) { @@ -768,8 +771,7 @@ Type PatternTypeRequest::evaluate(Evaluator &evaluator, // that type. case PatternKind::Typed: { auto resolution = TypeResolution::forContextual(dc, options); - TypedPattern *TP = cast(P); - return validateTypedPattern(resolution, TP, options); + return validateTypedPattern(cast(P), resolution); } // A wildcard or name pattern cannot appear by itself in a context @@ -824,7 +826,7 @@ Type PatternTypeRequest::evaluate(Evaluator &evaluator, if (somePat->isImplicit() && isa(somePat->getSubPattern())) { auto resolution = TypeResolution::forContextual(dc, options); TypedPattern *TP = cast(somePat->getSubPattern()); - auto type = validateTypedPattern(resolution, TP, options); + auto type = validateTypedPattern(TP, resolution); if (type && !type->hasError()) { return OptionalType::get(type); }