From 0342855e500b6c2f3f61c448dc36cf268b9e51dd Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Thu, 30 Apr 2020 19:01:24 -0700 Subject: [PATCH 01/35] [NFC] Debride Pattern.h of Implicit Tri-State Remove all of this in favor of explicit constructors to preserve the one-liners, or distribute the setImplicit() calls to the callsites if necessary. --- include/swift/AST/Pattern.h | 178 +++++++++--------- lib/AST/Pattern.cpp | 26 +-- lib/Parse/ParseExpr.cpp | 2 +- lib/Parse/ParsePattern.cpp | 2 +- lib/Parse/ParseStmt.cpp | 5 +- lib/Sema/BuilderTransform.cpp | 2 +- lib/Sema/DerivedConformanceCodable.cpp | 6 +- lib/Sema/DerivedConformanceCodingKey.cpp | 3 +- lib/Sema/DerivedConformanceComparable.cpp | 8 +- lib/Sema/DerivedConformanceDifferentiable.cpp | 2 +- .../DerivedConformanceEquatableHashable.cpp | 10 +- .../DerivedConformanceRawRepresentable.cpp | 3 +- lib/Sema/DerivedConformances.cpp | 15 +- lib/Sema/PCMacro.cpp | 2 +- lib/Sema/PlaygroundTransform.cpp | 2 +- lib/Sema/TypeCheckPattern.cpp | 33 ++-- lib/Sema/TypeCheckStorage.cpp | 19 +- lib/Serialization/Deserialization.cpp | 20 +- 18 files changed, 159 insertions(+), 179 deletions(-) diff --git a/include/swift/AST/Pattern.h b/include/swift/AST/Pattern.h index e32d570c8c784..7b11705882afb 100644 --- a/include/swift/AST/Pattern.h +++ b/include/swift/AST/Pattern.h @@ -34,6 +34,7 @@ namespace swift { class ASTContext; class Expr; enum class CheckedCastKind : unsigned; + class TypeExpr; /// PatternKind - The classification of different kinds of /// value-matching pattern. @@ -47,7 +48,7 @@ enum : unsigned { NumPatternKindBits = /// Diagnostic printing of PatternKinds. llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, PatternKind kind); - + /// Pattern - Base class for all patterns in Swift. class alignas(8) Pattern { protected: @@ -197,7 +198,7 @@ class alignas(8) Pattern { VD->setHasNonPatternBindingInit(); }); } - + /// Mark all vardecls in this pattern as having an owning statement for /// the pattern. void markOwnedByStatement(Stmt *S) { @@ -210,7 +211,7 @@ class alignas(8) Pattern { bool hasStorage() const; static bool classof(const Pattern *P) { return true; } - + //*** Allocation Routines ************************************************/ void *operator new(size_t bytes, const ASTContext &C); @@ -219,7 +220,7 @@ class alignas(8) Pattern { void *operator new(size_t bytes) = delete; void operator delete(void *data) = delete; void *operator new(size_t bytes, void *data) = delete; - + void print(llvm::raw_ostream &OS, const PrintOptions &Options = PrintOptions()) const; SWIFT_DEBUG_DUMP; @@ -227,7 +228,7 @@ class alignas(8) Pattern { /// walk - This recursively walks the AST rooted at this pattern. Pattern *walk(ASTWalker &walker); - Pattern *walk(ASTWalker &&walker) { return walk(walker); } + Pattern *walk(ASTWalker &&walker) { return walk(walker); } }; /// A pattern consisting solely of grouping parentheses around a @@ -236,13 +237,16 @@ class ParenPattern : public Pattern { SourceLoc LPLoc, RPLoc; Pattern *SubPattern; public: - ParenPattern(SourceLoc lp, Pattern *sub, SourceLoc rp, - Optional implicit = None) + ParenPattern(SourceLoc lp, Pattern *sub, SourceLoc rp) : Pattern(PatternKind::Paren), LPLoc(lp), RPLoc(rp), SubPattern(sub) { assert(lp.isValid() == rp.isValid()); - if (implicit.hasValue() ? *implicit : !lp.isValid()) - setImplicit(); + } + + static ParenPattern *createImplicit(ASTContext &Context, Pattern *sub) { + auto *PP = new (Context) ParenPattern(SourceLoc(), sub, SourceLoc()); + PP->setImplicit(); + return PP; } Pattern *getSubPattern() { return SubPattern; } @@ -289,7 +293,7 @@ class TuplePatternElt { const Pattern *getPattern() const { return ThePattern; } - + void setPattern(Pattern *p) { ThePattern = p; } }; @@ -300,25 +304,28 @@ class TuplePattern final : public Pattern, SourceLoc LPLoc, RPLoc; // Bits.TuplePattern.NumElements - TuplePattern(SourceLoc lp, unsigned numElements, SourceLoc rp, - bool implicit) + TuplePattern(SourceLoc lp, unsigned numElements, SourceLoc rp) : Pattern(PatternKind::Tuple), LPLoc(lp), RPLoc(rp) { Bits.TuplePattern.NumElements = numElements; assert(lp.isValid() == rp.isValid()); - if (implicit) - setImplicit(); } public: static TuplePattern *create(ASTContext &C, SourceLoc lp, - ArrayRef elements, SourceLoc rp, - Optional implicit = None); + ArrayRef elements, SourceLoc rp); + + static TuplePattern *createImplicit(ASTContext &C, + ArrayRef elements) { + auto *TP = create(C, SourceLoc(), elements, SourceLoc()); + TP->setImplicit(); + return TP; + } /// Create either a tuple pattern or a paren pattern, depending /// on the elements. static Pattern *createSimple(ASTContext &C, SourceLoc lp, - ArrayRef elements, SourceLoc rp, - Optional implicit = None); + ArrayRef elements, + SourceLoc rp); unsigned getNumElements() const { return Bits.TuplePattern.NumElements; @@ -348,10 +355,13 @@ class NamedPattern : public Pattern { VarDecl *const Var; public: - explicit NamedPattern(VarDecl *Var, Optional implicit = None) - : Pattern(PatternKind::Named), Var(Var) { - if (implicit.hasValue() ? *implicit : !Var->getLoc().isValid()) - setImplicit(); + explicit NamedPattern(VarDecl *Var) + : Pattern(PatternKind::Named), Var(Var) { } + + static NamedPattern *createImplicit(ASTContext &Ctx, VarDecl *Var) { + auto *NP = new (Ctx) NamedPattern(Var); + NP->setImplicit(); + return NP; } VarDecl *getDecl() const { return Var; } @@ -372,10 +382,13 @@ class AnyPattern : public Pattern { SourceLoc Loc; public: - explicit AnyPattern(SourceLoc Loc, Optional implicit = None) - : Pattern(PatternKind::Any), Loc(Loc) { - if (implicit.hasValue() ? *implicit : !Loc.isValid()) - setImplicit(); + explicit AnyPattern(SourceLoc Loc) + : Pattern(PatternKind::Any), Loc(Loc) { } + + static AnyPattern *createImplicit(ASTContext &Context) { + auto *AP = new (Context) AnyPattern(SourceLoc()); + AP->setImplicit(); + return AP; } SourceLoc getLoc() const { return Loc; } @@ -400,16 +413,16 @@ class TypedPattern : public Pattern { /// set to implicit. If false, it will not. If 'implicit' is not provided, /// then the pattern will be set to 'implicit' if there is a provided TypeRepr /// which has a valid SourceRange. - TypedPattern(Pattern *pattern, TypeRepr *tr, Optional implicit = None); + TypedPattern(Pattern *pattern, TypeRepr *tr); /// Creates an implicit typed pattern annotating the provided sub-pattern /// with a given type. static TypedPattern * createImplicit(ASTContext &ctx, Pattern *pattern, Type type) { - auto tp = new (ctx) TypedPattern(pattern, /*typeRepr*/nullptr, - /*implicit*/true); + auto tp = new (ctx) TypedPattern(pattern, /*typeRepr*/nullptr); if (!type.isNull()) tp->setType(type); + tp->setImplicit(); return tp; } @@ -449,29 +462,26 @@ class TypedPattern : public Pattern { /// TODO: Introduce type refinement of the value being matched. class IsPattern : public Pattern { SourceLoc IsLoc; - + Pattern *SubPattern; - + /// The semantics of the type check (class downcast, archetype-to-concrete, /// etc.) CheckedCastKind CastKind; - + /// The type being checked for. TypeLoc CastType; - + public: IsPattern(SourceLoc IsLoc, TypeLoc CastTy, Pattern *SubPattern, - CheckedCastKind Kind, - Optional implicit = None) + CheckedCastKind Kind) : Pattern(PatternKind::Is), IsLoc(IsLoc), SubPattern(SubPattern), CastKind(Kind), CastType(CastTy) { assert(IsLoc.isValid() == CastTy.hasLocation()); - if (implicit.hasValue() ? *implicit : !IsLoc.isValid()) - setImplicit(); } CheckedCastKind getCastKind() const { return CastKind; } @@ -481,7 +491,7 @@ class IsPattern : public Pattern { Pattern *getSubPattern() { return SubPattern; } const Pattern *getSubPattern() const { return SubPattern; } void setSubPattern(Pattern *p) { SubPattern = p; } - + SourceLoc getLoc() const { return IsLoc; } SourceRange getSourceRange() const { SourceLoc beginLoc = @@ -490,15 +500,15 @@ class IsPattern : public Pattern { (isImplicit() ? beginLoc : CastType.getSourceRange().End); return { beginLoc, endLoc }; } - + TypeLoc &getCastTypeLoc() { return CastType; } TypeLoc getCastTypeLoc() const { return CastType; } - + static bool classof(const Pattern *P) { return P->getKind() == PatternKind::Is; } }; - + /// A pattern that matches an enum case. If the enum value is in the matching /// case, then the value is extracted. If there is a subpattern, it is then /// matched against the associated value for the case. @@ -509,19 +519,16 @@ class EnumElementPattern : public Pattern { DeclNameRef Name; PointerUnion ElementDeclOrUnresolvedOriginalExpr; Pattern /*nullable*/ *SubPattern; - + public: EnumElementPattern(TypeLoc ParentType, SourceLoc DotLoc, DeclNameLoc NameLoc, DeclNameRef Name, EnumElementDecl *Element, - Pattern *SubPattern, Optional Implicit = None) + Pattern *SubPattern) : Pattern(PatternKind::EnumElement), ParentType(ParentType), DotLoc(DotLoc), NameLoc(NameLoc), Name(Name), ElementDeclOrUnresolvedOriginalExpr(Element), - SubPattern(SubPattern) { - if (Implicit.hasValue() && *Implicit) - setImplicit(); - } - + SubPattern(SubPattern) { } + /// Create an unresolved EnumElementPattern for a `.foo` pattern relying on /// contextual type. EnumElementPattern(SourceLoc DotLoc, @@ -533,15 +540,15 @@ class EnumElementPattern : public Pattern { ParentType(), DotLoc(DotLoc), NameLoc(NameLoc), Name(Name), ElementDeclOrUnresolvedOriginalExpr(UnresolvedOriginalExpr), SubPattern(SubPattern) { - + } bool hasSubPattern() const { return SubPattern; } - + const Pattern *getSubPattern() const { return SubPattern; } - + Pattern *getSubPattern() { return SubPattern; } @@ -549,25 +556,25 @@ class EnumElementPattern : public Pattern { bool isParentTypeImplicit() { return !ParentType.hasLocation(); } - + void setSubPattern(Pattern *p) { SubPattern = p; } - + DeclNameRef getName() const { return Name; } - + EnumElementDecl *getElementDecl() const { return ElementDeclOrUnresolvedOriginalExpr.dyn_cast(); } void setElementDecl(EnumElementDecl *d) { ElementDeclOrUnresolvedOriginalExpr = d; } - + Expr *getUnresolvedOriginalExpr() const { return ElementDeclOrUnresolvedOriginalExpr.get(); } bool hasUnresolvedOriginalExpr() const { return ElementDeclOrUnresolvedOriginalExpr.is(); } - + DeclNameLoc getNameLoc() const { return NameLoc; } SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); } SourceLoc getStartLoc() const { @@ -582,10 +589,10 @@ class EnumElementPattern : public Pattern { return NameLoc.getEndLoc(); } SourceRange getSourceRange() const { return {getStartLoc(), getEndLoc()}; } - + TypeLoc &getParentType() { return ParentType; } TypeLoc getParentType() const { return ParentType; } - + static bool classof(const Pattern *P) { return P->getKind() == PatternKind::EnumElement; } @@ -629,13 +636,9 @@ class OptionalSomePattern : public Pattern { public: explicit OptionalSomePattern(Pattern *SubPattern, - SourceLoc QuestionLoc, - Optional implicit = None) + SourceLoc QuestionLoc) : Pattern(PatternKind::OptionalSome), SubPattern(SubPattern), - QuestionLoc(QuestionLoc) { - if (implicit.hasValue() ? *implicit : !QuestionLoc.isValid()) - setImplicit(); - } + QuestionLoc(QuestionLoc) { } SourceLoc getQuestionLoc() const { return QuestionLoc; } SourceRange getSourceRange() const { @@ -655,63 +658,61 @@ class OptionalSomePattern : public Pattern { }; - /// A pattern which matches a value obtained by evaluating an expression. /// The match will be tested using user-defined '~=' operator function lookup; /// the match succeeds if 'patternValue ~= matchedValue' produces a true value. class ExprPattern : public Pattern { llvm::PointerIntPair SubExprAndIsResolved; - + /// An expression constructed during type-checking that produces a call to the /// '~=' operator comparing the match expression on the left to the matched /// value on the right. Expr *MatchExpr; - + /// An implicit variable used to represent the RHS value of the match. VarDecl *MatchVar; - + public: /// Construct an ExprPattern. - ExprPattern(Expr *e, bool isResolved, Expr *matchExpr, VarDecl *matchVar, - Optional implicit = None); - + ExprPattern(Expr *e, bool isResolved, Expr *matchExpr, VarDecl *matchVar); + /// Construct an unresolved ExprPattern. ExprPattern(Expr *e) : ExprPattern(e, false, nullptr, nullptr) {} - + /// Construct a resolved ExprPattern. ExprPattern(Expr *e, Expr *matchExpr, VarDecl *matchVar) : ExprPattern(e, true, matchExpr, matchVar) {} - + Expr *getSubExpr() const { return SubExprAndIsResolved.getPointer(); } void setSubExpr(Expr *e) { SubExprAndIsResolved.setPointer(e); } - + Expr *getMatchExpr() const { return MatchExpr; } void setMatchExpr(Expr *e) { assert(isResolved() && "cannot set match fn for unresolved expr patter"); MatchExpr = e; } - + VarDecl *getMatchVar() const { return MatchVar; } void setMatchVar(VarDecl *v) { assert(isResolved() && "cannot set match var for unresolved expr patter"); MatchVar = v; } - + SourceLoc getLoc() const; SourceRange getSourceRange() const; - + /// True if pattern resolution has been applied to the subexpression. bool isResolved() const { return SubExprAndIsResolved.getInt(); } void setResolved(bool isResolved) { SubExprAndIsResolved.setInt(isResolved); } - + static bool classof(const Pattern *P) { return P->getKind() == PatternKind::Expr; } }; - + /// A pattern which introduces variable bindings. This pattern node has no /// semantics of its own, but has a syntactic effect on the subpattern. Bare /// identifiers in the subpattern create new variable bindings instead of being @@ -720,16 +721,19 @@ class VarPattern : public Pattern { SourceLoc VarLoc; Pattern *SubPattern; public: - VarPattern(SourceLoc loc, bool isLet, Pattern *sub, - Optional implicit = None) + VarPattern(SourceLoc loc, bool isLet, Pattern *sub) : Pattern(PatternKind::Var), VarLoc(loc), SubPattern(sub) { Bits.VarPattern.IsLet = isLet; - if (implicit.hasValue() ? *implicit : !loc.isValid()) - setImplicit(); + } + + static VarPattern *createImplicit(ASTContext &Ctx, bool isLet, Pattern *sub) { + auto *VP = new (Ctx) VarPattern(SourceLoc(), isLet, sub); + VP->setImplicit(); + return VP; } bool isLet() const { return Bits.VarPattern.IsLet; } - + SourceLoc getLoc() const { return VarLoc; } SourceRange getSourceRange() const { SourceLoc EndLoc = SubPattern->getSourceRange().End; @@ -737,17 +741,17 @@ class VarPattern : public Pattern { return VarLoc; return {VarLoc, EndLoc}; } - + const Pattern *getSubPattern() const { return SubPattern; } Pattern *getSubPattern() { return SubPattern; } void setSubPattern(Pattern *p) { SubPattern = p; } - + static bool classof(const Pattern *P) { return P->getKind() == PatternKind::Var; } }; - + inline Pattern *Pattern::getSemanticsProvidingPattern() { if (auto *pp = dyn_cast(this)) return pp->getSubPattern()->getSemanticsProvidingPattern(); diff --git a/lib/AST/Pattern.cpp b/lib/AST/Pattern.cpp index 862dbb2794291..a6385bc564991 100644 --- a/lib/AST/Pattern.cpp +++ b/lib/AST/Pattern.cpp @@ -367,15 +367,12 @@ Identifier NamedPattern::getBoundName() const { /// Allocate a new pattern that matches a tuple. TuplePattern *TuplePattern::create(ASTContext &C, SourceLoc lp, - ArrayRef elts, SourceLoc rp, - Optional implicit) { - if (!implicit.hasValue()) - implicit = !lp.isValid(); - + ArrayRef elts, + SourceLoc rp) { unsigned n = elts.size(); void *buffer = C.Allocate(totalSizeToAlloc(n), alignof(TuplePattern)); - TuplePattern *pattern = ::new (buffer) TuplePattern(lp, n, rp, *implicit); + TuplePattern *pattern = ::new (buffer) TuplePattern(lp, n, rp); std::uninitialized_copy(elts.begin(), elts.end(), pattern->getTrailingObjects()); return pattern; @@ -383,17 +380,16 @@ TuplePattern *TuplePattern::create(ASTContext &C, SourceLoc lp, Pattern *TuplePattern::createSimple(ASTContext &C, SourceLoc lp, ArrayRef elements, - SourceLoc rp, - Optional implicit) { + SourceLoc rp) { assert(lp.isValid() == rp.isValid()); if (elements.size() == 1 && elements[0].getPattern()->getBoundName().empty()) { auto &first = const_cast(elements.front()); - return new (C) ParenPattern(lp, first.getPattern(), rp, implicit); + return new (C) ParenPattern(lp, first.getPattern(), rp); } - return create(C, lp, elements, rp, implicit); + return create(C, lp, elements, rp); } SourceRange TuplePattern::getSourceRange() const { @@ -406,11 +402,8 @@ SourceRange TuplePattern::getSourceRange() const { Fields.back().getPattern()->getEndLoc() }; } -TypedPattern::TypedPattern(Pattern *pattern, TypeRepr *tr, - Optional implicit) +TypedPattern::TypedPattern(Pattern *pattern, TypeRepr *tr) : Pattern(PatternKind::Typed), SubPattern(pattern), PatTypeRepr(tr) { - if (implicit ? *implicit : tr && !tr->getSourceRange().isValid()) - setImplicit(); Bits.TypedPattern.IsPropagatedType = false; } @@ -450,13 +443,10 @@ SourceRange TypedPattern::getSourceRange() const { /// Construct an ExprPattern. ExprPattern::ExprPattern(Expr *e, bool isResolved, Expr *matchExpr, - VarDecl *matchVar, - Optional implicit) + VarDecl *matchVar) : Pattern(PatternKind::Expr), SubExprAndIsResolved(e, isResolved), MatchExpr(matchExpr), MatchVar(matchVar) { assert(!matchExpr || e->isImplicit() == matchExpr->isImplicit()); - if (implicit.hasValue() ? *implicit : e->isImplicit()) - setImplicit(); } SourceLoc ExprPattern::getLoc() const { diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 7f9f27468e157..8f2601f7ed05f 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -2597,7 +2597,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange, VD->getAttrs().add(new (Context) ReferenceOwnershipAttr( SourceRange(ownershipLocStart, ownershipLocEnd), ownershipKind)); - auto pattern = new (Context) NamedPattern(VD, /*implicit*/true); + auto pattern = NamedPattern::createImplicit(Context, VD); auto *PBD = PatternBindingDecl::create( Context, /*StaticLoc*/ SourceLoc(), StaticSpellingKind::None, diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp index d16cb49e5eb43..804783e2e2ab3 100644 --- a/lib/Parse/ParsePattern.cpp +++ b/lib/Parse/ParsePattern.cpp @@ -968,7 +968,7 @@ ParserResult Parser::parsePattern() { auto VD = new (Context) VarDecl( /*IsStatic*/false, introducer, /*IsCaptureList*/false, consumeToken(tok::kw__), Identifier(), CurDeclContext); - return makeParserResult(new (Context) NamedPattern(VD, /*implicit*/true)); + return makeParserResult(NamedPattern::createImplicit(Context, VD)); } PatternCtx.setCreateSyntax(SyntaxKind::WildcardPattern); return makeParserResult(new (Context) AnyPattern(consumeToken(tok::kw__))); diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 21af64d2ae008..eea7b920e5c3e 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -1093,7 +1093,8 @@ static void parseGuardedPattern(Parser &P, GuardedPattern &result, var->setImplicit(); auto namePattern = new (P.Context) NamedPattern(var); auto varPattern = new (P.Context) VarPattern(loc, /*isLet*/true, - namePattern, /*implicit*/true); + namePattern); + varPattern->setImplicit(); patternResult = makeParserResult(varPattern); } @@ -1483,7 +1484,7 @@ Parser::parseStmtConditionElement(SmallVectorImpl &result, if (ThePattern.isNonNull()) { auto *P = new (Context) VarPattern(IntroducerLoc, wasLet, - ThePattern.get(), /*impl*/false); + ThePattern.get()); ThePattern = makeParserResult(Status, P); } diff --git a/lib/Sema/BuilderTransform.cpp b/lib/Sema/BuilderTransform.cpp index d8ff7e0003e77..bc15305c3ab83 100644 --- a/lib/Sema/BuilderTransform.cpp +++ b/lib/Sema/BuilderTransform.cpp @@ -895,7 +895,7 @@ class BuilderClosureRewriter // Form a new pattern binding to bind the temporary variable to the // transformed expression. - auto pattern = new (ctx) NamedPattern(temporaryVar,/*implicit=*/true); + auto pattern = NamedPattern::createImplicit(ctx, temporaryVar); pattern->setType(temporaryVar->getType()); auto pbd = PatternBindingDecl::create( diff --git a/lib/Sema/DerivedConformanceCodable.cpp b/lib/Sema/DerivedConformanceCodable.cpp index bb55145ab63db..c2fddac40d360 100644 --- a/lib/Sema/DerivedConformanceCodable.cpp +++ b/lib/Sema/DerivedConformanceCodable.cpp @@ -596,8 +596,7 @@ deriveBodyEncodable_encode(AbstractFunctionDecl *encodeDecl, void *) { // Full `let container = encoder.container(keyedBy: CodingKeys.self)` // binding. - auto *containerPattern = new (C) NamedPattern(containerDecl, - /*implicit=*/true); + auto *containerPattern = NamedPattern::createImplicit(C, containerDecl); auto *bindingDecl = PatternBindingDecl::createImplicit( C, StaticSpellingKind::None, containerPattern, callExpr, funcDC); statements.push_back(bindingDecl); @@ -815,8 +814,7 @@ deriveBodyDecodable_init(AbstractFunctionDecl *initDecl, void *) { // Full `let container = decoder.container(keyedBy: CodingKeys.self)` // binding. - auto *containerPattern = new (C) NamedPattern(containerDecl, - /*implicit=*/true); + auto *containerPattern = NamedPattern::createImplicit(C, containerDecl); auto *bindingDecl = PatternBindingDecl::createImplicit( C, StaticSpellingKind::None, containerPattern, tryExpr, funcDC); statements.push_back(bindingDecl); diff --git a/lib/Sema/DerivedConformanceCodingKey.cpp b/lib/Sema/DerivedConformanceCodingKey.cpp index 37c6c7d71b48b..7e06caaffe456 100644 --- a/lib/Sema/DerivedConformanceCodingKey.cpp +++ b/lib/Sema/DerivedConformanceCodingKey.cpp @@ -298,8 +298,7 @@ deriveBodyCodingKey_init_stringValue(AbstractFunctionDecl *initDecl, void *) { /*case body var decls*/ None)); } - auto *anyPat = new (C) AnyPattern(SourceLoc()); - anyPat->setImplicit(); + auto *anyPat = AnyPattern::createImplicit(C); auto dfltLabelItem = CaseLabelItem::getDefault(anyPat); auto *dfltReturnStmt = new (C) FailStmt(SourceLoc(), SourceLoc()); diff --git a/lib/Sema/DerivedConformanceComparable.cpp b/lib/Sema/DerivedConformanceComparable.cpp index 8faacc11ba2a4..176cc6247486c 100644 --- a/lib/Sema/DerivedConformanceComparable.cpp +++ b/lib/Sema/DerivedConformanceComparable.cpp @@ -172,9 +172,8 @@ deriveBodyComparable_enum_hasAssociatedValues_lt(AbstractFunctionDecl *ltDecl, v } // case (.(let l0, let l1, ...), .(let r0, let r1, ...)) - auto caseTuplePattern = TuplePattern::create(C, SourceLoc(), { - TuplePatternElt(lhsElemPat), TuplePatternElt(rhsElemPat) }, - SourceLoc()); + auto caseTuplePattern = TuplePattern::createImplicit(C, { + TuplePatternElt(lhsElemPat), TuplePatternElt(rhsElemPat) }); caseTuplePattern->setImplicit(); auto labelItem = CaseLabelItem(caseTuplePattern); @@ -215,8 +214,7 @@ deriveBodyComparable_enum_hasAssociatedValues_lt(AbstractFunctionDecl *ltDecl, v // We only generate this if the enum has more than one case. If it has exactly // one case, then that single case statement is already exhaustive. if (elementCount > 1) { - auto defaultPattern = new (C) AnyPattern(SourceLoc()); - defaultPattern->setImplicit(); + auto defaultPattern = AnyPattern::createImplicit(C); auto defaultItem = CaseLabelItem::getDefault(defaultPattern); auto body = deriveBodyComparable_enum_noAssociatedValues_lt(ltDecl, nullptr).first; cases.push_back(CaseStmt::create(C, CaseParentKind::Switch, SourceLoc(), diff --git a/lib/Sema/DerivedConformanceDifferentiable.cpp b/lib/Sema/DerivedConformanceDifferentiable.cpp index 8a4ed05a6d067..3acc57380d5d9 100644 --- a/lib/Sema/DerivedConformanceDifferentiable.cpp +++ b/lib/Sema/DerivedConformanceDifferentiable.cpp @@ -376,7 +376,7 @@ getOrSynthesizeTangentVectorStruct(DerivedConformance &derived, Identifier id) { auto memberAssocContextualType = parentDC->mapTypeIntoContext(memberAssocInterfaceType); newMember->setInterfaceType(memberAssocInterfaceType); - Pattern *memberPattern = new (C) NamedPattern(newMember, /*implicit*/ true); + Pattern *memberPattern = NamedPattern::createImplicit(C, newMember); memberPattern->setType(memberAssocContextualType); memberPattern = TypedPattern::createImplicit(C, memberPattern, memberAssocContextualType); diff --git a/lib/Sema/DerivedConformanceEquatableHashable.cpp b/lib/Sema/DerivedConformanceEquatableHashable.cpp index a091cb7d44d51..ab5066d57895d 100644 --- a/lib/Sema/DerivedConformanceEquatableHashable.cpp +++ b/lib/Sema/DerivedConformanceEquatableHashable.cpp @@ -294,9 +294,8 @@ deriveBodyEquatable_enum_hasAssociatedValues_eq(AbstractFunctionDecl *eqDecl, } // case (.(let l0, let l1, ...), .(let r0, let r1, ...)) - auto caseTuplePattern = TuplePattern::create(C, SourceLoc(), { - TuplePatternElt(lhsElemPat), TuplePatternElt(rhsElemPat) }, - SourceLoc()); + auto caseTuplePattern = TuplePattern::createImplicit(C, { + TuplePatternElt(lhsElemPat), TuplePatternElt(rhsElemPat) }); caseTuplePattern->setImplicit(); auto labelItem = CaseLabelItem(caseTuplePattern); @@ -338,8 +337,7 @@ deriveBodyEquatable_enum_hasAssociatedValues_eq(AbstractFunctionDecl *eqDecl, // We only generate this if the enum has more than one case. If it has exactly // one case, then that single case statement is already exhaustive. if (elementCount > 1) { - auto defaultPattern = new (C) AnyPattern(SourceLoc()); - defaultPattern->setImplicit(); + auto defaultPattern = AnyPattern::createImplicit(C); auto defaultItem = CaseLabelItem::getDefault(defaultPattern); auto falseExpr = new (C) BooleanLiteralExpr(false, SourceLoc(), /*implicit*/ true); @@ -999,7 +997,7 @@ static ValueDecl *deriveHashable_hashValue(DerivedConformance &derived) { hashValueDecl->copyFormalAccessFrom(derived.Nominal, /*sourceIsParentContext*/ true); - Pattern *hashValuePat = new (C) NamedPattern(hashValueDecl, /*implicit*/true); + Pattern *hashValuePat = NamedPattern::createImplicit(C, hashValueDecl); hashValuePat->setType(intType); hashValuePat = TypedPattern::createImplicit(C, hashValuePat, intType); hashValuePat->setType(intType); diff --git a/lib/Sema/DerivedConformanceRawRepresentable.cpp b/lib/Sema/DerivedConformanceRawRepresentable.cpp index f1de7210c9461..e2d98db6b4750 100644 --- a/lib/Sema/DerivedConformanceRawRepresentable.cpp +++ b/lib/Sema/DerivedConformanceRawRepresentable.cpp @@ -357,8 +357,7 @@ deriveBodyRawRepresentable_init(AbstractFunctionDecl *initDecl, void *) { Idx++; } - auto anyPat = new (C) AnyPattern(SourceLoc()); - anyPat->setImplicit(); + auto anyPat = AnyPattern::createImplicit(C); auto dfltLabelItem = CaseLabelItem::getDefault(anyPat); auto dfltReturnStmt = new (C) FailStmt(SourceLoc(), SourceLoc()); diff --git a/lib/Sema/DerivedConformances.cpp b/lib/Sema/DerivedConformances.cpp index 8d82e4c9b7e69..771fcf01fd4be 100644 --- a/lib/Sema/DerivedConformances.cpp +++ b/lib/Sema/DerivedConformances.cpp @@ -374,7 +374,7 @@ DerivedConformance::declareDerivedProperty(Identifier name, propDecl->copyFormalAccessFrom(Nominal, /*sourceIsParentContext*/ true); propDecl->setInterfaceType(propertyInterfaceType); - Pattern *propPat = new (Context) NamedPattern(propDecl, /*implicit*/ true); + Pattern *propPat = NamedPattern::createImplicit(Context, propDecl); propPat->setType(propertyContextType); propPat = TypedPattern::createImplicit(Context, propPat, propertyContextType); @@ -530,7 +530,7 @@ DeclRefExpr *DerivedConformance::convertEnumToIndex(SmallVectorImpl &st indexVar->setImplicit(); // generate: var indexVar - Pattern *indexPat = new (C) NamedPattern(indexVar, /*implicit*/ true); + Pattern *indexPat = NamedPattern::createImplicit(C, indexVar); indexPat->setType(intType); indexPat = TypedPattern::createImplicit(C, indexPat, intType); indexPat->setType(intType); @@ -651,14 +651,13 @@ DerivedConformance::enumElementPayloadSubpattern(EnumElementDecl *enumElementDec auto namedPattern = new (C) NamedPattern(payloadVar); namedPattern->setImplicit(); - auto letPattern = new (C) VarPattern(SourceLoc(), /*isLet*/ true, - namedPattern); + auto letPattern = VarPattern::createImplicit(C, /*isLet*/ true, + namedPattern); elementPatterns.push_back(TuplePatternElt(tupleElement.getName(), SourceLoc(), letPattern)); } - auto pat = TuplePattern::create(C, SourceLoc(), elementPatterns, - SourceLoc()); + auto pat = TuplePattern::createImplicit(C, elementPatterns); pat->setImplicit(); return pat; } @@ -674,9 +673,7 @@ DerivedConformance::enumElementPayloadSubpattern(EnumElementDecl *enumElementDec namedPattern->setImplicit(); auto letPattern = new (C) VarPattern(SourceLoc(), /*isLet*/ true, namedPattern); - auto pat = new (C) ParenPattern(SourceLoc(), letPattern, SourceLoc()); - pat->setImplicit(); - return pat; + return ParenPattern::createImplicit(C, letPattern); } diff --git a/lib/Sema/PCMacro.cpp b/lib/Sema/PCMacro.cpp index 35eaefe55ff87..120b76bf694af 100644 --- a/lib/Sema/PCMacro.cpp +++ b/lib/Sema/PCMacro.cpp @@ -516,7 +516,7 @@ class Instrumenter : InstrumenterBase { VD->setInterfaceType(MaybeLoadInitExpr->getType()->mapTypeOutOfContext()); VD->setImplicit(); - NamedPattern *NP = new (Context) NamedPattern(VD, /*implicit*/ true); + NamedPattern *NP = NamedPattern::createImplicit(Context, VD); PatternBindingDecl *PBD = PatternBindingDecl::createImplicit( Context, StaticSpellingKind::None, NP, MaybeLoadInitExpr, TypeCheckDC); diff --git a/lib/Sema/PlaygroundTransform.cpp b/lib/Sema/PlaygroundTransform.cpp index 30e85e98641aa..ceb0b795422a6 100644 --- a/lib/Sema/PlaygroundTransform.cpp +++ b/lib/Sema/PlaygroundTransform.cpp @@ -763,7 +763,7 @@ class Instrumenter : InstrumenterBase { VD->setInterfaceType(MaybeLoadInitExpr->getType()->mapTypeOutOfContext()); VD->setImplicit(); - NamedPattern *NP = new (Context) NamedPattern(VD, /*implicit*/ true); + NamedPattern *NP = NamedPattern::createImplicit(Context, VD); PatternBindingDecl *PBD = PatternBindingDecl::createImplicit( Context, StaticSpellingKind::None, NP, MaybeLoadInitExpr, TypeCheckDC); diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp index 95416920ee649..80b788655c880 100644 --- a/lib/Sema/TypeCheckPattern.cpp +++ b/lib/Sema/TypeCheckPattern.cpp @@ -345,7 +345,10 @@ class ResolvePattern : public ASTVisitorgetLoc(), E->isImplicit()); + if (E->isImplicit()) { + return AnyPattern::createImplicit(Context); + } + return new (Context) AnyPattern(E->getLoc()); } // Cast expressions 'x as T' get resolved to checked cast patterns. @@ -654,8 +657,8 @@ Pattern *TypeChecker::resolvePattern(Pattern *P, DeclContext *DC, // "if let" implicitly looks inside of an optional, so wrap it in an // OptionalSome pattern. - InnerP = new (Context) OptionalSomePattern(InnerP, InnerP->getEndLoc(), - true); + InnerP = new (Context) OptionalSomePattern(InnerP, InnerP->getEndLoc()); + InnerP->setImplicit(); if (auto *TP = dyn_cast(P)) TP->setSubPattern(InnerP); else @@ -1100,8 +1103,7 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, if (TP->getLParenLoc().isValid()) { P = new (Context) ParenPattern(TP->getLParenLoc(), sub, - TP->getRParenLoc(), - /*implicit*/ TP->isImplicit()); + TP->getRParenLoc()); P->setType(sub->getType()); } else { P = sub; @@ -1192,7 +1194,7 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, NLE->getLoc(), DeclNameLoc(NLE->getLoc()), NoneEnumElement->createNameRef(), - NoneEnumElement, nullptr, false); + NoneEnumElement, nullptr); return TypeChecker::coercePatternToType( pattern.forSubPattern(P, /*retainTopLevel=*/true), type, options); } @@ -1233,8 +1235,8 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, IP->getStartLoc(), DeclNameLoc(IP->getEndLoc()), some->createNameRef(), - nullptr, sub, - /*Implicit=*/true); + nullptr, sub); + sub->setImplicit(); } P = sub; @@ -1358,7 +1360,8 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, baseType->lookThroughAllOptionalTypes(), EEP->getName(), EEP->getLoc())) { P = new (Context) - OptionalSomePattern(EEP, EEP->getEndLoc(), /*implicit*/true); + OptionalSomePattern(EEP, EEP->getEndLoc()); + P->setImplicit(); return coercePatternToType( pattern.forSubPattern(P, /*retainTopLevel=*/true), type, options); @@ -1503,7 +1506,7 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, SmallVector elements; if (auto *TTy = dyn_cast(elementType.getPointer())) { for (auto &elt : TTy->getElements()) { - auto *subPattern = new (Context) AnyPattern(SourceLoc()); + auto *subPattern = AnyPattern::createImplicit(Context); elements.push_back(TuplePatternElt(elt.getName(), SourceLoc(), subPattern)); } @@ -1512,13 +1515,13 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, assert(parenTy && "Associated value type is neither paren nor tuple?"); (void)parenTy; - auto *subPattern = new (Context) AnyPattern(SourceLoc()); + auto *subPattern = AnyPattern::createImplicit(Context); elements.push_back(TuplePatternElt(Identifier(), SourceLoc(), subPattern)); } Pattern *sub = TuplePattern::createSimple(Context, SourceLoc(), - elements, SourceLoc(), - /*implicit*/true); + elements, SourceLoc()); + sub->setImplicit(); auto newSubOptions = subOptions; newSubOptions.setContext(TypeResolverContext::EnumPatternPayload); newSubOptions |= TypeResolutionFlags::FromNonInferredPattern; @@ -1542,8 +1545,8 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, if (castKind) { auto isPattern = new (Context) IsPattern(SourceLoc(), TypeLoc::withoutLoc(enumTy), - EEP, *castKind, - /*implicit*/true); + EEP, *castKind); + isPattern->setImplicit(); isPattern->setType(type); P = isPattern; } diff --git a/lib/Sema/TypeCheckStorage.cpp b/lib/Sema/TypeCheckStorage.cpp index 7e6237d36f641..dcd44b00c95d4 100644 --- a/lib/Sema/TypeCheckStorage.cpp +++ b/lib/Sema/TypeCheckStorage.cpp @@ -1264,13 +1264,12 @@ synthesizeLazyGetterBody(AccessorDecl *Get, VarDecl *VD, VarDecl *Storage, Tmp1VD->setHasNonPatternBindingInit(); Tmp1VD->setImplicit(); - auto *Named = new (Ctx) NamedPattern(Tmp1VD, /*implicit*/true); + auto *Named = NamedPattern::createImplicit(Ctx, Tmp1VD); Named->setType(Tmp1VD->getType()); - auto *Let = new (Ctx) VarPattern(SourceLoc(), /*let*/true, Named, - /*implict*/true); + auto *Let = VarPattern::createImplicit(Ctx, /*let*/true, Named); Let->setType(Named->getType()); - auto *Some = new (Ctx) OptionalSomePattern(Let, SourceLoc(), - /*implicit*/true); + auto *Some = new (Ctx) OptionalSomePattern(Let, SourceLoc()); + Some->setImplicit(); Some->setElementDecl(Ctx.getOptionalSomeDecl()); Some->setType(OptionalType::get(Let->getType())); @@ -1332,7 +1331,7 @@ synthesizeLazyGetterBody(AccessorDecl *Get, VarDecl *VD, VarDecl *Storage, InitValue = new (Ctx) LazyInitializerExpr(InitValue); InitValue->setType(initType); - Pattern *Tmp2PBDPattern = new (Ctx) NamedPattern(Tmp2VD, /*implicit*/true); + Pattern *Tmp2PBDPattern = NamedPattern::createImplicit(Ctx, Tmp2VD); Tmp2PBDPattern = TypedPattern::createImplicit(Ctx, Tmp2PBDPattern, Tmp2VD->getType()); @@ -1575,7 +1574,7 @@ synthesizeObservedSetterBody(AccessorDecl *Set, TargetImpl target, Ctx.getIdentifier("tmp"), Set); OldValue->setImplicit(); OldValue->setInterfaceType(VD->getValueInterfaceType()); - auto *tmpPattern = new (Ctx) NamedPattern(OldValue, /*implicit*/ true); + auto *tmpPattern = NamedPattern::createImplicit(Ctx, OldValue); auto *tmpPBD = PatternBindingDecl::createImplicit( Ctx, StaticSpellingKind::None, tmpPattern, OldValueExpr, Set); SetterBody.push_back(tmpPBD); @@ -2305,7 +2304,7 @@ LazyStoragePropertyRequest::evaluate(Evaluator &evaluator, // Create the pattern binding decl for the storage decl. This will get // default initialized to nil. - Pattern *PBDPattern = new (Context) NamedPattern(Storage, /*implicit*/true); + Pattern *PBDPattern = NamedPattern::createImplicit(Context, Storage); PBDPattern->setType(StorageTy); PBDPattern = TypedPattern::createImplicit(Context, PBDPattern, StorageTy); auto *InitExpr = new (Context) NilLiteralExpr(SourceLoc(), /*Implicit=*/true); @@ -2378,7 +2377,7 @@ static VarDecl *synthesizePropertyWrapperStorageWrapperProperty( addMemberToContextIfNeeded(property, dc, var); // Create the pattern binding declaration for the property. - Pattern *pbdPattern = new (ctx) NamedPattern(property, /*implicit=*/true); + Pattern *pbdPattern = NamedPattern::createImplicit(ctx, property); pbdPattern->setType(propertyType); pbdPattern = TypedPattern::createImplicit(ctx, pbdPattern, propertyType); auto pbd = PatternBindingDecl::createImplicit( @@ -2649,7 +2648,7 @@ PropertyWrapperBackingPropertyInfoRequest::evaluate(Evaluator &evaluator, addMemberToContextIfNeeded(backingVar, dc, var); // Create the pattern binding declaration for the backing property. - Pattern *pbdPattern = new (ctx) NamedPattern(backingVar, /*implicit=*/true); + Pattern *pbdPattern = NamedPattern::createImplicit(ctx, backingVar); pbdPattern->setType(storageType); pbdPattern = TypedPattern::createImplicit(ctx, pbdPattern, storageType); auto pbd = PatternBindingDecl::createImplicit( diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index a2a5276b132b0..87440acb8e829 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -320,10 +320,7 @@ Expected ModuleFile::readPattern(DeclContext *owningDC) { Pattern *subPattern = readPatternUnchecked(owningDC); - auto result = new (getContext()) ParenPattern(SourceLoc(), - subPattern, - SourceLoc(), - isImplicit); + auto result = ParenPattern::createImplicit(getContext(), subPattern); if (Type interfaceType = subPattern->getDelayedInterfaceType()) result->setDelayedInterfaceType(ParenType::get(getContext(), @@ -358,8 +355,7 @@ Expected ModuleFile::readPattern(DeclContext *owningDC) { elements.push_back(TuplePatternElt(label, SourceLoc(), subPattern)); } - auto result = TuplePattern::create(getContext(), SourceLoc(), - elements, SourceLoc(), isImplicit); + auto result = TuplePattern::createImplicit(getContext(), elements); recordPatternType(result, getType(tupleTypeID)); restoreOffset.reset(); return result; @@ -378,7 +374,7 @@ Expected ModuleFile::readPattern(DeclContext *owningDC) { } auto var = cast(deserialized.get()); - auto result = new (getContext()) NamedPattern(var, isImplicit); + auto result = NamedPattern::createImplicit(getContext(), var); recordPatternType(result, getType(typeID)); restoreOffset.reset(); return result; @@ -388,7 +384,7 @@ Expected ModuleFile::readPattern(DeclContext *owningDC) { bool isImplicit; AnyPatternLayout::readRecord(scratch, typeID, isImplicit); - auto result = new (getContext()) AnyPattern(SourceLoc(), isImplicit); + auto result = AnyPattern::createImplicit(getContext()); recordPatternType(result, getType(typeID)); restoreOffset.reset(); return result; @@ -405,9 +401,8 @@ Expected ModuleFile::readPattern(DeclContext *owningDC) { } auto type = getType(typeID); - auto result = new (getContext()) TypedPattern(subPattern.get(), - /*typeRepr*/nullptr, - isImplicit); + auto result = TypedPattern::createImplicit(getContext(), + subPattern.get(), type); recordPatternType(result, type); restoreOffset.reset(); return result; @@ -418,8 +413,7 @@ Expected ModuleFile::readPattern(DeclContext *owningDC) { Pattern *subPattern = readPatternUnchecked(owningDC); - auto result = new (getContext()) VarPattern(SourceLoc(), isLet, subPattern, - isImplicit); + auto result = VarPattern::createImplicit(getContext(), isLet, subPattern); if (Type interfaceType = subPattern->getDelayedInterfaceType()) result->setDelayedInterfaceType(interfaceType, owningDC); else From a05e072a6c7a777d84a187d94136983f61aee134 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Fri, 1 May 2020 10:52:25 -0700 Subject: [PATCH 02/35] [Diagnostics] Fix `RequirementFailure::getConformanceForConditionalReq` to use data from solution --- lib/Sema/CSDiagnostics.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index e53ee24b39f56..fc409f6f578e8 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -183,7 +183,7 @@ const Requirement &RequirementFailure::getRequirement() const { ProtocolConformance *RequirementFailure::getConformanceForConditionalReq( ConstraintLocator *locator) { - auto &cs = getConstraintSystem(); + auto &solution = getSolution(); auto reqElt = locator->castLastElementTo(); if (!reqElt.isConditionalRequirement()) return nullptr; @@ -192,10 +192,10 @@ ProtocolConformance *RequirementFailure::getConformanceForConditionalReq( auto *typeReqLoc = getConstraintLocator(getRawAnchor(), path.drop_back()); auto result = llvm::find_if( - cs.CheckedConformances, + solution.Conformances, [&](const std::pair &conformance) { return conformance.first == typeReqLoc; }); - assert(result != cs.CheckedConformances.end()); + assert(result != solution.Conformances.end()); auto conformance = result->second; assert(conformance.isConcrete()); From b4c73abdbc01b455a7bb5ac626c45c8992b25fe0 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Fri, 1 May 2020 10:55:25 -0700 Subject: [PATCH 03/35] [Diagnostics] Fix `MissingConformanceFailure::diagnoseAsError` to use solution to retrieve fixes --- lib/Sema/CSDiagnostics.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index fc409f6f578e8..1423aef7509d4 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -407,9 +407,8 @@ bool MissingConformanceFailure::diagnoseAsError() { if (auto *binaryOp = dyn_cast_or_null(findParentExpr(anchor))) { auto *caseExpr = binaryOp->getArg()->getElement(0); - auto &cs = getConstraintSystem(); llvm::SmallPtrSet anchors; - for (const auto *fix : cs.getFixes()) { + for (const auto *fix : getSolution().Fixes) { if (auto anchor = fix->getAnchor()) { if (anchor.is()) anchors.insert(getAsExpr(anchor)); From 490548f70b47cf33b1dd01456d7f5bae1b36dd7e Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Fri, 1 May 2020 11:02:40 -0700 Subject: [PATCH 04/35] [Diagnostics] Fix `ContextualFailure` to use solution data for `hasAppliedSelf` --- lib/Sema/CSDiagnostics.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index 1423aef7509d4..0a356dcf150c8 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -2020,8 +2020,7 @@ bool ContextualFailure::diagnoseAsError() { } case ConstraintLocator::RValueAdjustment: { - auto &cs = getConstraintSystem(); - + auto &solution = getSolution(); auto overload = getOverloadChoiceIfAvailable( getConstraintLocator(anchor, ConstraintLocator::UnresolvedMember)); if (!(overload && overload->choice.isDecl())) @@ -2047,8 +2046,11 @@ bool ContextualFailure::diagnoseAsError() { auto params = fnType->getParams(); - ParameterListInfo info(params, choice, - hasAppliedSelf(cs, overload->choice)); + ParameterListInfo info( + params, choice, + hasAppliedSelf(overload->choice, [&solution](Type type) { + return solution.simplifyType(type); + })); auto numMissingArgs = llvm::count_if( indices(params), [&info](const unsigned paramIdx) -> bool { return !info.hasDefaultArgument(paramIdx); From ee6c22821480a5cc8597ebe0baf2406b12a1f91e Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Fri, 1 May 2020 12:21:15 -0700 Subject: [PATCH 05/35] [Diagnostics] NFC: Move `is{Array, Collection}Type` helpers into `FailureDiagnostic` --- lib/Sema/CSDiagnostics.cpp | 13 +++++-------- lib/Sema/CSDiagnostics.h | 10 ++++++++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index 0a356dcf150c8..afe3869f196af 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -1261,12 +1261,11 @@ bool RValueTreatedAsLValueFailure::diagnoseAsError() { ParameterTypeFlags())}); if (auto info = getFunctionArgApplyInfo(argLoc)) { - auto &cs = getConstraintSystem(); auto paramType = info->getParamType(); auto argType = getType(inoutExpr)->getWithoutSpecifierType(); PointerTypeKind ptr; - if (cs.isArrayType(argType) && + if (isArrayType(argType) && paramType->getAnyPointerElementType(ptr) && (ptr == PTK_UnsafePointer || ptr == PTK_UnsafeRawPointer)) { emitDiagnosticAt(inoutExpr->getLoc(), @@ -3403,9 +3402,8 @@ bool MissingMemberFailure::diagnoseForDynamicCallable() const { } bool MissingMemberFailure::diagnoseInLiteralCollectionContext() const { - auto &cs = getConstraintSystem(); auto *expr = castToExpr(getAnchor()); - auto *parentExpr = cs.getParentExpr(expr); + auto *parentExpr = findParentExpr(expr); auto &solution = getSolution(); if (!(parentExpr && isa(expr))) @@ -3413,17 +3411,16 @@ bool MissingMemberFailure::diagnoseInLiteralCollectionContext() const { auto parentType = getType(parentExpr); - if (!cs.isCollectionType(parentType) && !parentType->is()) + if (!isCollectionType(parentType) && !parentType->is()) return false; if (isa(parentExpr)) { - parentExpr = cs.getParentExpr(parentExpr); + parentExpr = findParentExpr(parentExpr); if (!parentExpr) return false; } - if (auto *defaultableVar = - cs.getType(parentExpr)->getAs()) { + if (auto *defaultableVar = getType(parentExpr)->getAs()) { if (solution.DefaultedConstraints.count( defaultableVar->getImpl().getLocator()) != 0) { emitDiagnostic(diag::unresolved_member_no_inference, getName()); diff --git a/lib/Sema/CSDiagnostics.h b/lib/Sema/CSDiagnostics.h index cd5fa0ae72310..05f9f260a7509 100644 --- a/lib/Sema/CSDiagnostics.h +++ b/lib/Sema/CSDiagnostics.h @@ -202,6 +202,16 @@ class FailureDiagnostic { Type type, llvm::function_ref substitution = [](GenericTypeParamType *, Type) {}); + + bool isCollectionType(Type type) const { + auto &cs = getConstraintSystem(); + return bool(cs.isCollectionType(type)); + } + + bool isArrayType(Type type) const { + auto &cs = getConstraintSystem(); + return bool(cs.isArrayType(type)); + } }; /// Base class for all of the diagnostics related to generic requirement From 71f8a4eda632c789350b65fe2fd4f485e2b6508e Mon Sep 17 00:00:00 2001 From: Valeriy Van Date: Fri, 1 May 2020 21:23:44 +0200 Subject: [PATCH 06/35] Fixes example snippet in KeyValuePairs.swift --- stdlib/public/core/KeyValuePairs.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/public/core/KeyValuePairs.swift b/stdlib/public/core/KeyValuePairs.swift index b902e75f77288..63ecafc8c1622 100644 --- a/stdlib/public/core/KeyValuePairs.swift +++ b/stdlib/public/core/KeyValuePairs.swift @@ -27,7 +27,7 @@ /// "Evelyn Ashford": 10.79, /// "Marlies Gohr": 10.81] /// print(recordTimes.first!) -/// // Prints "("Florence Griffith-Joyner", 10.49)" +/// // Prints "(key: "Florence Griffith-Joyner", value: 10.49)" /// /// Some operations that are efficient on a dictionary are slower when using /// `KeyValuePairs`. In particular, to find the value matching a key, you From db6801b4b540699d5d865c5e9708d225d17cd78b Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Thu, 30 Apr 2020 12:44:07 +0200 Subject: [PATCH 07/35] [Diagnostics] Add `getRawType` which allows to retrieve type associated with ASTNode This is useful when diagnostic needs to check something about type variables involved in a particular type e.g. whether type variable has been defaulted. --- lib/Sema/CSDiagnostics.cpp | 9 +++++++-- lib/Sema/CSDiagnostics.h | 6 +++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index afe3869f196af..e3259f3745dbe 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -73,7 +73,11 @@ ASTNode FailureDiagnostic::getAnchor() const { } Type FailureDiagnostic::getType(ASTNode node, bool wantRValue) const { - return resolveType(S.getType(node), /*reconstituteSugar=*/false, wantRValue); + return resolveType(getRawType(node), /*reconstituteSugar=*/false, wantRValue); +} + +Type FailureDiagnostic::getRawType(ASTNode node) const { + return S.getType(node); } template @@ -3420,7 +3424,8 @@ bool MissingMemberFailure::diagnoseInLiteralCollectionContext() const { return false; } - if (auto *defaultableVar = getType(parentExpr)->getAs()) { + if (auto *defaultableVar = + getRawType(parentExpr)->getAs()) { if (solution.DefaultedConstraints.count( defaultableVar->getImpl().getLocator()) != 0) { emitDiagnostic(diag::unresolved_member_no_inference, getName()); diff --git a/lib/Sema/CSDiagnostics.h b/lib/Sema/CSDiagnostics.h index 05f9f260a7509..cc91fb0007dc3 100644 --- a/lib/Sema/CSDiagnostics.h +++ b/lib/Sema/CSDiagnostics.h @@ -86,6 +86,10 @@ class FailureDiagnostic { Type getType(ASTNode node, bool wantRValue = true) const; + /// Get type associated with a given ASTNode without resolving it, + /// which means that returned type would have type variables. + Type getRawType(ASTNode node) const; + /// Resolve type variables present in the raw type, if any. Type resolveType(Type rawType, bool reconstituteSugar = false, bool wantRValue = true) const { @@ -205,7 +209,7 @@ class FailureDiagnostic { bool isCollectionType(Type type) const { auto &cs = getConstraintSystem(); - return bool(cs.isCollectionType(type)); + return cs.isCollectionType(type); } bool isArrayType(Type type) const { From b405f7c5430cb56f15340093f32d81d3a29affa3 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Fri, 1 May 2020 12:45:48 -0700 Subject: [PATCH 08/35] [Diagnostics] Avoid direct use of constraint system by `MissingArgumentsFailure::isMisplacedMissingArgument` --- lib/Sema/CSDiagnostics.cpp | 7 +++---- lib/Sema/ConstraintSystem.cpp | 2 ++ lib/Sema/ConstraintSystem.h | 2 ++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index e3259f3745dbe..60ac8eadc0145 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -4264,12 +4264,11 @@ bool MissingArgumentsFailure::isMisplacedMissingArgument( return (*fix)->getKind() == kind; }; - auto &cs = solution.getConstraintSystem(); auto *callLocator = - cs.getConstraintLocator(anchor, ConstraintLocator::ApplyArgument); + solution.getConstraintLocator(anchor, {ConstraintLocator::ApplyArgument}); auto argFlags = fnType->getParams()[0].getParameterFlags(); - auto *argLoc = cs.getConstraintLocator( + auto *argLoc = solution.getConstraintLocator( callLocator, LocatorPathElt::ApplyArgToParam(0, 0, argFlags)); if (!(hasFixFor(FixKind::AllowArgumentTypeMismatch, argLoc) && @@ -4298,7 +4297,7 @@ bool MissingArgumentsFailure::isMisplacedMissingArgument( auto argType = solution.simplifyType(solution.getType(argument)); auto paramType = fnType->getParams()[1].getPlainType(); - return TypeChecker::isConvertibleTo(argType, paramType, cs.DC); + return TypeChecker::isConvertibleTo(argType, paramType, solution.getDC()); } std::tuple diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index e3b38f9edeab4..33d06b98f9137 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -2509,6 +2509,8 @@ size_t Solution::getTotalMemory() const { Conformances.size() * sizeof(std::pair); } +DeclContext *Solution::getDC() const { return constraintSystem->DC; } + DeclName OverloadChoice::getName() const { switch (getKind()) { case OverloadChoiceKind::Decl: diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h index 9cd408ba807ef..c43b1fa2638ec 100644 --- a/lib/Sema/ConstraintSystem.h +++ b/lib/Sema/ConstraintSystem.h @@ -885,6 +885,8 @@ class Solution { /// Retrieve the constraint system that this solution solves. ConstraintSystem &getConstraintSystem() const { return *constraintSystem; } + DeclContext *getDC() const; + /// The set of type bindings. llvm::DenseMap typeBindings; From 2d1e408170321ac68f9480c51fc7a410da22cb7b Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Fri, 1 May 2020 12:52:58 -0700 Subject: [PATCH 09/35] [Diagnostics] Use solution for verify presence of fix in `diagnoseUseOfReferenceEqualityOperator` --- lib/Sema/CSDiagnostics.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index 60ac8eadc0145..16fa82db96b09 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -5560,11 +5560,14 @@ bool ArgumentMismatchFailure::diagnoseUseOfReferenceEqualityOperator() const { // let's avoid producing a diagnostic second time, because first // one would cover both arguments. if (getAsExpr(getAnchor()) == rhs && rhsType->is()) { - auto &cs = getConstraintSystem(); - if (cs.hasFixFor(getConstraintLocator( - binaryOp, {ConstraintLocator::ApplyArgument, - LocatorPathElt::ApplyArgToParam( - 0, 0, getParameterFlagsAtIndex(0))}))) + auto *argLoc = getConstraintLocator( + binaryOp, + {ConstraintLocator::ApplyArgument, + LocatorPathElt::ApplyArgToParam(0, 0, getParameterFlagsAtIndex(0))}); + + if (llvm::any_of(getSolution().Fixes, [&argLoc](const ConstraintFix *fix) { + return fix->getLocator() == argLoc; + })) return true; } From bf4c3b7bdd09d254e74ccddc98f59ca5977969a3 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Fri, 1 May 2020 13:00:28 -0700 Subject: [PATCH 10/35] [Diagnostics] Use data from associated solution while diagnosing missing generic arguments --- lib/Sema/CSDiagnostics.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index 16fa82db96b09..400e08fbce8ea 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -5055,7 +5055,7 @@ bool MissingGenericArgumentsFailure::diagnoseForAnchor( bool MissingGenericArgumentsFailure::diagnoseParameter( Anchor anchor, GenericTypeParamType *GP) const { - auto &cs = getConstraintSystem(); + auto &solution = getSolution(); auto loc = anchor.is() ? anchor.get()->getLoc() : anchor.get()->getLoc(); @@ -5065,7 +5065,7 @@ bool MissingGenericArgumentsFailure::diagnoseParameter( // going to be completely cut off from the rest of constraint system, // that's why we'd get two fixes in this case which is not ideal. if (locator->isForContextualType() && - llvm::count_if(cs.DefaultedConstraints, + llvm::count_if(solution.DefaultedConstraints, [&GP](const ConstraintLocator *locator) { return locator->getGenericParameter() == GP; }) > 1) { @@ -5105,7 +5105,7 @@ bool MissingGenericArgumentsFailure::diagnoseParameter( void MissingGenericArgumentsFailure::emitGenericSignatureNote( Anchor anchor) const { - auto &cs = getConstraintSystem(); + auto &solution = getSolution(); auto *paramDC = getDeclContext(); if (!paramDC) @@ -5123,7 +5123,9 @@ void MissingGenericArgumentsFailure::emitGenericSignatureNote( }; llvm::SmallDenseMap params; - for (auto *typeVar : cs.getTypeVariables()) { + for (auto &entry : solution.typeBindings) { + auto *typeVar = entry.first; + auto *GP = typeVar->getImpl().getGenericParameter(); if (!GP) continue; @@ -5133,7 +5135,7 @@ void MissingGenericArgumentsFailure::emitGenericSignatureNote( // If this is one of the defaulted parameter types, attempt // to emit placeholder for it instead of `Any`. - if (llvm::any_of(cs.DefaultedConstraints, + if (llvm::any_of(solution.DefaultedConstraints, [&](const ConstraintLocator *locator) { return GP->getDecl() == getParamDecl(locator); })) From 5a7c70dcc4f5bb98772c497b3710f3962b5535e8 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Fri, 1 May 2020 13:46:21 -0700 Subject: [PATCH 11/35] [Diagnostics] NFC: Add `isRawRepresentable/conformsToKnownProtocol` helpers into `FailureDiagnostic` --- lib/Sema/CSDiagnostics.cpp | 31 ++++++++++++++++++++----------- lib/Sema/CSDiagnostics.h | 6 ++++-- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index 400e08fbce8ea..d89fb35925a96 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -150,6 +150,18 @@ Type FailureDiagnostic::restoreGenericParameters( }); } +bool FailureDiagnostic::conformsToKnownProtocol( + Type type, KnownProtocolKind protocol) const { + auto &cs = getConstraintSystem(); + return constraints::conformsToKnownProtocol(cs, type, protocol); +} + +Type FailureDiagnostic::isRawRepresentable(Type type, + KnownProtocolKind protocol) const { + auto &cs = getConstraintSystem(); + return constraints::isRawRepresentable(cs, type, protocol); +} + Type RequirementFailure::getOwnerType() const { auto anchor = getRawAnchor(); @@ -2406,9 +2418,8 @@ bool ContextualFailure::diagnoseConversionToBool() const { // If we're trying to convert something from optional type to an integer, then // a comparison against nil was probably expected. - auto &cs = getConstraintSystem(); - if (conformsToKnownProtocol(cs, fromType, KnownProtocolKind::BinaryInteger) && - conformsToKnownProtocol(cs, fromType, + if (conformsToKnownProtocol(fromType, KnownProtocolKind::BinaryInteger) && + conformsToKnownProtocol(fromType, KnownProtocolKind::ExpressibleByIntegerLiteral)) { StringRef prefix = "(("; StringRef suffix; @@ -2503,7 +2514,6 @@ bool ContextualFailure::diagnoseYieldByReferenceMismatch() const { bool ContextualFailure::tryRawRepresentableFixIts( InFlightDiagnostic &diagnostic, KnownProtocolKind rawRepresentableProtocol) const { - auto &CS = getConstraintSystem(); auto anchor = getAnchor(); auto fromType = getFromType(); auto toType = getToType(); @@ -2558,14 +2568,14 @@ bool ContextualFailure::tryRawRepresentableFixIts( } }; - if (conformsToKnownProtocol(CS, fromType, rawRepresentableProtocol)) { - if (conformsToKnownProtocol(CS, fromType, KnownProtocolKind::OptionSet) && + if (conformsToKnownProtocol(fromType, rawRepresentableProtocol)) { + if (conformsToKnownProtocol(fromType, KnownProtocolKind::OptionSet) && isExpr(anchor) && castToExpr(anchor)->getDigitsText() == "0") { diagnostic.fixItReplace(::getSourceRange(anchor), "[]"); return true; } - if (auto rawTy = isRawRepresentable(CS, toType, rawRepresentableProtocol)) { + if (auto rawTy = isRawRepresentable(toType, rawRepresentableProtocol)) { // Produce before/after strings like 'Result(rawValue: RawType())' // or just 'Result(rawValue: )'. std::string convWrapBefore = toType.getString(); @@ -2595,8 +2605,8 @@ bool ContextualFailure::tryRawRepresentableFixIts( } } - if (auto rawTy = isRawRepresentable(CS, fromType, rawRepresentableProtocol)) { - if (conformsToKnownProtocol(CS, toType, rawRepresentableProtocol)) { + if (auto rawTy = isRawRepresentable(fromType, rawRepresentableProtocol)) { + if (conformsToKnownProtocol(toType, rawRepresentableProtocol)) { std::string convWrapBefore; std::string convWrapAfter = ".rawValue"; if (!TypeChecker::isConvertibleTo(rawTy, toType, getDC())) { @@ -2877,12 +2887,11 @@ void ContextualFailure::tryComputedPropertyFixIts() const { } bool ContextualFailure::isIntegerToStringIndexConversion() const { - auto &cs = getConstraintSystem(); auto kind = KnownProtocolKind::ExpressibleByIntegerLiteral; auto fromType = getFromType(); auto toType = getToType()->getCanonicalType(); - return (conformsToKnownProtocol(cs, fromType, kind) && + return (conformsToKnownProtocol(fromType, kind) && toType.getString() == "String.CharacterView.Index"); } diff --git a/lib/Sema/CSDiagnostics.h b/lib/Sema/CSDiagnostics.h index cc91fb0007dc3..767749eef03e0 100644 --- a/lib/Sema/CSDiagnostics.h +++ b/lib/Sema/CSDiagnostics.h @@ -216,6 +216,9 @@ class FailureDiagnostic { auto &cs = getConstraintSystem(); return bool(cs.isArrayType(type)); } + + bool conformsToKnownProtocol(Type type, KnownProtocolKind protocol) const; + Type isRawRepresentable(Type type, KnownProtocolKind protocol) const; }; /// Base class for all of the diagnostics related to generic requirement @@ -672,8 +675,7 @@ class ContextualFailure : public FailureDiagnostic { bool isIntegerType(Type type) const { return conformsToKnownProtocol( - getConstraintSystem(), type, - KnownProtocolKind::ExpressibleByIntegerLiteral); + type, KnownProtocolKind::ExpressibleByIntegerLiteral); } /// Return true if the conversion from fromType to toType is From e34ee7b61cb149d58056227a08bbf8554a310ed8 Mon Sep 17 00:00:00 2001 From: Valeriy Van Date: Fri, 1 May 2020 22:52:34 +0200 Subject: [PATCH 12/35] Fixes example snippet in MemoryLayout.swift --- stdlib/public/core/MemoryLayout.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/public/core/MemoryLayout.swift b/stdlib/public/core/MemoryLayout.swift index b381844e8724d..79dd42d55386d 100644 --- a/stdlib/public/core/MemoryLayout.swift +++ b/stdlib/public/core/MemoryLayout.swift @@ -37,8 +37,8 @@ /// /// let count = 4 /// let pointPointer = UnsafeMutableRawPointer.allocate( -/// bytes: count * MemoryLayout.stride, -/// alignedTo: MemoryLayout.alignment) +/// byteCount: count * MemoryLayout.stride, +/// alignment: MemoryLayout.alignment) @frozen // namespace public enum MemoryLayout { /// The contiguous memory footprint of `T`, in bytes. From 786b16ce82559c076eb18e77328f75ee5017b32d Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Fri, 1 May 2020 14:09:33 -0700 Subject: [PATCH 13/35] [Diagnostics] NFC: Switch to which doesn't require constraint system --- lib/Sema/CSDiagnostics.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index d89fb35925a96..7d9d908b5db0e 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -52,16 +52,20 @@ bool FailureDiagnostic::diagnoseAsNote() { } ASTNode FailureDiagnostic::getAnchor() const { - auto &cs = getConstraintSystem(); - auto *locator = getLocator(); // Resolve the locator to a specific expression. - SourceRange range; - ConstraintLocator *resolved = simplifyLocator(cs, locator, range); - if (!resolved || !resolved->getAnchor()) - return locator->getAnchor(); - auto anchor = resolved->getAnchor(); + auto anchor = locator->getAnchor(); + + { + SourceRange range; + auto path = locator->getPath(); + + simplifyLocator(anchor, path, range); + if (!anchor) + return locator->getAnchor(); + } + // FIXME: Work around an odd locator representation that doesn't separate the // base of a subscript member from the member access. if (locator->isLastElement()) { @@ -3148,12 +3152,18 @@ bool MissingPropertyWrapperUnwrapFailure::diagnoseAsError() { } bool SubscriptMisuseFailure::diagnoseAsError() { + auto *locator = getLocator(); auto &sourceMgr = getASTContext().SourceMgr; auto *memberExpr = castToExpr(getRawAnchor()); auto memberRange = getSourceRange(); - (void)simplifyLocator(getConstraintSystem(), getLocator(), memberRange); + + { + auto rawAnchor = getRawAnchor(); + auto path = locator->getPath(); + simplifyLocator(rawAnchor, path, memberRange); + } auto nameLoc = DeclNameLoc(memberRange.Start); @@ -3183,7 +3193,7 @@ bool SubscriptMisuseFailure::diagnoseAsError() { } diag.flush(); - if (auto overload = getOverloadChoiceIfAvailable(getLocator())) { + if (auto overload = getOverloadChoiceIfAvailable(locator)) { emitDiagnosticAt(overload->choice.getDecl(), diag::kind_declared_here, DescriptiveDeclKind::Subscript); } From f1fcec14f4560b88952301e42e1ab4e65a0a822e Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Fri, 1 May 2020 14:56:01 -0700 Subject: [PATCH 14/35] [Test] Generalize api-digester tests to all platforms. The API digester tests were being run only for macOS, mainly because they were not using %target-swift consistently. Lift the unnecessary restriction so we run these tests more widely. --- test/api-digester/apinotes-diags.swift | 1 - test/api-digester/apinotes-migrator-gen.swift | 1 - test/api-digester/clang-module-dump.swift | 3 +-- test/api-digester/compare-dump-abi.swift | 4 ++-- test/api-digester/compare-dump.swift | 10 +++++----- test/api-digester/compare-two-sdks.swift | 2 +- test/api-digester/dump-empty-baseline.swift | 1 - test/api-digester/dump-module.swift | 3 ++- test/api-digester/internal-extension.swift | 4 ++-- test/api-digester/lit.local.cfg | 5 ----- test/api-digester/macro-gen-json.swift | 4 ++-- test/api-digester/macro-gen.swift | 4 ++-- test/lit.cfg | 4 ++++ 13 files changed, 21 insertions(+), 25 deletions(-) delete mode 100644 test/api-digester/lit.local.cfg diff --git a/test/api-digester/apinotes-diags.swift b/test/api-digester/apinotes-diags.swift index 491919c51837f..0ced9ba43e0ca 100644 --- a/test/api-digester/apinotes-diags.swift +++ b/test/api-digester/apinotes-diags.swift @@ -1,4 +1,3 @@ -// REQUIRES: OS=macosx // RUN: %empty-directory(%t.mod) // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) diff --git a/test/api-digester/apinotes-migrator-gen.swift b/test/api-digester/apinotes-migrator-gen.swift index e6af1dc2faa9b..8b3e76bca280d 100644 --- a/test/api-digester/apinotes-migrator-gen.swift +++ b/test/api-digester/apinotes-migrator-gen.swift @@ -1,4 +1,3 @@ -// REQUIRES: OS=macosx // RUN: %empty-directory(%t.mod) // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) diff --git a/test/api-digester/clang-module-dump.swift b/test/api-digester/clang-module-dump.swift index 5931134255ad8..766ee1295d62a 100644 --- a/test/api-digester/clang-module-dump.swift +++ b/test/api-digester/clang-module-dump.swift @@ -1,6 +1,5 @@ -// REQUIRES: OS=macosx // RUN: %empty-directory(%t.mod) // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) // RUN: %api-digester -dump-sdk -module Foo -o %t.result -module-cache-path %t.module-cache %clang-importer-sdk-nosource -swift-version 4 -I %S/Inputs/Foo -avoid-location -avoid-tool-args -// RUN: diff -u %S/Outputs/clang-module-dump.txt %t.result \ No newline at end of file +// RUN: diff -u %S/Outputs/clang-module-dump.txt %t.result diff --git a/test/api-digester/compare-dump-abi.swift b/test/api-digester/compare-dump-abi.swift index e1b6330387e9d..23778ad881212 100644 --- a/test/api-digester/compare-dump-abi.swift +++ b/test/api-digester/compare-dump-abi.swift @@ -4,8 +4,8 @@ // RUN: %empty-directory(%t.module-cache) // RUN: %empty-directory(%t.baseline/ABI) -// RUN: %swift -emit-module -o %t.mod1/cake.swiftmodule %S/Inputs/cake_baseline/cake.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource -emit-module-source-info -emit-module-source-info-path %t.mod1/cake.swiftsourceinfo 2> %t.compiler-diags -// RUN: %swift -emit-module -o %t.mod2/cake.swiftmodule %S/Inputs/cake_current/cake.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource -emit-module-source-info -emit-module-source-info-path %t.mod2/cake.swiftsourceinfo +// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod1/cake.swiftmodule %S/Inputs/cake_baseline/cake.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource -emit-module-source-info -emit-module-source-info-path %t.mod1/cake.swiftsourceinfo 2> %t.compiler-diags +// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod2/cake.swiftmodule %S/Inputs/cake_current/cake.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource -emit-module-source-info -emit-module-source-info-path %t.mod2/cake.swiftsourceinfo // RUN: %api-digester -dump-sdk -module cake -output-dir %t.baseline -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod1 -I %S/Inputs/APINotesLeft -abi // RUN: %api-digester -diagnose-sdk -print-module -baseline-dir %t.baseline -module cake -I %t.mod2 -I %S/Inputs/APINotesLeft -module-cache-path %t.module-cache %clang-importer-sdk-nosource -abi -o %t.result // RUN: %clang -E -P -w -x c %S/Outputs/Cake-abi.txt -o - | sed '/^\s*$/d' > %t.abi.expected diff --git a/test/api-digester/compare-dump.swift b/test/api-digester/compare-dump.swift index c37cecb5d424f..622e3a960bca4 100644 --- a/test/api-digester/compare-dump.swift +++ b/test/api-digester/compare-dump.swift @@ -2,8 +2,8 @@ // RUN: %empty-directory(%t.mod2) // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) -// RUN: %swift -emit-module -o %t.mod1/cake.swiftmodule %S/Inputs/cake_baseline/cake.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource -module-name cake -// RUN: %swift -emit-module -o %t.mod2/cake.swiftmodule %S/Inputs/cake_current/cake.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource -module-name cake +// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod1/cake.swiftmodule %S/Inputs/cake_baseline/cake.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource -module-name cake +// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod2/cake.swiftmodule %S/Inputs/cake_current/cake.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource -module-name cake // RUN: %api-digester -dump-sdk -module cake -o %t.dump1.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod1 -I %S/Inputs/APINotesLeft // RUN: %api-digester -dump-sdk -module cake -o %t.dump2.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod2 -I %S/Inputs/APINotesRight // RUN: %api-digester -diagnose-sdk -print-module --input-paths %t.dump1.json -input-paths %t.dump2.json -o %t.result @@ -13,15 +13,15 @@ // RUN: diff -u %t.expected %t.result.tmp // Compare color against an empty baseline -// RUN: %swift -emit-module -o %t.mod1/color.swiftmodule %S/Inputs/cake_baseline/color.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource -module-name color +// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod1/color.swiftmodule %S/Inputs/cake_baseline/color.swift -parse-as-library -enable-library-evolution -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource -module-name color // RUN: %api-digester -diagnose-sdk -o %t.result -empty-baseline -I %S/Inputs/APINotesLeft -I %t.mod1 %clang-importer-sdk-nosource -module color -abi // RUN: %clang -E -P -x c %S/Outputs/color_vs_empty.txt -o - | sed '/^\s*$/d' > %t.expected // RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp // RUN: diff -u %t.expected %t.result.tmp // Run another module API checking without -enable-library-evolution -// RUN: %swift -emit-module -o %t.mod1/color.swiftmodule %S/Inputs/cake_baseline/color.swift -parse-as-library -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource -module-name color -// RUN: %swift -emit-module -o %t.mod2/color.swiftmodule %S/Inputs/cake_current/color.swift -parse-as-library -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource -module-name color +// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod1/color.swiftmodule %S/Inputs/cake_baseline/color.swift -parse-as-library -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource -module-name color +// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod2/color.swiftmodule %S/Inputs/cake_current/color.swift -parse-as-library -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource -module-name color // RUN: %api-digester -dump-sdk -module color -o - -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod1 -I %S/Inputs/APINotesLeft > %t.dump1.json // RUN: %api-digester -dump-sdk -module color -o - -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod2 -I %S/Inputs/APINotesLeft > %t.dump2.json // RUN: %api-digester -diagnose-sdk -print-module --input-paths %t.dump1.json -input-paths %t.dump2.json -o %t.result diff --git a/test/api-digester/compare-two-sdks.swift b/test/api-digester/compare-two-sdks.swift index f33596a0025c5..f034e359803cb 100644 --- a/test/api-digester/compare-two-sdks.swift +++ b/test/api-digester/compare-two-sdks.swift @@ -5,7 +5,7 @@ // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) -// RUN: %api-digester -diagnose-sdk -print-module -module-list-file %S/Inputs/mock-sdk-modules.txt -sdk %S/Inputs/mock-sdk.sdk -bsdk %S/Inputs/mock-sdk-baseline.sdk -module-cache-path %t.module-cache -o %t.result -abort-on-module-fail -target x86_64-apple-macos10.14 +// RUN: %api-digester -diagnose-sdk -print-module -module-list-file %S/Inputs/mock-sdk-modules.txt -sdk %S/Inputs/mock-sdk.sdk -bsdk %S/Inputs/mock-sdk-baseline.sdk -module-cache-path %t.module-cache -o %t.result -abort-on-module-fail // RUN: %clang -E -P -x c %S/Outputs/mock-sdk-api.txt -o - | sed '/^\s*$/d' > %t.expected // RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp diff --git a/test/api-digester/dump-empty-baseline.swift b/test/api-digester/dump-empty-baseline.swift index 62cde9696fed6..f61fde643ed5d 100644 --- a/test/api-digester/dump-empty-baseline.swift +++ b/test/api-digester/dump-empty-baseline.swift @@ -1,4 +1,3 @@ -// REQUIRES: OS=macosx // RUN: %empty-directory(%t.mod) // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) diff --git a/test/api-digester/dump-module.swift b/test/api-digester/dump-module.swift index 16fcf02c5857e..c0bdcb213a869 100644 --- a/test/api-digester/dump-module.swift +++ b/test/api-digester/dump-module.swift @@ -1,7 +1,8 @@ +// REQUIRES: macosx // RUN: %empty-directory(%t.mod) // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) -// RUN: %swift -emit-module -o %t.mod/cake.swiftmodule %S/Inputs/cake.swift -parse-as-library -I %S/Inputs/ClangCake %clang-importer-sdk-nosource +// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod/cake.swiftmodule %S/Inputs/cake.swift -parse-as-library -I %S/Inputs/ClangCake %clang-importer-sdk-nosource // RUN: %api-digester -dump-sdk -module cake -o %t.dump.json -module-cache-path %t.module-cache -swift-only -I %t.mod -I %S/Inputs/ClangCake %clang-importer-sdk-nosource -avoid-tool-args // RUN: diff -u %S/Outputs/cake.json %t.dump.json // RUN: %api-digester -dump-sdk -module cake -o %t.dump.json -module-cache-path %t.module-cache -swift-only -I %t.mod -abi -I %S/Inputs/ClangCake %clang-importer-sdk-nosource -avoid-tool-args diff --git a/test/api-digester/internal-extension.swift b/test/api-digester/internal-extension.swift index c9867ceabc6e6..c4537fb4b16c3 100644 --- a/test/api-digester/internal-extension.swift +++ b/test/api-digester/internal-extension.swift @@ -1,8 +1,8 @@ // RUN: %empty-directory(%t.mod) // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) -// RUN: %swift -emit-module -o %t.mod/cake.swiftmodule %S/Inputs/cake.swift -parse-as-library -I %S/Inputs/ClangCake %clang-importer-sdk-nosource -// RUN: %swift -emit-module -o %t.mod/main.swiftmodule %s -parse-as-library -I %t.mod -I %S/Inputs/ClangCake %clang-importer-sdk-nosource +// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod/cake.swiftmodule %S/Inputs/cake.swift -parse-as-library -I %S/Inputs/ClangCake %clang-importer-sdk-nosource +// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod/main.swiftmodule %s -parse-as-library -I %t.mod -I %S/Inputs/ClangCake %clang-importer-sdk-nosource // RUN: %api-digester -dump-sdk -module main -o %t.dump.json -module-cache-path %t.module-cache -swift-only -I %t.mod -I %S/Inputs/ClangCake %clang-importer-sdk-nosource // RUN: %FileCheck %s < %t.dump.json diff --git a/test/api-digester/lit.local.cfg b/test/api-digester/lit.local.cfg deleted file mode 100644 index 92e6a855c61cf..0000000000000 --- a/test/api-digester/lit.local.cfg +++ /dev/null @@ -1,5 +0,0 @@ -if 'OS=macosx' not in config.available_features: - config.unsupported = True - -else: - config.substitutions.append(('%api-digester', config.swift_api_digester)) diff --git a/test/api-digester/macro-gen-json.swift b/test/api-digester/macro-gen-json.swift index 051bba4d7547f..567e544e127ae 100644 --- a/test/api-digester/macro-gen-json.swift +++ b/test/api-digester/macro-gen-json.swift @@ -1,8 +1,8 @@ // RUN: %empty-directory(%t.mod) // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) -// RUN: %swift -emit-module -o %t.mod/macrogenleft.swiftmodule %S/Inputs/macro-gen-left.swift -parse-as-library -// RUN: %swift -emit-module -o %t.mod/macrogenright.swiftmodule %S/Inputs/macro-gen-right.swift -parse-as-library +// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod/macrogenleft.swiftmodule %S/Inputs/macro-gen-left.swift -parse-as-library +// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod/macrogenright.swiftmodule %S/Inputs/macro-gen-right.swift -parse-as-library // RUN: %api-digester -dump-sdk -module macrogenleft -o %t.dump1.json -module-cache-path %t.module-cache -sdk %t.sdk -I %t.mod -migrator // RUN: %api-digester -dump-sdk -module macrogenright -o %t.dump2.json -module-cache-path %t.module-cache -sdk %t.sdk -I %t.mod -migrator // RUN: %api-digester -generate-migration-script --input-paths %t.dump1.json -input-paths %t.dump2.json -o %t.result -json diff --git a/test/api-digester/macro-gen.swift b/test/api-digester/macro-gen.swift index 58267751f4c02..5cb9d5513a0f5 100644 --- a/test/api-digester/macro-gen.swift +++ b/test/api-digester/macro-gen.swift @@ -1,8 +1,8 @@ // RUN: %empty-directory(%t.mod) // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) -// RUN: %swift -emit-module -o %t.mod/macrogenleft.swiftmodule %S/Inputs/macro-gen-left.swift -parse-as-library -// RUN: %swift -emit-module -o %t.mod/macrogenright.swiftmodule %S/Inputs/macro-gen-right.swift -parse-as-library +// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod/macrogenleft.swiftmodule %S/Inputs/macro-gen-left.swift -parse-as-library +// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod/macrogenright.swiftmodule %S/Inputs/macro-gen-right.swift -parse-as-library // RUN: %api-digester -dump-sdk -module macrogenleft -o %t.dump1.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 4 -I %t.mod -migrator // RUN: %api-digester -dump-sdk -module macrogenright -o %t.dump2.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 5 -I %t.mod -migrator // RUN: %api-digester -generate-migration-script --input-paths %t.dump1.json -input-paths %t.dump2.json -o %t.result diff --git a/test/lit.cfg b/test/lit.cfg index 89f578cefbf00..5d67e1403481b 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -1345,6 +1345,10 @@ else: lit_config.fatal("Don't know how to define target_run and " "target_build_swift for platform " + config.variant_triple) +config.swift_api_digester = ( + '%s -target %s' % (config.swift_api_digester, config.variant_triple)) +config.substitutions.append(('%api-digester', config.swift_api_digester)) + # Enable typo-correction for testing purposes. config.target_swift_frontend += " -typo-correction-limit 10 " subst_target_swift_frontend_mock_sdk += " -typo-correction-limit 10 " From 6d12fa0a830753183af35762eac3ea7a4feed962 Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Sat, 2 May 2020 01:10:13 +0300 Subject: [PATCH 15/35] [Gardening] Fix repeated word in diagnostic message --- include/swift/AST/DiagnosticsSema.def | 2 +- .../special/coding/class_codable_failure_diagnostics.swift | 2 +- .../special/coding/class_codable_simple_conditional.swift | 2 +- .../coding/class_codable_simple_conditional_separate.swift | 2 +- .../special/coding/class_codable_simple_extension.swift | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index e225c26427bbd..5378756985ba1 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -2686,7 +2686,7 @@ ERROR(implementation_only_override_import_without_attr,none, // Derived conformances ERROR(cannot_synthesize_init_in_extension_of_nonfinal,none, "implementation of %0 for non-final class cannot be automatically " - "synthesized in extension because initializer requirement %1 can only be " + "synthesized in extension because initializer requirement %1 can only " "be satisfied by a 'required' initializer in the class definition", (Type, DeclName)) ERROR(cannot_synthesize_in_crossfile_extension,none, diff --git a/test/decl/protocol/special/coding/class_codable_failure_diagnostics.swift b/test/decl/protocol/special/coding/class_codable_failure_diagnostics.swift index f6b8c0b6f3ffd..ba35fb4e92e4a 100644 --- a/test/decl/protocol/special/coding/class_codable_failure_diagnostics.swift +++ b/test/decl/protocol/special/coding/class_codable_failure_diagnostics.swift @@ -112,7 +112,7 @@ class C6 : Codable { // Non-final classes cannot synthesize Decodable in an extension. class C7 {} extension C7 : Decodable {} -// expected-error@-1 {{implementation of 'Decodable' for non-final class cannot be automatically synthesized in extension because initializer requirement 'init(from:)' can only be be satisfied by a 'required' initializer in the class definition}} +// expected-error@-1 {{implementation of 'Decodable' for non-final class cannot be automatically synthesized in extension because initializer requirement 'init(from:)' can only be satisfied by a 'required' initializer in the class definition}} // Check that the diagnostics from an extension end up on the extension class C8 { diff --git a/test/decl/protocol/special/coding/class_codable_simple_conditional.swift b/test/decl/protocol/special/coding/class_codable_simple_conditional.swift index e9268afea2640..6dd447e6508d5 100644 --- a/test/decl/protocol/special/coding/class_codable_simple_conditional.swift +++ b/test/decl/protocol/special/coding/class_codable_simple_conditional.swift @@ -22,7 +22,7 @@ class Conditional { } extension Conditional: Codable where T: Codable { // expected-note 2 {{where 'T' = 'Nonconforming'}} - // expected-error@-1 2 {{implementation of 'Decodable' for non-final class cannot be automatically synthesized in extension because initializer requirement 'init(from:)' can only be be satisfied by a 'required' initializer in the class definition}} + // expected-error@-1 2 {{implementation of 'Decodable' for non-final class cannot be automatically synthesized in extension because initializer requirement 'init(from:)' can only be satisfied by a 'required' initializer in the class definition}} } // They should receive synthesized init(from:) and an encode(to:). diff --git a/test/decl/protocol/special/coding/class_codable_simple_conditional_separate.swift b/test/decl/protocol/special/coding/class_codable_simple_conditional_separate.swift index 6fa14f24fc8aa..0033a58b734a8 100644 --- a/test/decl/protocol/special/coding/class_codable_simple_conditional_separate.swift +++ b/test/decl/protocol/special/coding/class_codable_simple_conditional_separate.swift @@ -25,7 +25,7 @@ extension Conditional: Encodable where T: Encodable { // expected-note {{where ' } extension Conditional: Decodable where T: Decodable { - // expected-error@-1 2 {{implementation of 'Decodable' for non-final class cannot be automatically synthesized in extension because initializer requirement 'init(from:)' can only be be satisfied by a 'required' initializer in the class definition}} + // expected-error@-1 2 {{implementation of 'Decodable' for non-final class cannot be automatically synthesized in extension because initializer requirement 'init(from:)' can only be satisfied by a 'required' initializer in the class definition}} } struct OnlyEnc: Encodable {} diff --git a/test/decl/protocol/special/coding/class_codable_simple_extension.swift b/test/decl/protocol/special/coding/class_codable_simple_extension.swift index dc37466a2b519..90b21c3331f00 100644 --- a/test/decl/protocol/special/coding/class_codable_simple_extension.swift +++ b/test/decl/protocol/special/coding/class_codable_simple_extension.swift @@ -20,7 +20,7 @@ class SimpleClass { // expected-note {{did you mean 'init'?}} } } -extension SimpleClass : Codable {} // expected-error 2 {{implementation of 'Decodable' for non-final class cannot be automatically synthesized in extension because initializer requirement 'init(from:)' can only be be satisfied by a 'required' initializer in the class definition}} +extension SimpleClass : Codable {} // expected-error 2 {{implementation of 'Decodable' for non-final class cannot be automatically synthesized in extension because initializer requirement 'init(from:)' can only be satisfied by a 'required' initializer in the class definition}} // They should not receive synthesized init(from:), but should receive an encode(to:). let _ = SimpleClass.init(from:) // expected-error {{type 'SimpleClass' has no member 'init(from:)'}} From 72f1beab28c9b2ae637dada806371363cc2929f2 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Fri, 1 May 2020 15:58:46 -0700 Subject: [PATCH 16/35] [Test] Downscope api-digester generalization to all *Apple* platforms --- test/api-digester/apinotes-diags.swift | 2 ++ test/api-digester/apinotes-migrator-gen.swift | 2 ++ test/api-digester/clang-module-dump.swift | 2 ++ test/api-digester/compare-clang-dump.swift | 2 ++ test/api-digester/compare-dump-abi-parsable-interface.swift | 2 ++ test/api-digester/compare-dump-abi.swift | 2 ++ test/api-digester/compare-dump-binary-vs-interface.swift | 2 ++ test/api-digester/compare-dump-parsable-interface.swift | 2 ++ test/api-digester/compare-dump.swift | 2 ++ test/api-digester/internal-extension.swift | 2 ++ 10 files changed, 20 insertions(+) diff --git a/test/api-digester/apinotes-diags.swift b/test/api-digester/apinotes-diags.swift index 0ced9ba43e0ca..27d8d8ebabd7d 100644 --- a/test/api-digester/apinotes-diags.swift +++ b/test/api-digester/apinotes-diags.swift @@ -1,3 +1,5 @@ +// REQUIRES: VENDOR=apple + // RUN: %empty-directory(%t.mod) // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) diff --git a/test/api-digester/apinotes-migrator-gen.swift b/test/api-digester/apinotes-migrator-gen.swift index 8b3e76bca280d..024ce868683db 100644 --- a/test/api-digester/apinotes-migrator-gen.swift +++ b/test/api-digester/apinotes-migrator-gen.swift @@ -1,3 +1,5 @@ +// REQUIRES: VENDOR=apple + // RUN: %empty-directory(%t.mod) // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) diff --git a/test/api-digester/clang-module-dump.swift b/test/api-digester/clang-module-dump.swift index 766ee1295d62a..3893a2abdd3f7 100644 --- a/test/api-digester/clang-module-dump.swift +++ b/test/api-digester/clang-module-dump.swift @@ -1,3 +1,5 @@ +// REQUIRES: VENDOR=apple + // RUN: %empty-directory(%t.mod) // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) diff --git a/test/api-digester/compare-clang-dump.swift b/test/api-digester/compare-clang-dump.swift index 26bf62b0cd78d..5aa14b0702cc8 100644 --- a/test/api-digester/compare-clang-dump.swift +++ b/test/api-digester/compare-clang-dump.swift @@ -1,3 +1,5 @@ +// REQUIRES: VENDOR=apple + // RUN: %empty-directory(%t.module-cache) // RUN: %api-digester -dump-sdk -module Foo -o %t.dump1.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %S/Inputs/Foo -avoid-location // RUN: %api-digester -dump-sdk -module Foo -o %t.dump2.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %S/Inputs/Foo-new-version -avoid-location diff --git a/test/api-digester/compare-dump-abi-parsable-interface.swift b/test/api-digester/compare-dump-abi-parsable-interface.swift index b0645b417fcc5..30450a6d3575a 100644 --- a/test/api-digester/compare-dump-abi-parsable-interface.swift +++ b/test/api-digester/compare-dump-abi-parsable-interface.swift @@ -1,3 +1,5 @@ +// REQUIRES: VENDOR=apple + // RUN: %empty-directory(%t.mod1) // RUN: %empty-directory(%t.mod2) // RUN: %empty-directory(%t.sdk) diff --git a/test/api-digester/compare-dump-abi.swift b/test/api-digester/compare-dump-abi.swift index 23778ad881212..53914a0051ee1 100644 --- a/test/api-digester/compare-dump-abi.swift +++ b/test/api-digester/compare-dump-abi.swift @@ -1,3 +1,5 @@ +// REQUIRES: VENDOR=apple + // RUN: %empty-directory(%t.mod1) // RUN: %empty-directory(%t.mod2) // RUN: %empty-directory(%t.sdk) diff --git a/test/api-digester/compare-dump-binary-vs-interface.swift b/test/api-digester/compare-dump-binary-vs-interface.swift index a0466f0dc6407..11a42e7e371de 100644 --- a/test/api-digester/compare-dump-binary-vs-interface.swift +++ b/test/api-digester/compare-dump-binary-vs-interface.swift @@ -1,3 +1,5 @@ +// REQUIRES: VENDOR=apple + // RUN: %empty-directory(%t.mod1) // RUN: %empty-directory(%t.mod2) // RUN: %empty-directory(%t.sdk) diff --git a/test/api-digester/compare-dump-parsable-interface.swift b/test/api-digester/compare-dump-parsable-interface.swift index b06c30ac97d7d..38db90b4e9e84 100644 --- a/test/api-digester/compare-dump-parsable-interface.swift +++ b/test/api-digester/compare-dump-parsable-interface.swift @@ -1,3 +1,5 @@ +// REQUIRES: VENDOR=apple + // RUN: %empty-directory(%t.mod1) // RUN: %empty-directory(%t.mod2) // RUN: %empty-directory(%t.sdk) diff --git a/test/api-digester/compare-dump.swift b/test/api-digester/compare-dump.swift index 622e3a960bca4..029ae740d2e2e 100644 --- a/test/api-digester/compare-dump.swift +++ b/test/api-digester/compare-dump.swift @@ -1,3 +1,5 @@ +// REQUIRES: VENDOR=apple + // RUN: %empty-directory(%t.mod1) // RUN: %empty-directory(%t.mod2) // RUN: %empty-directory(%t.sdk) diff --git a/test/api-digester/internal-extension.swift b/test/api-digester/internal-extension.swift index c4537fb4b16c3..76c9ebb385d85 100644 --- a/test/api-digester/internal-extension.swift +++ b/test/api-digester/internal-extension.swift @@ -1,3 +1,5 @@ +// REQUIRES: VENDOR=apple + // RUN: %empty-directory(%t.mod) // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) From 89464353ac451b2d0a5c073bcab1e87d4b6eb68f Mon Sep 17 00:00:00 2001 From: Alex Martini Date: Fri, 1 May 2020 16:01:15 -0700 Subject: [PATCH 17/35] Remove stray backtick in docs. Fixes --- stdlib/public/core/Dictionary.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/public/core/Dictionary.swift b/stdlib/public/core/Dictionary.swift index eeb9d72117ef6..90ddae2229bad 100644 --- a/stdlib/public/core/Dictionary.swift +++ b/stdlib/public/core/Dictionary.swift @@ -879,7 +879,7 @@ extension Dictionary { /// - key: The key the look up in the dictionary. /// - defaultValue: The default value to use if `key` doesn't exist in the /// dictionary. - /// - Returns: The value associated with `key` in the dictionary`; otherwise, + /// - Returns: The value associated with `key` in the dictionary; otherwise, /// `defaultValue`. @inlinable public subscript( From deb25e115f5dff7b70a08a29f3646b4843255d10 Mon Sep 17 00:00:00 2001 From: Frederick Kellison-Linn Date: Fri, 1 May 2020 19:13:38 -0400 Subject: [PATCH 18/35] Append newline to printout of "Defaulted constraints" --- lib/Sema/TypeCheckConstraints.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp index c755e183d4d7b..e16eac57a7bd0 100644 --- a/lib/Sema/TypeCheckConstraints.cpp +++ b/lib/Sema/TypeCheckConstraints.cpp @@ -3921,6 +3921,7 @@ void ConstraintSystem::print(raw_ostream &out) const { }, [&] { out << ", "; }); + out << "\n"; } if (failedConstraint) { From 72807bf284682dccb37fb7de3d5a894512bd9eaa Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Thu, 30 Apr 2020 19:30:51 -0700 Subject: [PATCH 19/35] [NFC] Don't Serialize Pattern::isImplicit --- lib/Serialization/Deserialization.cpp | 19 ++++++------------- lib/Serialization/ModuleFormat.h | 20 +++++++------------- lib/Serialization/Serialization.cpp | 17 ++++++----------- 3 files changed, 19 insertions(+), 37 deletions(-) diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index 87440acb8e829..cd329878502e7 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -315,9 +315,6 @@ Expected ModuleFile::readPattern(DeclContext *owningDC) { fatalIfUnexpected(DeclTypeCursor.readRecord(next.ID, scratch)); switch (kind) { case decls_block::PAREN_PATTERN: { - bool isImplicit; - ParenPatternLayout::readRecord(scratch, isImplicit); - Pattern *subPattern = readPatternUnchecked(owningDC); auto result = ParenPattern::createImplicit(getContext(), subPattern); @@ -333,9 +330,8 @@ Expected ModuleFile::readPattern(DeclContext *owningDC) { case decls_block::TUPLE_PATTERN: { TypeID tupleTypeID; unsigned count; - bool isImplicit; - TuplePatternLayout::readRecord(scratch, tupleTypeID, count, isImplicit); + TuplePatternLayout::readRecord(scratch, tupleTypeID, count); SmallVector elements; for ( ; count > 0; --count) { @@ -363,8 +359,7 @@ Expected ModuleFile::readPattern(DeclContext *owningDC) { case decls_block::NAMED_PATTERN: { DeclID varID; TypeID typeID; - bool isImplicit; - NamedPatternLayout::readRecord(scratch, varID, typeID, isImplicit); + NamedPatternLayout::readRecord(scratch, varID, typeID); auto deserialized = getDeclChecked(varID); if (!deserialized) { @@ -381,9 +376,8 @@ Expected ModuleFile::readPattern(DeclContext *owningDC) { } case decls_block::ANY_PATTERN: { TypeID typeID; - bool isImplicit; - AnyPatternLayout::readRecord(scratch, typeID, isImplicit); + AnyPatternLayout::readRecord(scratch, typeID); auto result = AnyPattern::createImplicit(getContext()); recordPatternType(result, getType(typeID)); restoreOffset.reset(); @@ -391,8 +385,7 @@ Expected ModuleFile::readPattern(DeclContext *owningDC) { } case decls_block::TYPED_PATTERN: { TypeID typeID; - bool isImplicit; - TypedPatternLayout::readRecord(scratch, typeID, isImplicit); + TypedPatternLayout::readRecord(scratch, typeID); Expected subPattern = readPattern(owningDC); if (!subPattern) { @@ -408,8 +401,8 @@ Expected ModuleFile::readPattern(DeclContext *owningDC) { return result; } case decls_block::VAR_PATTERN: { - bool isImplicit, isLet; - VarPatternLayout::readRecord(scratch, isLet, isImplicit); + bool isLet; + VarPatternLayout::readRecord(scratch, isLet); Pattern *subPattern = readPatternUnchecked(owningDC); diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index ca49bee023b5e..5d00fbc3d4d5c 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -55,7 +55,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 555; // add @main attribute +const uint16_t SWIFTMODULE_VERSION_MINOR = 556; // dont serialize Pattern::isImplicit /// A standard hash seed used for all string hashes in a serialized module. /// @@ -1448,16 +1448,14 @@ namespace decls_block { >; using ParenPatternLayout = BCRecordLayout< - PAREN_PATTERN, - BCFixed<1> // implicit? + PAREN_PATTERN // The sub-pattern trails the record. >; using TuplePatternLayout = BCRecordLayout< TUPLE_PATTERN, TypeIDField, // type - BCVBR<5>, // arity - BCFixed<1> // implicit? + BCVBR<5> // arity // The elements trail the record. >; @@ -1470,28 +1468,24 @@ namespace decls_block { using NamedPatternLayout = BCRecordLayout< NAMED_PATTERN, DeclIDField, // associated VarDecl - TypeIDField, // type - BCFixed<1> // implicit? + TypeIDField // type >; using AnyPatternLayout = BCRecordLayout< ANY_PATTERN, - TypeIDField, // type - BCFixed<1> // implicit? + TypeIDField // type // FIXME: is the type necessary? >; using TypedPatternLayout = BCRecordLayout< TYPED_PATTERN, - TypeIDField, // associated type - BCFixed<1> // implicit? + TypeIDField // associated type // The sub-pattern trails the record. >; using VarPatternLayout = BCRecordLayout< VAR_PATTERN, - BCFixed<1>, // isLet? - BCFixed<1> // implicit? + BCFixed<1> // isLet? // The sub-pattern trails the record. >; diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 815c74b32df5f..24992f2b4b051 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -2659,8 +2659,7 @@ class Serializer::DeclSerializer : public DeclVisitor { switch (pattern->getKind()) { case PatternKind::Paren: { unsigned abbrCode = S.DeclTypeAbbrCodes[ParenPatternLayout::Code]; - ParenPatternLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode, - pattern->isImplicit()); + ParenPatternLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode); writePattern(cast(pattern)->getSubPattern()); break; } @@ -2670,8 +2669,7 @@ class Serializer::DeclSerializer : public DeclVisitor { unsigned abbrCode = S.DeclTypeAbbrCodes[TuplePatternLayout::Code]; TuplePatternLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode, S.addTypeRef(getPatternType()), - tuple->getNumElements(), - tuple->isImplicit()); + tuple->getNumElements()); abbrCode = S.DeclTypeAbbrCodes[TuplePatternEltLayout::Code]; for (auto &elt : tuple->getElements()) { @@ -2688,15 +2686,13 @@ class Serializer::DeclSerializer : public DeclVisitor { unsigned abbrCode = S.DeclTypeAbbrCodes[NamedPatternLayout::Code]; NamedPatternLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode, S.addDeclRef(named->getDecl()), - S.addTypeRef(getPatternType()), - named->isImplicit()); + S.addTypeRef(getPatternType())); break; } case PatternKind::Any: { unsigned abbrCode = S.DeclTypeAbbrCodes[AnyPatternLayout::Code]; AnyPatternLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode, - S.addTypeRef(getPatternType()), - pattern->isImplicit()); + S.addTypeRef(getPatternType())); break; } case PatternKind::Typed: { @@ -2704,8 +2700,7 @@ class Serializer::DeclSerializer : public DeclVisitor { unsigned abbrCode = S.DeclTypeAbbrCodes[TypedPatternLayout::Code]; TypedPatternLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode, - S.addTypeRef(getPatternType()), - typed->isImplicit()); + S.addTypeRef(getPatternType())); writePattern(typed->getSubPattern()); break; } @@ -2721,7 +2716,7 @@ class Serializer::DeclSerializer : public DeclVisitor { unsigned abbrCode = S.DeclTypeAbbrCodes[VarPatternLayout::Code]; VarPatternLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode, - var->isLet(), var->isImplicit()); + var->isLet()); writePattern(var->getSubPattern()); break; } From 7161ed01f842869dffa78dac700c85f5d9e1cba2 Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Fri, 1 May 2020 16:30:43 -0700 Subject: [PATCH 20/35] Work Around IDE Structure Markers Structure analysis trusts what should be implicit pattern nodes have the right source location information in them. Preserve that behavior for now. --- lib/Parse/ParsePattern.cpp | 11 ++++++++--- lib/Parse/ParseStmt.cpp | 18 +++++++++++++----- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp index 804783e2e2ab3..f6b28b9c56413 100644 --- a/lib/Parse/ParsePattern.cpp +++ b/lib/Parse/ParsePattern.cpp @@ -887,9 +887,14 @@ ParserResult Parser::parseTypedPattern() { SyntaxParsingContext TypeAnnoCtx(SyntaxContext, SyntaxKind::TypeAnnotation); SourceLoc colonLoc = consumeToken(tok::colon); - if (result.isNull()) // Recover by creating AnyPattern. - result = makeParserErrorResult(new (Context) AnyPattern(colonLoc)); - + if (result.isNull()) { + // Recover by creating AnyPattern. + auto *AP = new (Context) AnyPattern(colonLoc); + if (colonLoc.isInvalid()) + AP->setImplicit(); + result = makeParserErrorResult(AP); + } + ParserResult Ty = parseDeclResultType(diag::expected_type); if (Ty.hasCodeCompletion()) return makeParserCodeCompletionResult(); diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index eea7b920e5c3e..80a5ab62d56de 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -1108,9 +1108,12 @@ static void parseGuardedPattern(Parser &P, GuardedPattern &result, // If that didn't work, use a bogus pattern so that we can fill out // the AST. - if (patternResult.isNull()) - patternResult = - makeParserErrorResult(new (P.Context) AnyPattern(P.PreviousLoc)); + if (patternResult.isNull()) { + auto *AP = new (P.Context) AnyPattern(P.PreviousLoc); + if (P.PreviousLoc.isInvalid()) + AP->setImplicit(); + patternResult = makeParserErrorResult(AP); + } // Fill in the pattern. status |= patternResult; @@ -1506,7 +1509,10 @@ Parser::parseStmtConditionElement(SmallVectorImpl &result, if (ThePattern.isNull()) { // Recover by creating AnyPattern. - ThePattern = makeParserResult(new (Context) AnyPattern(PreviousLoc)); + auto *AP = new (Context) AnyPattern(PreviousLoc); + if (PreviousLoc.isInvalid()) + AP->setImplicit(); + ThePattern = makeParserResult(AP); } // Conditional bindings must have an initializer. @@ -2133,7 +2139,7 @@ ParserResult Parser::parseStmtForEach(LabeledStmtInfo LabelInfo) { SourceLoc InLoc; if (pattern.isNull()) { // Recover by creating a "_" pattern. - pattern = makeParserErrorResult(new (Context) AnyPattern(SourceLoc())); + pattern = makeParserErrorResult(AnyPattern::createImplicit(Context)); consumeIf(tok::kw_in, InLoc); } else if (!IsCStyleFor) { parseToken(tok::kw_in, InLoc, diag::expected_foreach_in); @@ -2422,6 +2428,8 @@ parseStmtCaseDefault(Parser &P, SourceLoc &CaseLoc, // Create an implicit AnyPattern to represent the default match. auto Any = new (P.Context) AnyPattern(CaseLoc); + if (CaseLoc.isInvalid()) + Any->setImplicit(); LabelItems.push_back( CaseLabelItem::getDefault(Any, WhereLoc, Guard.getPtrOrNull())); From 55006887d1139154cbdc6344be09a61074ff9710 Mon Sep 17 00:00:00 2001 From: Valeriy Van Date: Sat, 2 May 2020 01:40:39 +0200 Subject: [PATCH 21/35] Fixes example snippet in ExistentialCollection.swift (#31462) * Fixes example snippet in ExistentialCollection.swift * Removes extra parentheses --- stdlib/public/core/ExistentialCollection.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/public/core/ExistentialCollection.swift b/stdlib/public/core/ExistentialCollection.swift index 50d2ee925e3be..e01c87095bd2f 100644 --- a/stdlib/public/core/ExistentialCollection.swift +++ b/stdlib/public/core/ExistentialCollection.swift @@ -51,7 +51,7 @@ public struct AnyIterator { /// func digits() -> AnyIterator { /// let lazyStrings = (0..<10).lazy.map { String($0) } /// let iterator: - /// LazyMapIterator>, String> + /// LazyMapSequence, String>.Iterator /// = lazyStrings.makeIterator() /// /// return AnyIterator(iterator) From 532b63273e4c561aeb909ce61397e2191b3bcfee Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Fri, 27 Mar 2020 14:42:36 +0300 Subject: [PATCH 22/35] Sema: Make -debug-generic-signatures output legible --- lib/Sema/TypeCheckDeclPrimary.cpp | 1 + lib/Sema/TypeCheckGeneric.cpp | 5 +++-- lib/Sema/TypeCheckProtocol.cpp | 7 +++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index f159f272e057f..8e16554d2e371 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -2057,6 +2057,7 @@ class DeclChecker : public DeclVisitor { GenericSignature::get({PD->getProtocolSelfType()}, PD->getRequirementSignature()); + llvm::errs() << "\n"; llvm::errs() << "Protocol requirement signature:\n"; PD->dumpRef(llvm::errs()); llvm::errs() << "\n"; diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp index 909d63e6a1f98..06b5c80e31246 100644 --- a/lib/Sema/TypeCheckGeneric.cpp +++ b/lib/Sema/TypeCheckGeneric.cpp @@ -467,12 +467,13 @@ GenericSignature TypeChecker::checkGenericSignature( // Debugging of the generic signature builder and generic signature // generation. if (dc->getASTContext().TypeCheckerOpts.DebugGenericSignatures) { + llvm::errs() << "\n"; if (auto *VD = dyn_cast_or_null(dc->getAsDecl())) { VD->dumpRef(llvm::errs()); + llvm::errs() << "\n"; } else { dc->printContext(llvm::errs()); } - llvm::errs() << "\n"; llvm::errs() << "Generic signature: "; sig->print(llvm::errs()); llvm::errs() << "\n"; @@ -589,8 +590,8 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator, // Debugging of the generic signature builder and generic signature // generation. if (GC->getASTContext().TypeCheckerOpts.DebugGenericSignatures) { - PD->printContext(llvm::errs()); llvm::errs() << "\n"; + PD->printContext(llvm::errs()); llvm::errs() << "Generic signature: "; sig->print(llvm::errs()); llvm::errs() << "\n"; diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index cec432abf23ca..0361f02511988 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -5087,12 +5087,15 @@ void TypeChecker::checkConformancesInContext(DeclContext *dc, // Check all conformances. groupChecker.checkAllConformances(); - if (Context.TypeCheckerOpts.DebugGenericSignatures) { + if (Context.TypeCheckerOpts.DebugGenericSignatures && + !conformances.empty()) { // Now that they're filled out, print out information about the conformances // here, when requested. + llvm::errs() << "\n"; + dc->printContext(llvm::errs()); for (auto conformance : conformances) { - dc->printContext(llvm::errs()); conformance->dump(llvm::errs()); + llvm::errs() << "\n"; } } From fb8e23e94ff99b44d84182906bc2f16179e917cc Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Fri, 1 May 2020 14:36:12 -0700 Subject: [PATCH 23/35] Propagate Failures Explicitly in Opaque Type Resolution This code should not yield the null Type() on failure. Instead, diagnose the failure and yield an ErrorType. This matches what clients of this function expect to signal failure. Include a regression test that exercises a common failure mode if we don't do this: module interface loading crashes. rdar://62745419 --- lib/Sema/TypeCheckType.cpp | 15 ++++++++---- .../invalid-opaque-result-types.swift | 23 +++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 test/ModuleInterface/invalid-opaque-result-types.swift diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index b1d06abde8e49..ce1afd50fc1de 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -2657,8 +2657,10 @@ Type TypeResolver::resolveOpaqueReturnType(TypeRepr *repr, if (auto generic = dyn_cast(repr)) { for (auto argRepr : generic->getGenericArgs()) { auto argTy = resolveType(argRepr, options); - if (!argTy) - return Type(); + // If we cannot resolve the generic parameter, propagate the error out. + if (!argTy || argTy->hasError()) { + return ErrorType::get(Context); + } TypeArgsBuf.push_back(argTy); } } @@ -2666,8 +2668,10 @@ Type TypeResolver::resolveOpaqueReturnType(TypeRepr *repr, // Use type reconstruction to summon the opaque type decl. Demangler demangle; auto definingDeclNode = demangle.demangleSymbol(mangledName); - if (!definingDeclNode) - return Type(); + if (!definingDeclNode) { + diagnose(repr->getLoc(), diag::no_opaque_return_type_of); + return ErrorType::get(Context); + } if (definingDeclNode->getKind() == Node::Kind::Global) definingDeclNode = definingDeclNode->getChild(0); ASTBuilder builder(Context); @@ -2677,8 +2681,9 @@ Type TypeResolver::resolveOpaqueReturnType(TypeRepr *repr, auto TypeArgs = ArrayRef(TypeArgsBuf); auto ty = builder.resolveOpaqueType(opaqueNode, TypeArgs, ordinal); - if (!ty) { + if (!ty || ty->hasError()) { diagnose(repr->getLoc(), diag::no_opaque_return_type_of); + return ErrorType::get(Context); } return ty; } diff --git a/test/ModuleInterface/invalid-opaque-result-types.swift b/test/ModuleInterface/invalid-opaque-result-types.swift new file mode 100644 index 0000000000000..5caefc4c5caeb --- /dev/null +++ b/test/ModuleInterface/invalid-opaque-result-types.swift @@ -0,0 +1,23 @@ +// Test that we emit a diagnostic (and don't crash) when we cannot resolve +// an opaque result type reference. +// +// First, emit an empty module interface: +// +// RUN: %empty-directory(%t) +// RUN: echo "" | %target-swift-frontend -typecheck -emit-module-interface-path %t/InvalidOpaqueResultType.swiftinterface -enable-library-evolution -swift-version 5 -module-name InvalidOpaqueResultType - +// +// Then, blit some invalid opaque result types into the interface +// +// Test that we reject broken type parameters +// RUN: echo "public typealias SomeGenericBalderdash = @_opaqueReturnTypeOf(\"$somesuchnonsense\", 0) 🦸" >> %t/InvalidOpaqueResultType.swiftinterface +// Test that we reject types we cannot demangle +// RUN: echo "public typealias SomesuchNonsense = @_opaqueReturnTypeOf(\"$somesuchnonsense\", 0) 🦸" >> %t/InvalidOpaqueResultType.swiftinterface +// +// The stage is set: +// +// RUN: not %target-swift-frontend -typecheck %s -I %t 2>&1 | %FileCheck %s + +// CHECK: cannot find type 'InvalidParameter' in scope +// CHECK: unable to resolve type for _opaqueReturnTypeOf attribute +// CHECK: failed to build module 'InvalidOpaqueResultType' from its module interface +import InvalidOpaqueResultType From 48651cae07da03ea81508d4d9b54eff53e0bdf28 Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Fri, 1 May 2020 18:33:09 -0700 Subject: [PATCH 24/35] [Gardening] Improve Overview of Evaluator-Based Incremental Dependencies --- docs/RequestEvaluator.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/RequestEvaluator.md b/docs/RequestEvaluator.md index 77c4d37c7c412..7feda0e256cff 100644 --- a/docs/RequestEvaluator.md +++ b/docs/RequestEvaluator.md @@ -53,7 +53,16 @@ The request-evaluator contains a cache of any requests that have already been ev Until then, the request-evaluator lives in a compiler that has mutable ASTs, and will for the foreseeable future. To cope with this, requests can opt for "separate" caching of their results, implementing a simple protocol to query their own cache (`getCachedResult`) and set the value for the cache (`cacheResult`). For now, these functions can directly modify state in the AST, allowing the requests to be mixed with direct mutation of the state. For each request, the intent is to make all state access go through the evaluator, but getting there can be an incremental process. ## Incremental Dependency Tracking -Request evaluation naturally captures the dependency structure of any given invocation of the compiler frontend. In fact, it captures it so well that the request graph trace generated by a select kind of lookup request can be used to completely recover the information relevant to the Swift compiler's incremental compilation subsystem. For these select *dependency-relevant* requests, we can further subdivide them into so-called *dependency sources* and *dependency sinks*. A dependency source is any (usually high-level) request that introduces a new context under which dependencies can be registered. Currently, these are the requests that operate that the level of individual source files. A dependency sink is any (usually lower-level) request that executes as a sub-computation of a dependency source. Any names that are dependency-relevant, such as the result of a lookup in a particular context, are then registered against trackers in the active dependency source (file). Using this, the evaluator pushes and pops sources and sinks automatically as request evaluation proceeds, and sink requests pair automatically to source requests to write out dependency information. + +Request evaluation naturally captures the dependency structure of any given invocation of the compiler frontend. In fact, it captures it so well that the request graph trace generated by a certain kind of lookup request can be used to completely recover the information relevant to the Swift compiler's incremental compilation subsystem. For these select dependency-relevant requests, we can further subdivide them into so-called *dependency sources* and *dependency sinks*. A dependency source is any (usually high-level) request that introduces a new context under which dependencies can be registered. Currently, these are the requests that operate at the level of individual source files. A dependency sink is any (usually lower-level) request that executes as a sub-computation of a dependency source. Any names that are dependency-relevant are then registered against trackers in the active dependency source (file). Using this, the evaluator pushes and pops sources and sinks automatically as request evaluation proceeds, and sink requests pair automatically to source requests to write out dependency information. + +To see an example of this in action, suppose the following chain of requests is currently being evaluated: + +``` +TypeCheckSourceFileRequest(File.swift) -> ... -> DirectLookupRequest(Foo, "bar") +``` + +Because `TypeCheckSourceFileRequest` is a dependency source, `File.swift` is automatically set as the active dependency scope. When the subsequent dependency sink `DirectLookupRequest` completes, it will automatically write the fact that `Foo.bar` has been looked up in the appropriate referenced name tracker in the active source - `File.swift`. To define a request as a dependency source, it must implement an accessor for the new active scope (`readDependencySource`). To define a request as a dependency sink, it must implement a function that writes the result of evaluating the request into the current active source (`writeDependencySink`). From 8e35609df297d9a7ab78775da63f9e58b10fd007 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 30 Apr 2020 22:07:14 -0400 Subject: [PATCH 25/35] IRGen: Sign the class stub initialization callback pointer on arm64e The Objective-C runtime expects a signed pointer here. The existing test would have caught this, except it was always disabled because the symbol name passed to the dlsym() check should not have had the leading '_'. Fixes . --- include/swift/ABI/MetadataValues.h | 3 ++ include/swift/AST/IRGenOptions.h | 3 ++ lib/IRGen/GenClass.cpp | 45 ++++++++++--------- lib/IRGen/GenClass.h | 8 ---- lib/IRGen/GenMeta.cpp | 8 ++-- lib/IRGen/IRGen.cpp | 4 ++ lib/IRGen/IRGenModule.h | 8 ++++ .../class_update_callback_with_stub.swift | 6 +-- validation-test/Runtime/class_stubs.m | 4 +- validation-test/Runtime/class_stubs_weak.m | 6 ++- 10 files changed, 55 insertions(+), 40 deletions(-) diff --git a/include/swift/ABI/MetadataValues.h b/include/swift/ABI/MetadataValues.h index 1da872df3f972..31b60023e1938 100644 --- a/include/swift/ABI/MetadataValues.h +++ b/include/swift/ABI/MetadataValues.h @@ -1164,6 +1164,9 @@ namespace SpecialPointerAuthDiscriminators { /// they're important enough to be worth writing in one place. const uint16_t OpaqueReadResumeFunction = 56769; const uint16_t OpaqueModifyResumeFunction = 3909; + + /// Resilient class stub initializer callback + const uint16_t ResilientClassStubInitCallback = 0xC671; } /// The number of arguments that will be passed directly to a generic diff --git a/include/swift/AST/IRGenOptions.h b/include/swift/AST/IRGenOptions.h index 0d72a2aee209a..0665a1c9ff092 100644 --- a/include/swift/AST/IRGenOptions.h +++ b/include/swift/AST/IRGenOptions.h @@ -122,6 +122,9 @@ struct PointerAuthOptions : clang::PointerAuthOptions { /// Resumption functions from yield-many coroutines. PointerAuthSchema YieldManyResumeFunctions; + + /// Resilient class stub initializer callbacks. + PointerAuthSchema ResilientClassStubInitCallbacks; }; /// The set of options supported by IR generation. diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp index fa77733b6d390..f759e17cc9f5e 100644 --- a/lib/IRGen/GenClass.cpp +++ b/lib/IRGen/GenClass.cpp @@ -2097,41 +2097,44 @@ static llvm::Function *emitObjCMetadataUpdateFunction(IRGenModule &IGM, /// We emit Objective-C class stubs for non-generic classes with resilient /// ancestry. This lets us attach categories to the class even though it /// does not have statically-emitted metadata. -bool irgen::hasObjCResilientClassStub(IRGenModule &IGM, ClassDecl *D) { - assert(IGM.getClassMetadataStrategy(D) == ClassMetadataStrategy::Resilient); - return IGM.ObjCInterop && !D->isGenericContext(); +bool IRGenModule::hasObjCResilientClassStub(ClassDecl *D) { + assert(getClassMetadataStrategy(D) == ClassMetadataStrategy::Resilient); + return ObjCInterop && !D->isGenericContext(); } -void irgen::emitObjCResilientClassStub(IRGenModule &IGM, ClassDecl *D) { - assert(hasObjCResilientClassStub(IGM, D)); +void IRGenModule::emitObjCResilientClassStub(ClassDecl *D) { + assert(hasObjCResilientClassStub(D)); - llvm::Constant *fields[] = { - llvm::ConstantInt::get(IGM.SizeTy, 0), // reserved - llvm::ConstantInt::get(IGM.SizeTy, 1), // isa - IGM.getAddrOfObjCMetadataUpdateFunction(D, NotForDefinition) - }; - auto init = llvm::ConstantStruct::get(IGM.ObjCFullResilientClassStubTy, - makeArrayRef(fields)); + ConstantInitBuilder builder(*this); + auto fields = builder.beginStruct(ObjCFullResilientClassStubTy); + fields.addInt(SizeTy, 0); // reserved + fields.addInt(SizeTy, 1); // isa + auto *impl = getAddrOfObjCMetadataUpdateFunction(D, NotForDefinition); + const auto &schema = + getOptions().PointerAuth.ResilientClassStubInitCallbacks; + fields.addSignedPointer(impl, schema, PointerAuthEntity()); // callback + + auto init = fields.finishAndCreateFuture(); // Define the full stub. This is a private symbol. + LinkEntity entity = LinkEntity::forObjCResilientClassStub( + D, TypeMetadataAddress::FullMetadata); auto fullObjCStub = cast( - IGM.getAddrOfObjCResilientClassStub(D, ForDefinition, - TypeMetadataAddress::FullMetadata)); - fullObjCStub->setInitializer(init); + getAddrOfLLVMVariable(entity, init, DebugTypeInfo())); // Emit the metadata update function referenced above. - emitObjCMetadataUpdateFunction(IGM, D); + emitObjCMetadataUpdateFunction(*this, D); // Apply the offset. - auto *objcStub = llvm::ConstantExpr::getBitCast(fullObjCStub, IGM.Int8PtrTy); + auto *objcStub = llvm::ConstantExpr::getBitCast(fullObjCStub, Int8PtrTy); objcStub = llvm::ConstantExpr::getInBoundsGetElementPtr( - IGM.Int8Ty, objcStub, IGM.getSize(IGM.getPointerSize())); + Int8Ty, objcStub, getSize(getPointerSize())); objcStub = llvm::ConstantExpr::getPointerCast(objcStub, - IGM.ObjCResilientClassStubTy->getPointerTo()); + ObjCResilientClassStubTy->getPointerTo()); - auto entity = LinkEntity::forObjCResilientClassStub( + entity = LinkEntity::forObjCResilientClassStub( D, TypeMetadataAddress::AddressPoint); - IGM.defineAlias(entity, objcStub); + defineAlias(entity, objcStub); } /// Emit the private data (RO-data) associated with a class. diff --git a/lib/IRGen/GenClass.h b/lib/IRGen/GenClass.h index 66018fbfb7b8d..834b10d32ba72 100644 --- a/lib/IRGen/GenClass.h +++ b/lib/IRGen/GenClass.h @@ -168,14 +168,6 @@ namespace irgen { llvm::Value *selfValue, llvm::Value *metadataValue); - /// We emit Objective-C class stubs for non-generic classes with resilient - /// ancestry. This lets us attach categories to the class even though it - /// does not have statically-emitted metadata. - bool hasObjCResilientClassStub(IRGenModule &IGM, ClassDecl *D); - - /// Emit a resilient class stub. - void emitObjCResilientClassStub(IRGenModule &IGM, ClassDecl *D); - /// Emit the constant fragile offset of the given property inside an instance /// of the class. llvm::Constant *tryEmitConstantClassFragilePhysicalMemberOffset( diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp index cc87d8c34f106..7eca86628b80c 100644 --- a/lib/IRGen/GenMeta.cpp +++ b/lib/IRGen/GenMeta.cpp @@ -1672,7 +1672,7 @@ namespace { / IGM.getPointerSize()); } else { ExtraClassDescriptorFlags flags; - if (hasObjCResilientClassStub(IGM, getType())) + if (IGM.hasObjCResilientClassStub(getType())) flags.setObjCResilientClassStub(true); B.addInt32(flags.getOpaqueValue()); } @@ -1694,7 +1694,7 @@ namespace { ClassMetadataStrategy::Resilient) return; - if (!hasObjCResilientClassStub(IGM, getType())) + if (!IGM.hasObjCResilientClassStub(getType())) return; B.addRelativeAddress( @@ -3390,8 +3390,8 @@ void irgen::emitClassMetadata(IRGenModule &IGM, ClassDecl *classDecl, // Even non-@objc classes can have Objective-C categories attached, so // we always emit a resilient class stub as long as -enable-objc-interop // is set. - if (hasObjCResilientClassStub(IGM, classDecl)) { - emitObjCResilientClassStub(IGM, classDecl); + if (IGM.hasObjCResilientClassStub(classDecl)) { + IGM.emitObjCResilientClassStub(classDecl); if (classDecl->isObjC()) { auto *stub = IGM.getAddrOfObjCResilientClassStub( diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp index 276e9fe7c1f2c..f3947efa47588 100644 --- a/lib/IRGen/IRGen.cpp +++ b/lib/IRGen/IRGen.cpp @@ -660,6 +660,10 @@ static void setPointerAuthOptions(PointerAuthOptions &opts, PointerAuthSchema(codeKey, /*address*/ true, Discrimination::Type); opts.YieldOnceResumeFunctions = PointerAuthSchema(codeKey, /*address*/ true, Discrimination::Type); + + opts.ResilientClassStubInitCallbacks = + PointerAuthSchema(codeKey, /*address*/ true, Discrimination::Constant, + SpecialPointerAuthDiscriminators::ResilientClassStubInitCallback); } std::unique_ptr diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h index 279da5e357f84..125efea4d0d4d 100644 --- a/lib/IRGen/IRGenModule.h +++ b/lib/IRGen/IRGenModule.h @@ -1563,6 +1563,14 @@ private: \ void emitOpaqueTypeDescriptorAccessor(OpaqueTypeDecl *); + /// We emit Objective-C class stubs for non-generic classes with resilient + /// ancestry. This lets us attach categories to the class even though it + /// does not have statically-emitted metadata. + bool hasObjCResilientClassStub(ClassDecl *D); + + /// Emit a resilient class stub. + void emitObjCResilientClassStub(ClassDecl *D); + private: llvm::Constant * getAddrOfSharedContextDescriptor(LinkEntity entity, diff --git a/test/IRGen/class_update_callback_with_stub.swift b/test/IRGen/class_update_callback_with_stub.swift index 3652209a245b7..0d6e3f2539c66 100644 --- a/test/IRGen/class_update_callback_with_stub.swift +++ b/test/IRGen/class_update_callback_with_stub.swift @@ -63,21 +63,21 @@ import resilient_objc_class // CHECK-SAME: internal global %objc_full_class_stub { // CHECK-SAME: [[INT]] 0, // CHECK-SAME: [[INT]] 1, -// CHECK-SAME: %objc_class* (%objc_class*, i8*)* @"$s31class_update_callback_with_stub17ResilientSubclassCMU" +// CHECK-SAME: %objc_class* (%objc_class*, i8*)* {{.*}}@"$s31class_update_callback_with_stub17ResilientSubclassCMU{{(\.ptrauth)?}}" // CHECK-SAME: } // CHECK-LABEL: @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMt" = // CHECK-SAME: internal global %objc_full_class_stub { // CHECK-SAME: [[INT]] 0, // CHECK-SAME: [[INT]] 1, -// CHECK-SAME: %objc_class* (%objc_class*, i8*)* @"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMU" +// CHECK-SAME: %objc_class* (%objc_class*, i8*)* {{.*}}@"$s31class_update_callback_with_stub25ResilientNSObjectSubclassCMU{{(\.ptrauth)?}}" // CHECK-SAME: } // CHECK-LABEL: @"$s31class_update_callback_with_stub27FixedLayoutNSObjectSubclassCMt" = // CHECK-SAME: internal global %objc_full_class_stub { // CHECK-SAME: [[INT]] 0, // CHECK-SAME: [[INT]] 1, -// CHECK-SAME: %objc_class* (%objc_class*, i8*)* @"$s31class_update_callback_with_stub27FixedLayoutNSObjectSubclassCMU" +// CHECK-SAME: %objc_class* (%objc_class*, i8*)* {{.*}}@"$s31class_update_callback_with_stub27FixedLayoutNSObjectSubclassCMU{{(\.ptrauth)?}}" // CHECK-SAME: } diff --git a/validation-test/Runtime/class_stubs.m b/validation-test/Runtime/class_stubs.m index 03af7438fd77c..91ce61674a91c 100644 --- a/validation-test/Runtime/class_stubs.m +++ b/validation-test/Runtime/class_stubs.m @@ -5,7 +5,7 @@ // RUN: %target-build-swift -emit-library -emit-module -o %t/libfirst.dylib -emit-objc-header-path %t/first.h %S/Inputs/class-stubs-from-objc/first.swift -Xlinker -install_name -Xlinker @executable_path/libfirst.dylib -enable-library-evolution // RUN: %target-build-swift -emit-library -o %t/libsecond.dylib -emit-objc-header-path %t/second.h -I %t %S/Inputs/class-stubs-from-objc/second.swift -Xlinker -install_name -Xlinker @executable_path/libsecond.dylib -lfirst -L %t -target %target-next-stable-abi-triple // RUN: cp %S/Inputs/class-stubs-from-objc/module.map %t/ -// RUN: xcrun -sdk %sdk %clang %s -I %t -L %t -fmodules -fobjc-arc -o %t/main -lfirst -lsecond -Wl,-U,_objc_loadClassref -target %target-next-stable-abi-triple +// RUN: xcrun -sdk %sdk %clang %s -I %t -L %t -fmodules -fobjc-arc -o %t/main -lfirst -lsecond -target %target-next-stable-abi-triple // RUN: %target-codesign %t/main %t/libfirst.dylib %t/libsecond.dylib // RUN: %target-run %t/main %t/libfirst.dylib %t/libsecond.dylib @@ -31,7 +31,7 @@ + (int)classMethod { int main(int argc, const char * const argv[]) { // Only test the new behavior on a new enough libobjc. - if (!dlsym(RTLD_NEXT, "_objc_loadClassref")) { + if (!dlsym(RTLD_NEXT, "objc_loadClassref")) { fprintf(stderr, "skipping evolution tests; OS too old\n"); return EXIT_SUCCESS; } diff --git a/validation-test/Runtime/class_stubs_weak.m b/validation-test/Runtime/class_stubs_weak.m index dd2330bdd7562..db4b7fe85238b 100644 --- a/validation-test/Runtime/class_stubs_weak.m +++ b/validation-test/Runtime/class_stubs_weak.m @@ -7,7 +7,7 @@ // RUN: cp %S/Inputs/class-stubs-weak/module.map %t/ // Note: This is the just-built Clang, not the system Clang. -// RUN: xcrun -sdk %sdk %clang %s -I %t -L %t -fmodules -fobjc-arc -o %t/main -lfirst -lsecond -Wl,-U,_objc_loadClassref -target %target-triple +// RUN: xcrun -sdk %sdk %clang %s -I %t -L %t -fmodules -fobjc-arc -o %t/main -lfirst -lsecond -target %target-triple // Now rebuild the library, omitting the weak-exported class // RUN: %target-build-swift -emit-library -o %t/libsecond.dylib -I %t %S/Inputs/class-stubs-weak/second.swift -Xlinker -install_name -Xlinker @executable_path/libsecond.dylib -lfirst -L %t -target %target-next-stable-abi-triple @@ -19,6 +19,8 @@ // REQUIRES: objc_interop // REQUIRES: swift_stable_abi +// REQUIRES: rdar62692550 + #import #import #import "second.h" @@ -37,7 +39,7 @@ + (int)classMethod { int main(int argc, const char * const argv[]) { // Only test the new behavior on a new enough libobjc. - if (!dlsym(RTLD_NEXT, "_objc_loadClassref")) { + if (!dlsym(RTLD_NEXT, "objc_loadClassref")) { fprintf(stderr, "skipping evolution tests; OS too old\n"); return EXIT_SUCCESS; } From 9eab9f3913861c4e5c8af7b6bfd0f214e293e8fe Mon Sep 17 00:00:00 2001 From: Valeriy Van Date: Sat, 2 May 2020 06:15:37 +0200 Subject: [PATCH 26/35] Fixes example snippets in MutableCollection.swift --- stdlib/public/core/MutableCollection.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/public/core/MutableCollection.swift b/stdlib/public/core/MutableCollection.swift index 3e335e6f9a775..d9f09477e0bb1 100644 --- a/stdlib/public/core/MutableCollection.swift +++ b/stdlib/public/core/MutableCollection.swift @@ -98,7 +98,7 @@ where SubSequence: MutableCollection /// the index of one of the strings in the slice, and then using that index /// in the original array. /// - /// let streets = ["Adams", "Bryant", "Channing", "Douglas", "Evarts"] + /// var streets = ["Adams", "Bryant", "Channing", "Douglas", "Evarts"] /// let streetsSlice = streets[2 ..< streets.endIndex] /// print(streetsSlice) /// // Prints "["Channing", "Douglas", "Evarts"]" @@ -222,7 +222,7 @@ extension MutableCollection { /// the index of one of the strings in the slice, and then using that index /// in the original array. /// - /// let streets = ["Adams", "Bryant", "Channing", "Douglas", "Evarts"] + /// var streets = ["Adams", "Bryant", "Channing", "Douglas", "Evarts"] /// let streetsSlice = streets[2 ..< streets.endIndex] /// print(streetsSlice) /// // Prints "["Channing", "Douglas", "Evarts"]" From 210af1c5ebfccddad05274c3f1f7d114fa9521f8 Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Sat, 2 May 2020 01:24:47 -0700 Subject: [PATCH 27/35] [Gardening] De-RST the Lexicon --- docs/Lexicon.md | 562 +++++++++++++++++++++++++++++++++++++++++++++++ docs/Lexicon.rst | 505 ------------------------------------------ 2 files changed, 562 insertions(+), 505 deletions(-) create mode 100644 docs/Lexicon.md delete mode 100644 docs/Lexicon.rst diff --git a/docs/Lexicon.md b/docs/Lexicon.md new file mode 100644 index 0000000000000..830ef67eeb2b9 --- /dev/null +++ b/docs/Lexicon.md @@ -0,0 +1,562 @@ +Lexicon +======= + +This file defines several terms used by the Swift compiler and standard library +source code, tests, and commit messages. See also the +[LLVM lexicon](http://llvm.org/docs/Lexicon.html). + +Glossary +======== + +## abstraction pattern + +The unsubstituted generic type of a property or function parameter, which +sets constraints on its representation in memory. For example, given the +following definitions: + +```swift +struct Foo { + var value: T + // Foo.value has abstraction pattern T +} +struct Bar { + var value: (T) -> U + // Bar.value has abstraction pattern (T) -> U +} +struct Bas { + var value: (Int) -> String + // Bas.value has abstraction pattern (Int) -> String +} +let transform: (Int) -> String = { "\($0)" } +let foo = Foo<(Int) -> String>(value: transform) +let bar = Bar(value: transform) +let bas = Bas(value: transform) +``` + +although `foo.value`, `bar.value`, and `bas.value` all have the same +function type `(Int) -> String`, they have different [abstraction +patterns](#abstraction-pattern). Because a value of type `Foo` or `Bar` may be used in a +generic context and invoke `value` with a parameter or result type +of unknown size, the compiler has to pick a more conservative representation +for the closure that uses indirect argument passing, whereas `Bas.value` +has a fully concrete closure type so can always use a more specialized +direct register-based calling convention. The compiler transparently +introduces [reabstraction](#reabstraction) conversions when a value is used with a +different abstraction pattern. (This is where the infamous "reabstraction +thunk helpers" sometimes seen in Swift backtraces come from.) + +## archetype + +A placeholder for a generic parameter or an associated type within a +generic context. Sometimes known as a "rigid type variable" in formal +CS literature. Directly stores its conforming protocols and nested +archetypes, if any. + +## AST + +"Abstract syntax tree", although in practice it's more of a directed graph. +A parsed representation of code used by a compiler. + +## bitcode + +Serialized LLVM [IR](#IR). + +## build czar + +Apple term for "the person assigned to watch CI this week". + +## canonical SIL + +SIL after the +[mandatory passes](#mandatory-passes--mandatory-optimizations) have run. +This can be used as input to IRGen to generate LLVM IR or object files. + +## canonical type + +A unique representation of a type, with any [sugar](#sugared-type) removed. +These can usually be directly compared to test whether two types are the +same; the exception is when generics get involved. In this case you'll need +a [generic environment](#generic-environment). Contrast with [sugared type](#sugared-type). + +## cascading dependency + +A kind of dependency edge relevant to the incremental name tracking +subsystem. A cascading dependency (as opposed to a +[private dependency](#private-dependency) requires the Swift driver to +transitively consider dependency edges in the file that defines the used +name when incremental compilation is enabled. A cascading dependency is much +safer to produce than its private counterpart, but it comes at the cost of +increased usage of compilation resources - even if those resources are being +wasted on rebuilding a file that didn't actually require rebuilding. +See [DependencyAnalysis.rst](DependencyAnalysis.rst). + +## Clang importer + +The part of the compiler that reads C and Objective-C declarations and +exposes them as Swift. Essentially contains a small instance of Clang +running inside the Swift compiler, which is also used during IRGen. + +## conformance + +A construct detailing how a particular type conforms to a particular +protocol. Represented in the compiler by the ProtocolConformance type at +the AST level. See also [witness table](#witness-table). + +## contextual type + +1. The expected type for a Swift sub-expression based on the rest of the + statement. For example, in the statement `print(6 * 9)`, the contextual + type of the expression `6 * 9` is `Any`. +2. The type of a value or declaration from inside a potentially generic + context. This type may contain [archetypes](#archetype) and cannot be + used directly from outside the context. Compare with [interface type](#interface-type). + +## customization point + +Informal term for a protocol requirement that has a default implementation, +i.e. one that conforming types don't *have* to implement but have the option +to "customize". + +## dependency sink + +Any request that uses a matching dependency source to write dependency +edges into the referenced name trackers. For example, a request that +performs direct lookup will write the name being looked up into the +name tracker associated with the file that issued the lookup request. +The request evaluator automatically determines the appropriate tracker +for a dependency sink to write into based on the current active +[dependency source](#dependency-source) request. + +## dependency source + +Any request that defines a scope under which reference dependencies may be +registered. For example, a request to type check an entire file is a +dependency source. Dependency sources are automatically managed by the +request evaluator as request evaluation proceeds. Dependency sources provide +one half of the necessary information to complete a full dependency edge. +The other half is provided by corresponding +[dependency sink](#dependency-sink) requests. + +## DI (definite initialization / definitive initialization) + +The feature that no uninitialized variables, constants, or properties will +be read by a program, or the analysis pass that operates on SIL to +guarantee this. This was +[discussed on Apple's Swift blog](https://developer.apple.com/swift/blog/?id=28). + +## DNM + +"Do not merge". Placed in PR titles where discussion or analysis is still +ongoing. + +## dup + +From "duplicate". As a noun, refers to another filed issue that describes +the same bug ("I have a dup of this"); as a verb, the act of marking a bug +*as* a duplicate ("Please dup this to the underlying issue"). Sometimes +written "dupe". Pronounced the same way as the first syllable of +"duplicate", which for most American English speakers is "doop". + +## existential + +A value whose type is a protocol composition (including a single protocol +and *zero* protocols; the latter is the `Any` type). + +## fragile + +Describes a type or function where making changes will break binary +compatibility. See [LibraryEvolution.rst](LibraryEvolution.rst). + +## generic environment + +Provides context for interpreting a type that may have generic parameters +in it. Generic parameter types are normally just represented as "first +generic parameter in the outermost context" (or similar), so it's up to the +generic environment to note that that type must be a Collection. (Another +way of looking at it is that the generic environment connects +[interface types](#interface-type) with +[contextual types](#contextual-type)). + +## generic signature + +A representation of all generic parameters and their requirements. Like +types, generic signatures can be [canonicalized](#canonical-type) to be +compared directly. + +## iff + +["if and only if"](https://en.wikipedia.org/wiki/If_and_only_if). This term comes from mathematics. + +## interface type + +The type of a value or declaration outside its generic context. These types +are written using "formal" generic types, which only have meaning when +combined with a particular generic declaration's "generic signature". +Unlike [contextual types](#contextual-type), interface types store +conformances and requirements in the generic signature and not in the types +themselves. They can be compared across declarations but cannot be used +directly from within the context. + +## irrefutable pattern + +A pattern that always matches. These patterns either bind to a variable or +perform structural modification, e.x.: + +1. `case _:`. +2. `case let x:`. +3. `case (_, _):`. + +## IR + +1. "intermediate representation": a generic term for a format representing + code in a way that is easy for a compiler or tool to manipulate. +2. "LLVM IR": a particular IR used by the LLVM libraries for optimization + and generation of machine code. + +## IUO (implicitly unwrapped optional) + +A type like Optional, but it implicitly converts to its wrapped type. If +the value is `nil` during such a conversion, the program traps just as +it would when a normal Optional is force-unwrapped. IUOs implicitly +convert to and from normal Optionals with the same wrapped type. + +## IWYU (include what you use) + +The accepted wisdom that implementation files (`.cpp`, `.c`, `.m`, +`.mm`) should explicitly `#include` or `#import` the headers they use. +Doing so prevents compilation errors when header files are included in a +different order, or when header files are modified to use forward +declarations instead of direct includes. + +## LGTM + +"Looks good to me." Used in code review to indicate approval with no further +comments. + +## LLVM IR + +See [IR](#IR). + +## lvalue + +Pronounced "L-value". Refers to an expression that can be assigned to or +passed `inout`. The term originally comes from C; the "L" refers to the +"l"eft side of an assignment operator. See also [rvalue](#rvalue). + +## main module + +The module for the file or files currently being compiled. + +## mandatory passes / mandatory optimizations + +Transformations over SIL that run immediately after SIL generation. Once +all mandatory passes have run (and if no errors are found), the SIL is +considered [canonical](#canonical-SIL). + +## metatype + +The type of a value representing a type. Greg Parker has a good +explanation of +[Objective-C's "metaclasses"](http://sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html); +because Swift has types +that are *not* classes, a more general term is used. + +We also sometimes refer to a value representing a type as a "metatype +object" or just "metatype", usually within low-level contexts like IRGen +and LLDB. This is technically incorrect (it's just a "type object"), but +the malapropism happened early in the project and has stuck around. + +## model + +A type that conforms to a particular protocol. Sometimes "concrete +model". Example: "Array and Set are both models of CollectionType". + +## module + +Has *many* uses in the Swift world. We may want to rename some of them. +#1 and #2 are the most common. + +1. A unit of API distribution and grouping. The `import` declaration + brings modules into scope. Represented as ModuleDecl in the compiler. +2. A compilation unit; that is, source files that are compiled together. + These files may contain cross-references. Represented as "the main + module" (a specific ModuleDecl). +3. (as "SIL module") A container for SIL to be compiled together, along + with various context for the compilation. +4. (as "LLVM module") A collection of LLVM IR to be compiled together. + Always created in an LLVMContext. +5. A file containing serialized AST and SIL information for a source file + or entire compilation unit. Often "swiftmodule file", with "swiftmodule" + pronounced as a single word. +6. (as "Clang module") A set of self-contained C-family header files. + Represented by a ClangModuleUnit in the Swift compiler, each of which is + contained in its own ModuleDecl. For more information, see + [Clang's documentation for Modules](http://clang.llvm.org/docs/Modules.html). +7. Shorthand for a "precompiled module file"; effectively "precompiled + headers" for an entire Clang module. Never used directly by Swift. + See also [module cache](#module-cache). + + +## module cache + +Clang's cache directory for precompiled module files. As cache files, these +are not forward-compatible, and so cannot be loaded by different versions +of Clang (or programs using Clang, like the Swift compiler). Normally this +is fine, but occasionally a development compiler will not have proper +version information and may try to load older module files, resulting in +crashes in `clang::ASTReader`. + +## NFC + +"No functionality change." Written in commit messages that are intended to +have no change on the compiler or library's behavior, though for some this +refers to having the *same* implementation and for others merely an +*equivalent* one. "NFC" is typically used to explain why a patch has no +included testcase, since the Swift project requires testcases for all +patches that change functionality. + +## open existential + +An [existential](#existential) value with its dynamic type pulled out, so that the +compiler can do something with it. + +## overlay + +A wrapper library that is implicitly imported "on top of" another library. +It contains an `@_exported` import of the underlying library, but it augments +it with additional APIs which, for one reason or another, are not included +in the underlying library directly. + +There are two kinds of overlays: + +A "clang overlay" (the older kind, so it's often just called an "overlay") +is a Swift library that adds Swift-specific functionality to a C-family +library or framework. Clang overlays are used with system libraries that +cannot be modified to add Swift features. A clang overlay has the same +module name as the underlying library and can do a few special things that +normal modules can't, like adding required initializers to classes. If a +module has a clang overlay, the Clang Importer will always load it unless it +is actually compiling the overlay itself. Apple has a number of clang +overlays for its own SDKs in `stdlib/public/Darwin/`. + +A "separately-imported overlay" is a separate module with its own name. +Unlike a clang overlay, it can be imported in some SourceFiles and not +others. When the compiler processes import declarations, it determines which +separately-imported overlays need to be imported and then adds them to the +list of imports for that file; name lookup also knows to look through the +overlay when it looks for declarations in the underlying module. +Separately-imported overlays are used to implement the "cross-import +overlays" feature, which is used to augment a module with additional +functionality when it is imported alongside another module. + +## parent type + +The type in which a given declaration is nested. For example: + +```swift +struct Outer { + struct Inner { + } +} +``` + +`Outer` is the parent type of `Inner`. + +Note that the terms "parent type" and "superclass" refer to completely +different concepts. + +## PCH + +Precompiled header, a type of file ending in .pch. A precompiled header is +like a precompiled module, in the sense that it's the same file format and +is just a cache file produced by clang and read by `clang::ASTReader`. The +difference is that PCH files are not "modular": they do not correspond to a +named module, and cannot be read in any order or imported by module-name; +rather they must be the first file parsed by the compiler. PCHs are used +only to accelerate the process of reading C/C++/Objective-C headers, such as +the bridging headers read in by the `-import-objc-header` command-line +flag to swiftc. + +## PR + +1. "Problem Report": An issue reported in [LLVM's bug tracker](https://llvm.org/bugs/). +See also [SR](#SR). +2. "pull request" + +## primary file + +The file currently being compiled, as opposed to the other files that are +only needed for context. See also +[Whole-Module Optimization](#wmo-whole-module-optimization). + +## private dependency + +A kind of dependency edge relevant to the incremental name tracking +subsystem. A private dependency (as opposed to a +[cascading dependency](#cascading-dependency)) declares a dependency edge +from one file to a name referenced in that file that does not +require further transitive evaluation of dependency edges by the Swift +driver. Private dependencies are therefore cheaper than cascading +dependencies, but must be used with the utmost care or dependent files will +fail to rebuild and the result will most certainly be a miscompile. +See [DependencyAnalysis.rst](DependencyAnalysis.rst). + +## QoI + +"Quality of implementation." The term is meant to describe not how +well-engineered a particular implementation is, but how much value it +provides to users beyond a sort of minimum expectation. Good diagnostics +are a matter of QoI, as is good unoptimized performance. For example, a +comment like "FIXME: QoI could be improved here" is suggesting that there's +some sort of non-mandatory work that could be done that would improve the +behavior of the compiler--it is not just a general statement that the code +needs to be improved. + +It's possible that this term was originally "quality of life", written as +"Qol", referring to the experience of end users. At some point along its +history, the lowercase "L" was misinterpreted as an uppercase "i", and a +new meaning derived. Swift inherited this term from LLVM, which got it from +GCC. + +## Radar + +[Apple's bug-tracking system](https://bugreport.apple.com), or an issue reported +on that system. + +## raw SIL + +SIL just after being generated, not yet in a form that can be used for +IR generation. +See [mandatory passes](#mandatory-passes--mandatory-optimizations). + +## reabstraction + +An implicit representation change that occurs when a value is used with +a different [abstraction pattern](#abstraction-pattern) from its current representation. + +## refutable pattern + +A pattern that may not always match. These include patterns such as: + +1. Isa check, e.g. `case let x as String:`. +2. Enum case check: e.g. `case .none:`. +3. Expr pattern: e.g. `case foo():`. + +## resilient + +Describes a type or function where making certain changes will not break +binary compatibility. See [LibraryEvolution.rst](LibraryEvolution.rst). + +## runtime + +Code that implements a language's dynamic features that aren't just +compiled down to plain instructions. For example, Swift's runtime library +includes support for dynamic casting and for the Mirror-based reflection. + +## rvalue + +Pronounced "R-value". Represents an expression that can be used as a value; +in Swift this is nearly every expression, so we don't use the term very +often. The term originally comes from C; the "R" refers to the "r"ight side +of an assignment operator. Contrast with [lvalue](#lvalue). + +## script mode + +The parsing mode that allows top-level imperative code in a source file. + +## Sema + +Short for 'Semantic Analysis', the compiler pass that performs type checking, +validation, and expression rewriting before SILGen. + +## SIL + +"Swift Intermediate Language". A high-level IR used by the Swift compiler +for flow-sensitive diagnostics, optimization, and LLVM IR generation. + +## SR + +An issue reported on [bugs.swift.org](https://bugs.swift.org). A +backronym for "Swift Report"; really the name is derived from LLVM's +idiomatic use of "PR" ("Problem Report") for its bugs. We didn't go with +"PR" for Swift because we wanted to be able to unambiguously reference +LLVM bugs. + +## stdlib + +"Standard library". Sometimes this just means the "Swift" module (also +known as "swiftCore"); sometimes it means everything in the stdlib/ +directory. Pronounced "stid-lib" or "ess-tee-dee-lib". + +## sugared type + +A type that may have been written in a more convenient way, using special +language syntax or a typealias. (For example, `Int?` is the sugared form +of `Optional`.) Sugared types preserve information about the form +and use of the type even though the behavior usually does not change +(except for things like access control). Contrast with [canonical type](#canonical-type). + +## thunk + +In the Swift compiler, a synthesized function whose only purpose is to +perform some kind of adjustment in order to call another function. For +example, Objective-C and Swift have different calling conventions, so the +Swift compiler generates a thunk for use in Objective-C that calls through +to the real Swift implementation. + +## trap + +A deterministic runtime failure. Can be used as both as a noun ("Using an +out-of-bounds index on an Array results in a trap") and a verb +("Force-unwrapping a nil Optional will trap"). + +## type metadata + +The runtime representation of a type, and everything you can do with it. +Like a `Class` in Objective-C, but for any type. + +## USR + +A Unified Symbol Resolution (USR) is a string that identifies a particular +entity (function, class, variable, etc.) within a program. USRs can be +compared across translation units to determine, e.g., when references in +one translation refer to an entity defined in another translation unit. + +## VWT (value witness table) + +A runtime structure that describes how to do basic operations on an unknown +value, like "assign", "copy", and "destroy". (For example, does copying +this value require any retains?) + +Only conceptually related to a [witness table](#witness-table). + +## vtable (virtual dispatch table) + +A map attached to a class of which implementation to use for each +overridable method in the class. Unlike an Objective-C method table, +vtable keys are just offsets, making lookup much simpler at the cost of +dynamism and duplicated information about *non*-overridden methods. + +## WIP + +"Work-in-progress". Placed in PR titles to indicate that the PR is not ready +for review or merging. + +## witness + +The value or type that satisfies a protocol requirement. + +## witness table + +The SIL (and runtime) representation of a [conformance](#conformance); essentially a +[vtable](#vtable-virtual-dispatch-table) but for a protocol instead of +a class. + +Only conceptually related to a [value witness table](#vwt-value-witness-table). + +## WMO (whole-module optimization) + +A compilation mode where all files in a module are compiled in a single +process. In this mode there is no `primary file`; all files are parsed, +type-checked, and optimized together at the SIL level. LLVM optimization +and object file generation may happen all together or in separate threads. diff --git a/docs/Lexicon.rst b/docs/Lexicon.rst deleted file mode 100644 index e39b7cfa43188..0000000000000 --- a/docs/Lexicon.rst +++ /dev/null @@ -1,505 +0,0 @@ -:orphan: - -.. title:: Lexicon -.. default-role:: term - -This file defines several terms used by the Swift compiler and standard library -source code, tests, and commit messages. See also the `LLVM lexicon`_. - -.. _LLVM lexicon: http://llvm.org/docs/Lexicon.html - -.. note:: - - This document uses Sphinx-specific features. If you are viewing this on - GitHub, you'll have to use raw mode, or download and build the docs - yourself. - -.. glossary:: - - abstraction pattern - The unsubstituted generic type of a property or function parameter, which - sets constraints on its representation in memory. For example, given the - following definitions:: - - struct Foo { - var value: T - // Foo.value has abstraction pattern T - } - struct Bar { - var value: (T) -> U - // Bar.value has abstraction pattern (T) -> U - } - struct Bas { - var value: (Int) -> String - // Bas.value has abstraction pattern (Int) -> String - } - let transform: (Int) -> String = { "\($0)" } - let foo = Foo<(Int) -> String>(value: transform) - let bar = Bar(value: transform) - let bas = Bas(value: transform) - - although ``foo.value``, ``bar.value``, and ``bas.value`` all have the same - function type ``(Int) -> String``, they have different *abstraction - patterns*. Because a value of type ``Foo`` or ``Bar`` may be used in a - generic context and invoke ``value`` with a parameter or result type - of unknown size, the compiler has to pick a more conservative representation - for the closure that uses indirect argument passing, whereas ``Bas.value`` - has a fully concrete closure type so can always use a more specialized - direct register-based calling convention. The compiler transparently - introduces `reabstraction` conversions when a value is used with a - different abstraction pattern. (This is where the infamous "reabstraction - thunk helpers" sometimes seen in Swift backtraces come from.) - - archetype - A placeholder for a generic parameter or an associated type within a - generic context. Sometimes known as a "rigid type variable" in formal - CS literature. Directly stores its conforming protocols and nested - archetypes, if any. - - AST - "Abstract syntax tree", although in practice it's more of a directed graph. - A parsed representation of code used by a compiler. - - bitcode - Serialized LLVM `IR`. - - build czar - Apple term for "the person assigned to watch CI this week". - - canonical SIL - SIL after the - `mandatory passes ` have run. - This can be used as input to IRGen to generate LLVM IR or object files. - - canonical type - A unique representation of a type, with any `sugar ` removed. - These can usually be directly compared to test whether two types are the - same; the exception is when generics get involved. In this case you'll need - a `generic environment`. Contrast with `sugared type`. - - cascading dependency - A kind of dependency edge relevant to the incremental name tracking - subsystem. A cascading dependency (as opposed to a - `private dependency `) requires the Swift driver to - transitively consider dependency edges in the file that defines the used - name when incremental compilation is enabled. A cascading dependency is much - safer to produce than its private counterpart, but it comes at the cost of - increased usage of compilation resources - even if those resources are being - wasted on rebuilding a file that didn't actually require rebuilding. - See :doc:`DependencyAnalysis.rst `. - - Clang importer - The part of the compiler that reads C and Objective-C declarations and - exposes them as Swift. Essentially contains a small instance of Clang - running inside the Swift compiler, which is also used during IRGen. - - conformance - A construct detailing how a particular type conforms to a particular - protocol. Represented in the compiler by the ProtocolConformance type at - the AST level. See also `witness table`. - - contextual type - 1. The expected type for a Swift sub-expression based on the rest of the - statement. For example, in the statement ``print(6 * 9)``, the contextual - type of the expression ``6 * 9`` is ``Any``. - 2. The type of a value or declaration from inside a potentially generic - context. This type may contain `archetypes ` and cannot be - used directly from outside the context. Compare with `interface type`. - - customization point - Informal term for a protocol requirement that has a default implementation, - i.e. one that conforming types don't *have* to implement but have the option - to "customize". - - dependency sink - Any request that uses a matching dependency source to write dependency - edges into the referenced name trackers. For example, a request that - performs direct lookup will write the name being looked up into the - name tracker associated with the file that issued the lookup request. - The request evaluator automatically determines the appropriate tracker - for a dependency sink to write into based on the current active - `dependency source ` request. - - dependency source - Any request that defines a scope under which reference dependencies may be - registered. For example, a request to type check an entire file is a - dependency source. Dependency sources are automatically managed by the - request evaluator as request evaluation proceeds. Dependency sources provide - one half of the necessary information to complete a full dependency edge. - The other half is provided by corresponding - `dependency sink ` requests. - - DI (definite initialization / definitive initialization) - The feature that no uninitialized variables, constants, or properties will - be read by a program, or the analysis pass that operates on SIL to - guarantee this. This was `discussed on Apple's Swift blog`__. - - __ https://developer.apple.com/swift/blog/?id=28 - - DNM - "Do not merge". Placed in PR titles where discussion or analysis is still - ongoing. - - dup - From "duplicate". As a noun, refers to another filed issue that describes - the same bug ("I have a dup of this"); as a verb, the act of marking a bug - *as* a duplicate ("Please dup this to the underlying issue"). Sometimes - written "dupe". Pronounced the same way as the first syllable of - "duplicate", which for most American English speakers is "doop". - - existential - A value whose type is a protocol composition (including a single protocol - and *zero* protocols; the latter is the ``Any`` type). - - fragile - Describes a type or function where making changes will break binary - compatibility. See :doc:`LibraryEvolution.rst `. - - generic environment - Provides context for interpreting a type that may have generic parameters - in it. Generic parameter types are normally just represented as "first - generic parameter in the outermost context" (or similar), so it's up to the - generic environment to note that that type must be a Collection. (Another - way of looking at it is that the generic environment connects - `interface types ` with - `contextual types `). - - generic signature - A representation of all generic parameters and their requirements. Like - types, generic signatures can be `canonicalized ` to be - compared directly. - - iff - "`if and only if`__". This term comes from mathematics. - - __ https://en.wikipedia.org/wiki/If_and_only_if - - interface type - The type of a value or declaration outside its generic context. These types - are written using "formal" generic types, which only have meaning when - combined with a particular generic declaration's "generic signature". - Unlike `contextual types `, interface types store - conformances and requirements in the generic signature and not in the types - themselves. They can be compared across declarations but cannot be used - directly from within the context. - - irrefutable pattern - A pattern that always matches. These patterns either bind to a variable or - perform structural modification, e.x.: - - 1. ``case _:``. - 2. ``case let x:``. - 3. ``case (_, _):``. - - IR - 1. "intermediate representation": a generic term for a format representing - code in a way that is easy for a compiler or tool to manipulate. - 2. "LLVM IR": a particular IR used by the LLVM libraries for optimization - and generation of machine code. - - IUO (implicitly unwrapped optional) - A type like Optional, but it implicitly converts to its wrapped type. If - the value is ``nil`` during such a conversion, the program traps just as - it would when a normal Optional is force-unwrapped. IUOs implicitly - convert to and from normal Optionals with the same wrapped type. - - IWYU (include what you use) - The accepted wisdom that implementation files (``.cpp``, ``.c``, ``.m``, - ``.mm``) should explicitly ``#include`` or ``#import`` the headers they use. - Doing so prevents compilation errors when header files are included in a - different order, or when header files are modified to use forward - declarations instead of direct includes. - - LGTM - "Looks good to me." Used in code review to indicate approval with no further - comments. - - LLVM IR - See `IR`. - - lvalue - Pronounced "L-value". Refers to an expression that can be assigned to or - passed ``inout``. The term originally comes from C; the "L" refers to the - "l"eft side of an assignment operator. See also `rvalue`. - - main module - The module for the file or files currently being compiled. - - mandatory passes / mandatory optimizations - Transformations over SIL that run immediately after SIL generation. Once - all mandatory passes have run (and if no errors are found), the SIL is - considered `canonical `. - - metatype - The type of a value representing a type. Greg Parker has a good - explanation of `Objective-C's "metaclasses"`__; because Swift has types - that are *not* classes, a more general term is used. - - We also sometimes refer to a value representing a type as a "metatype - object" or just "metatype", usually within low-level contexts like IRGen - and LLDB. This is technically incorrect (it's just a "type object"), but - the malapropism happened early in the project and has stuck around. - - __ http://sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html - - model - A type that conforms to a particular protocol. Sometimes "concrete - model". Example: "Array and Set are both models of CollectionType". - - module - Has *many* uses in the Swift world. We may want to rename some of them. - #1 and #2 are the most common. - - 1. A unit of API distribution and grouping. The ``import`` declaration - brings modules into scope. Represented as ModuleDecl in the compiler. - 2. A compilation unit; that is, source files that are compiled together. - These files may contain cross-references. Represented as "the main - module" (a specific ModuleDecl). - 3. (as "SIL module") A container for SIL to be compiled together, along - with various context for the compilation. - 4. (as "LLVM module") A collection of LLVM IR to be compiled together. - Always created in an LLVMContext. - 5. A file containing serialized AST and SIL information for a source file - or entire compilation unit. Often "swiftmodule file", with "swiftmodule" - pronounced as a single word. - 6. (as "Clang module") A set of self-contained C-family header files. - Represented by a ClangModuleUnit in the Swift compiler, each of which is - contained in its own ModuleDecl. For more information, see - `Clang's documentation for Modules`__. - 7. Shorthand for a "precompiled module file"; effectively "precompiled - headers" for an entire Clang module. Never used directly by Swift. - See also `module cache`. - - __ http://clang.llvm.org/docs/Modules.html - - module cache - Clang's cache directory for precompiled module files. As cache files, these - are not forward-compatible, and so cannot be loaded by different versions - of Clang (or programs using Clang, like the Swift compiler). Normally this - is fine, but occasionally a development compiler will not have proper - version information and may try to load older module files, resulting in - crashes in ``clang::ASTReader``. - - NFC - "No functionality change." Written in commit messages that are intended to - have no change on the compiler or library's behavior, though for some this - refers to having the *same* implementation and for others merely an - *equivalent* one. "NFC" is typically used to explain why a patch has no - included testcase, since the Swift project requires testcases for all - patches that change functionality. - - open existential - An `existential` value with its dynamic type pulled out, so that the - compiler can do something with it. - - overlay - A wrapper library that is implicitly imported "on top of" another library. - It contains an @_exported import of the underlying library, but it augments - it with additional APIs which, for one reason or another, are not included - in the underlying library directly. - - There are two kinds of overlays: - - A "clang overlay" (the older kind, so it's often just called an "overlay") - is a Swift library that adds Swift-specific functionality to a C-family - library or framework. Clang overlays are used with system libraries that - cannot be modified to add Swift features. A clang overlay has the same - module name as the underlying library and can do a few special things that - normal modules can't, like adding required initializers to classes. If a - module has a clang overlay, the Clang Importer will always load it unless it - is actually compiling the overlay itself. Apple has a number of clang - overlays for its own SDKs in stdlib/public/Darwin/. - - A "separately-imported overlay" is a separate module with its own name. - Unlike a clang overlay, it can be imported in some SourceFiles and not - others. When the compiler processes import declarations, it determines which - separately-imported overlays need to be imported and then adds them to the - list of imports for that file; name lookup also knows to look through the - overlay when it looks for declarations in the underlying module. - Separately-imported overlays are used to implement the "cross-import - overlays" feature, which is used to augment a module with additional - functionality when it is imported alongside another module. - - parent type - The type in which a given declaration is nested. For example:: - - struct Outer { - struct Inner { - } - } - - ``Outer`` is the parent type of ``Inner``. - - Note that the terms "parent type" and "superclass" refer to completely - different concepts. - - PCH - Precompiled header, a type of file ending in .pch. A precompiled header is - like a precompiled module, in the sense that it's the same file format and - is just a cache file produced by clang and read by ``clang::ASTReader``. The - difference is that PCH files are not "modular": they do not correspond to a - named module, and cannot be read in any order or imported by module-name; - rather they must be the first file parsed by the compiler. PCHs are used - only to accelerate the process of reading C/C++/Objective-C headers, such as - the bridging headers read in by the ``-import-objc-header`` command-line - flag to swiftc. - - PR - 1. "Problem Report": An issue reported in `LLVM's bug tracker`__. - See also `SR`. - 2. "pull request" - - __ https://llvm.org/bugs/ - - primary file - The file currently being compiled, as opposed to the other files that are - only needed for context. See also - `Whole-Module Optimization `. - - private dependency - A kind of dependency edge relevant to the incremental name tracking - subsystem. A private dependency (as opposed to a - `cascading dependency `) declares a dependency edge - from one file to a name referenced in that file that does not - require further transitive evaluation of dependency edges by the Swift - driver. Private dependencies are therefore cheaper than cascading - dependencies, but must be used with the utmost care or dependent files will - fail to rebuild and the result will most certainly be a miscompile. - See :doc:`DependencyAnalysis.rst `. - - QoI - "Quality of implementation." The term is meant to describe not how - well-engineered a particular implementation is, but how much value it - provides to users beyond a sort of minimum expectation. Good diagnostics - are a matter of QoI, as is good unoptimized performance. For example, a - comment like "FIXME: QoI could be improved here" is suggesting that there's - some sort of non-mandatory work that could be done that would improve the - behavior of the compiler--it is not just a general statement that the code - needs to be improved. - - It's possible that this term was originally "quality of life", written as - "Qol", referring to the experience of end users. At some point along its - history, the lowercase "L" was misinterpreted as an uppercase "i", and a - new meaning derived. Swift inherited this term from LLVM, which got it from - GCC. - - Radar - `Apple's bug-tracking system`__, or an issue reported on that system. - - __ https://bugreport.apple.com - - raw SIL - SIL just after being generated, not yet in a form that can be used for - IR generation. - See `mandatory passes `. - - reabstraction - An implicit representation change that occurs when a value is used with - a different `abstraction pattern` from its current representation. - - refutable pattern - A pattern that may not always match. These include patterns such as: - - 1. Isa check, e.g. ``case let x as String:``. - 2. Enum case check: e.g. ``case .none:``. - 3. Expr pattern: e.g. ``case foo():``. - - resilient - Describes a type or function where making certain changes will not break - binary compatibility. See :doc:`LibraryEvolution.rst `. - - runtime - Code that implements a language's dynamic features that aren't just - compiled down to plain instructions. For example, Swift's runtime library - includes support for dynamic casting and for the Mirror-based reflection. - - rvalue - Pronounced "R-value". Represents an expression that can be used as a value; - in Swift this is nearly every expression, so we don't use the term very - often. The term originally comes from C; the "R" refers to the "r"ight side - of an assignment operator. Contrast with `lvalue`. - - script mode - The parsing mode that allows top-level imperative code in a source file. - - Sema - Short for 'Semantic Analysis', the compiler pass that performs type checking, - validation, and expression rewriting before SILGen. - - SIL - "Swift Intermediate Language". A high-level IR used by the Swift compiler - for flow-sensitive diagnostics, optimization, and LLVM IR generation. - - SR - An issue reported on `bugs.swift.org `_. A - backronym for "Swift Report"; really the name is derived from LLVM's - idiomatic use of "PR" ("Problem Report") for its bugs. We didn't go with - "PR" for Swift because we wanted to be able to unambiguously reference - LLVM bugs. - - stdlib - "Standard library". Sometimes this just means the "Swift" module (also - known as "swiftCore"); sometimes it means everything in the stdlib/ - directory. Pronounced "stid-lib" or "ess-tee-dee-lib". - - sugared type - A type that may have been written in a more convenient way, using special - language syntax or a typealias. (For example, ``Int?`` is the sugared form - of ``Optional``.) Sugared types preserve information about the form - and use of the type even though the behavior usually does not change - (except for things like access control). Contrast with `canonical type`. - - thunk - In the Swift compiler, a synthesized function whose only purpose is to - perform some kind of adjustment in order to call another function. For - example, Objective-C and Swift have different calling conventions, so the - Swift compiler generates a thunk for use in Objective-C that calls through - to the real Swift implementation. - - trap - A deterministic runtime failure. Can be used as both as a noun ("Using an - out-of-bounds index on an Array results in a trap") and a verb - ("Force-unwrapping a nil Optional will trap"). - - type metadata - The runtime representation of a type, and everything you can do with it. - Like a ``Class`` in Objective-C, but for any type. - - USR - A Unified Symbol Resolution (USR) is a string that identifies a particular - entity (function, class, variable, etc.) within a program. USRs can be - compared across translation units to determine, e.g., when references in - one translation refer to an entity defined in another translation unit. - - VWT (value witness table) - A runtime structure that describes how to do basic operations on an unknown - value, like "assign", "copy", and "destroy". (For example, does copying - this value require any retains?) - - Only conceptually related to a `witness table`. - - vtable (virtual dispatch table) - A map attached to a class of which implementation to use for each - overridable method in the class. Unlike an Objective-C method table, - vtable keys are just offsets, making lookup much simpler at the cost of - dynamism and duplicated information about *non*-overridden methods. - - WIP - "Work-in-progress". Placed in PR titles to indicate that the PR is not ready - for review or merging. - - witness - The value or type that satisfies a protocol requirement. - - witness table - The SIL (and runtime) representation of a `conformance`; essentially a - `vtable ` but for a protocol instead of - a class. - - Only conceptually related to a `value witness table `. - - WMO (whole-module optimization) - A compilation mode where all files in a module are compiled in a single - process. In this mode there is no `primary file`; all files are parsed, - type-checked, and optimized together at the SIL level. LLVM optimization - and object file generation may happen all together or in separate threads. From 7d8c75489d7d216fef53acf6d2522fd5b89a9c29 Mon Sep 17 00:00:00 2001 From: Valeriy Van Date: Sat, 2 May 2020 13:45:56 +0200 Subject: [PATCH 28/35] Fixes example snippet in Reverse.swift --- stdlib/public/core/Reverse.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/public/core/Reverse.swift b/stdlib/public/core/Reverse.swift index e70d5678152b2..b9c63f76605bb 100644 --- a/stdlib/public/core/Reverse.swift +++ b/stdlib/public/core/Reverse.swift @@ -156,7 +156,7 @@ extension ReversedCollection { /// // name[aIndex] == "a" /// /// let reversedName = name.reversed() - /// let i = ReversedIndex(aIndex) + /// let i = ReversedCollection.Index(aIndex) /// // reversedName[i] == "r" /// /// The element at the position created using `ReversedIndex<...>(aIndex)` is From 959eab036145b1d38dd9e9ab9aff8c0c23a15f9a Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Sat, 2 May 2020 05:20:02 -0700 Subject: [PATCH 29/35] [Gardening] Update reference to lexicon --- docs/Driver.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Driver.md b/docs/Driver.md index 51ddd1b0fdb67..2034b8e215072 100644 --- a/docs/Driver.md +++ b/docs/Driver.md @@ -26,7 +26,7 @@ Some terms: - For the purposes of this document, a _module_ is a single distributable unit of API. (We use this term for a lot of other things too, though; check out - [Lexicon.rst](Lexicon.rst) for the full list.) "Foundation" is a single + [Lexicon.md](Lexicon.md) for the full list.) "Foundation" is a single module, as is the Swift standard library ("Swift"). An app is a module too. - A _compilation unit_ is a set of source files that are compiled together. In From 2753fc5715f90fd1c369981dfd3e8b514974929f Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Sat, 2 May 2020 16:27:36 +0300 Subject: [PATCH 30/35] Diags: Use the declared type for diagnosing inheritance from final class --- include/swift/AST/DiagnosticsSema.def | 2 +- lib/Sema/TypeCheckDeclPrimary.cpp | 3 ++- test/attr/attr_final.swift | 5 +++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index e225c26427bbd..92f103ffc33aa 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -2536,7 +2536,7 @@ NOTE(superclass_here,none,"superclass is declared here", ()) ERROR(superclass_of_open_not_open,none, "superclass %0 of open class must be open", (Type)) ERROR(inheritance_from_final_class,none, - "inheritance from a final class %0", (Identifier)) + "inheritance from a final class %0", (Type)) ERROR(inheritance_from_unspecialized_objc_generic_class,none, "inheritance from a generic Objective-C class %0 must bind " "type parameters of %0 to specific concrete types", (Identifier)) diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index f159f272e057f..cd67e4149ab00 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -1943,7 +1943,8 @@ class DeclChecker : public DeclVisitor { bool isInvalidSuperclass = false; if (Super->isFinal()) { - CD->diagnose(diag::inheritance_from_final_class, Super->getName()); + CD->diagnose(diag::inheritance_from_final_class, + Super->getDeclaredType()); // FIXME: should this really be skipping the rest of decl-checking? return; } diff --git a/test/attr/attr_final.swift b/test/attr/attr_final.swift index 5d713f9ac491a..9433e0f617675 100644 --- a/test/attr/attr_final.swift +++ b/test/attr/attr_final.swift @@ -81,3 +81,8 @@ class Sub2 : Super2 { //// expected-error{{inheritance from a final class 'Super final override init() {} // expected-error {{'final' modifier cannot be applied to this declaration}} {{3-9=}} } + +struct Box { + final class Super3 {} +} +class Sub3: Box.Super3 {} // expected-error{{inheritance from a final class 'Box.Super3'}} From 6b14c2a74609f3a2d2ab98829ff94800eba12ecc Mon Sep 17 00:00:00 2001 From: Kyle Macomber Date: Sat, 2 May 2020 13:04:20 -0700 Subject: [PATCH 31/35] [Docs] Clarifies `Identifiable` requirements (#31472) [SR-12528](https://bugs.swift.org/browse/SR-12528) rdar://62201744 --- stdlib/public/core/Identifiable.swift | 34 ++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/stdlib/public/core/Identifiable.swift b/stdlib/public/core/Identifiable.swift index c9a9147abf8c8..14791c9259532 100644 --- a/stdlib/public/core/Identifiable.swift +++ b/stdlib/public/core/Identifiable.swift @@ -10,14 +10,42 @@ // //===----------------------------------------------------------------------===// -/// A class of types whose instances hold the value of an entity with stable identity. +/// A class of types whose instances hold the value of an entity with stable +/// identity. +/// +/// Use the `Identifiable` protocol to provide a stable notion of identity to a +/// class or value type. For example, you could define a `User` type with an `id` +/// property that is stable across your app and your app's database storage. +/// You could use the `id` property to identify a particular user even if other +/// data fields change, such as the user's name. +/// +/// `Identifiable` leaves the duration and scope of the identity unspecified. +/// Identities could be any of the following: +/// +/// - Guaranteed always unique (e.g. UUIDs). +/// - Persistently unique per environment (e.g. database record keys). +/// - Unique for the lifetime of a process (e.g. global incrementing integers). +/// - Unique for the lifetime of an object (e.g. object identifiers). +/// - Unique within the current collection (e.g. collection index). +/// +/// It is up to both the conformer and the receiver of the protocol to document +/// the nature of the identity. +/// +/// Conforming to the Identifiable Protocol +/// ======================================= +/// +/// `Identifiable` provides a default implementation for class types (using +/// `ObjectIdentifier`), which is only guaranteed to remain unique for the +/// lifetime of an object. If an object has a stronger notion of identity, it +/// may be appropriate to provide a custom implementation. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) public protocol Identifiable { - /// A type representing the stable identity of the entity associated with `self`. + /// A type representing the stable identity of the entity associated with + /// an instance. associatedtype ID: Hashable - /// The stable identity of the entity associated with `self`. + /// The stable identity of the entity associated with this instance. var id: ID { get } } From d14bb1eed53c9ffd7bfe89b307e97a2595214c6e Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Fri, 1 May 2020 10:11:55 -0700 Subject: [PATCH 32/35] Driver: sink the `static-stdlib-args.lnk` generation This moves the standard library response file into the standard library generation rather than in the driver. Although the driver consumes this file, it is part of the standard library as it knows its dependencies. This removes the last of the ICU references in the toolchain. --- lib/Driver/CMakeLists.txt | 39 ---------------------------- stdlib/public/runtime/CMakeLists.txt | 34 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 39 deletions(-) diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt index 6b36e0e2eda0d..380c3c6dc8a0c 100644 --- a/lib/Driver/CMakeLists.txt +++ b/lib/Driver/CMakeLists.txt @@ -26,42 +26,3 @@ target_link_libraries(swiftDriver PRIVATE swiftAST swiftBasic swiftOption) - -# Generate the static-stdlib-args.lnk file used by -static-stdlib option -# for 'GenericUnix' (eg linux) -if(SWIFT_BUILD_STATIC_STDLIB) - set(static_stdlib_lnk_file_list) - foreach(sdk ${SWIFT_CONFIGURED_SDKS}) - if("${SWIFT_SDK_${sdk}_OBJECT_FORMAT}" STREQUAL "ELF") - string(TOLOWER "${sdk}" lowercase_sdk) - if(SWIFT_${SWIFT_HOST_VARIANT_SDK}_${SWIFT_HOST_VARIANT_ARCH}_ICU_STATICLIB) - set(ICU_STATICLIB "TRUE") - else() - set(ICU_STATICLIB "FALSE") - find_package(ICU REQUIRED COMPONENTS uc i18n) - get_filename_component(ICU_UC_LIBDIR "${ICU_UC_LIBRARIES}" DIRECTORY) - get_filename_component(ICU_I18N_LIBDIR "${ICU_I18N_LIBRARIES}" DIRECTORY) - endif() - set(linkfile "${lowercase_sdk}/static-stdlib-args.lnk") - add_custom_command_target(swift_static_stdlib_${sdk}_args - COMMAND - "${SWIFT_SOURCE_DIR}/utils/gen-static-stdlib-link-args" - "${sdk}" - "${SWIFTSTATICLIB_DIR}/${linkfile}" - "${ICU_STATICLIB}" - "${ICU_UC_LIBDIR}" - "${ICU_I18N_LIBDIR}" - OUTPUT - "${SWIFTSTATICLIB_DIR}/${linkfile}" - DEPENDS - "${SWIFT_SOURCE_DIR}/utils/gen-static-stdlib-link-args") - - list(APPEND static_stdlib_lnk_file_list ${swift_static_stdlib_${sdk}_args}) - swift_install_in_component(FILES "${SWIFTSTATICLIB_DIR}/${linkfile}" - DESTINATION "lib/swift_static/${lowercase_sdk}" - COMPONENT stdlib) - endif() - endforeach() - add_custom_target(swift_static_lnk_args ALL DEPENDS ${static_stdlib_lnk_file_list}) - add_dependencies(stdlib swift_static_lnk_args) -endif() diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt index 53499105de23b..aad215ac87e15 100644 --- a/stdlib/public/runtime/CMakeLists.txt +++ b/stdlib/public/runtime/CMakeLists.txt @@ -263,6 +263,40 @@ foreach(sdk ${SWIFT_CONFIGURED_SDKS}) ${swiftImageRegistration-${arch_suffix}}) add_dependencies(stdlib swift-stdlib-${arch_suffix} swiftImageRegistration-${arch_suffix}) endif() + + # Generate the static-stdlib-args.lnk file used by -static-stdlib option for + # 'GenericUnix' (eg linux) + if(${SWIFT_SDK_${sdk}_OBJECT_FORMAT} STREQUAL ELF) + string(TOLOWER "${sdk}" lowercase_sdk) + if(SWIFT_${SWIFT_HOST_VARIANT_SDK}_${SWIFT_HOST_VARIANT_ARCH}_ICU_STATICLIB) + set(ICU_STATICLIB "TRUE") + else() + set(ICU_STATICLIB "FALSE") + find_package(ICU REQUIRED COMPONENTS uc i18n) + get_filename_component(ICU_UC_LIBDIR "${ICU_UC_LIBRARIES}" DIRECTORY) + get_filename_component(ICU_I18N_LIBDIR "${ICU_I18N_LIBRARIES}" DIRECTORY) + endif() + set(linkfile "${lowercase_sdk}/static-stdlib-args.lnk") + add_custom_command_target(swift_static_stdlib_${sdk}_args + COMMAND + "${SWIFT_SOURCE_DIR}/utils/gen-static-stdlib-link-args" + "${sdk}" + "${SWIFTSTATICLIB_DIR}/${linkfile}" + "${ICU_STATICLIB}" + "${ICU_UC_LIBDIR}" + "${ICU_I18N_LIBDIR}" + OUTPUT + "${SWIFTSTATICLIB_DIR}/${linkfile}" + DEPENDS + "${SWIFT_SOURCE_DIR}/utils/gen-static-stdlib-link-args") + + list(APPEND static_stdlib_lnk_file_list ${swift_static_stdlib_${sdk}_args}) + swift_install_in_component(FILES "${SWIFTSTATICLIB_DIR}/${linkfile}" + DESTINATION "lib/swift_static/${lowercase_sdk}" + COMPONENT stdlib) + endif() endforeach() endforeach() +add_custom_target(swift_static_lnk_args ALL DEPENDS ${static_stdlib_lnk_file_list}) +add_dependencies(stdlib swift_static_lnk_args) From 5ac1926f509bc7a21ccf05a6e841aa9303e90ff2 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Sun, 3 May 2020 02:09:00 -0300 Subject: [PATCH 33/35] [CSDiagnostics] Break to the fallbacks when no specific diagnostics is found --- lib/Sema/CSDiagnostics.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index 40ea93ccc00ef..0eafcd15dd481 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -659,10 +659,6 @@ bool GenericArgumentsMismatchFailure::diagnoseAsError() { break; } - case ConstraintLocator::GenericArgument: { - break; - } - case ConstraintLocator::OptionalPayload: { // If we have an inout expression, this comes from an // InoutToPointer argument mismatch failure. @@ -689,7 +685,7 @@ bool GenericArgumentsMismatchFailure::diagnoseAsError() { } default: - return false; + break; } } From 08be3d284e8ac5b6168a859051fc28c5937023ee Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Sun, 3 May 2020 02:09:56 -0300 Subject: [PATCH 34/35] [tests] Add SR-12725 tests --- test/Constraints/diagnostics.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift index 486cd37ee2d63..8e976afc15e02 100644 --- a/test/Constraints/diagnostics.swift +++ b/test/Constraints/diagnostics.swift @@ -1470,3 +1470,10 @@ func gericArgToParamInout(_ x: inout [[Int]]) { // expected-note {{change variab // expected-note@-1 {{arguments to generic parameter 'Element' ('Int' and 'String') are expected to be equal}} // expected-error@-2 {{inout argument could be set to a value with a type other than '[[Int]]'; use a value declared as type '[[String]]?' instead}} } + +// SR-12725 +struct SR12725 {} // expected-note {{arguments to generic parameter 'E' ('Int' and 'Double') are expected to be equal}} +func generic(_ value: inout T, _ closure: (SR12725) -> Void) {} + +let arg: Int +generic(&arg) { (g: SR12725) -> Void in } // expected-error {{cannot convert value of type '(SR12725) -> Void' to expected argument type '(SR12725) -> Void'}} From b340b21e63be474e6d0429eaeff8cda1b1e431f6 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Tue, 5 May 2020 10:39:02 +0100 Subject: [PATCH 35/35] Fix lowercase_sdk not redefined in runtime CMake --- stdlib/public/runtime/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt index 7501480a0434b..51c4cec96a5e7 100644 --- a/stdlib/public/runtime/CMakeLists.txt +++ b/stdlib/public/runtime/CMakeLists.txt @@ -322,10 +322,10 @@ foreach(sdk ${SWIFT_CONFIGURED_SDKS}) add_dependencies(stdlib swift-stdlib-${arch_suffix} swiftImageRegistration-${arch_suffix}) endif() + string(TOLOWER "${sdk}" lowercase_sdk) # Generate the static-stdlib-args.lnk file used by -static-stdlib option for # 'GenericUnix' (eg linux) if(${SWIFT_SDK_${sdk}_OBJECT_FORMAT} STREQUAL ELF) - string(TOLOWER "${sdk}" lowercase_sdk) if(SWIFT_${SWIFT_HOST_VARIANT_SDK}_${SWIFT_HOST_VARIANT_ARCH}_ICU_STATICLIB) set(ICU_STATICLIB "TRUE") else()