diff --git a/include/swift/AST/DiagnosticEngine.h b/include/swift/AST/DiagnosticEngine.h index ad73eac78834b..08a2c93c152bf 100644 --- a/include/swift/AST/DiagnosticEngine.h +++ b/include/swift/AST/DiagnosticEngine.h @@ -279,6 +279,19 @@ namespace swift { } }; + namespace detail { + /// Stores information for an active diagnostic that hasn't been emitted yet. + /// This includes both "in-flight" diagnostics as well as diagnostics queued + /// for a transaction. + struct ActiveDiagnostic { + Diagnostic Diag; + SmallVector WrappedDiagnostics; + SmallVector, 4> WrappedDiagnosticArgs; + + ActiveDiagnostic(Diagnostic diag) : Diag(std::move(diag)) {} + }; + } // namespace detail + /// A diagnostic that has no input arguments, so it is trivially-destructable. using ZeroArgDiagnostic = Diag<>; @@ -293,33 +306,40 @@ namespace swift { friend class DiagnosticEngine; DiagnosticEngine *Engine; + unsigned Idx; bool IsActive; /// Create a new in-flight diagnostic. /// /// This constructor is only available to the DiagnosticEngine. - InFlightDiagnostic(DiagnosticEngine &Engine) - : Engine(&Engine), IsActive(true) { } - + InFlightDiagnostic(DiagnosticEngine &Engine, unsigned idx) + : Engine(&Engine), Idx(idx), IsActive(true) {} + InFlightDiagnostic(const InFlightDiagnostic &) = delete; InFlightDiagnostic &operator=(const InFlightDiagnostic &) = delete; InFlightDiagnostic &operator=(InFlightDiagnostic &&) = delete; + /// Retrieve the underlying active diagnostic information. + detail::ActiveDiagnostic &getActiveDiag() const; + + /// Retrieve the underlying diagnostic. + Diagnostic &getDiag() const { return getActiveDiag().Diag; } + public: /// Create an active but unattached in-flight diagnostic. /// /// The resulting diagnostic can be used as a dummy, accepting the /// syntax to add additional information to a diagnostic without /// actually emitting a diagnostic. - InFlightDiagnostic() : Engine(0), IsActive(true) { } - + InFlightDiagnostic() : Engine(0), Idx(0), IsActive(true) {} + /// Transfer an in-flight diagnostic to a new object, which is /// typically used when returning in-flight diagnostics. InFlightDiagnostic(InFlightDiagnostic &&Other) - : Engine(Other.Engine), IsActive(Other.IsActive) { + : Engine(Other.Engine), Idx(Other.Idx), IsActive(Other.IsActive) { Other.IsActive = false; } - + ~InFlightDiagnostic() { if (IsActive) flush(); @@ -784,16 +804,12 @@ namespace swift { /// Tracks diagnostic behaviors and state DiagnosticState state; - /// The currently active diagnostic, if there is one. - std::optional ActiveDiagnostic; - - /// Diagnostics wrapped by ActiveDiagnostic, if any. - SmallVector WrappedDiagnostics; - SmallVector, 4> WrappedDiagnosticArgs; + /// The currently active diagnostics. + SmallVector ActiveDiagnostics; /// All diagnostics that have are no longer active but have not yet /// been emitted due to an open transaction. - SmallVector TentativeDiagnostics; + SmallVector TentativeDiagnostics; llvm::BumpPtrAllocator TransactionAllocator; /// A set of all strings involved in current transactional chain. @@ -816,6 +832,9 @@ namespace swift { /// emitted once all transactions have closed. unsigned TransactionCount = 0; + /// The number of currently in-flight diagnostics. + unsigned NumActiveDiags = 0; + /// For batch mode, use this to know where to output a diagnostic from a /// non-primary file. It's any location in the buffer of the current primary /// input being compiled. @@ -851,7 +870,7 @@ namespace swift { public: explicit DiagnosticEngine(SourceManager &SourceMgr) - : SourceMgr(SourceMgr), ActiveDiagnostic(), + : SourceMgr(SourceMgr), ActiveDiagnostics(), TransactionStrings(TransactionAllocator), DiagnosticStringsSaver(DiagnosticStringsAllocator) {} @@ -870,6 +889,7 @@ namespace swift { } void flushConsumers() { + ASSERT(NumActiveDiags == 0 && "Expected in-flight diags to be flushed"); for (auto consumer : Consumers) consumer->flush(); } @@ -1001,10 +1021,9 @@ namespace swift { /// \returns An in-flight diagnostic, to which additional information can /// be attached. InFlightDiagnostic diagnose(SourceLoc Loc, const Diagnostic &D) { - assert(!ActiveDiagnostic && "Already have an active diagnostic"); - ActiveDiagnostic = D; - ActiveDiagnostic->setLoc(Loc); - return InFlightDiagnostic(*this); + auto IFD = beginDiagnostic(D); + getActiveDiagnostic(IFD).Diag.setLoc(Loc); + return IFD; } /// Emit a diagnostic with the given set of diagnostic arguments. @@ -1080,10 +1099,9 @@ namespace swift { /// \returns An in-flight diagnostic, to which additional information can /// be attached. InFlightDiagnostic diagnose(const Decl *decl, const Diagnostic &diag) { - assert(!ActiveDiagnostic && "Already have an active diagnostic"); - ActiveDiagnostic = diag; - ActiveDiagnostic->setDecl(decl); - return InFlightDiagnostic(*this); + auto IFD = beginDiagnostic(diag); + getActiveDiagnostic(IFD).Diag.setDecl(decl); + return IFD; } /// Emit a diagnostic with the given set of diagnostic arguments. @@ -1137,16 +1155,21 @@ namespace swift { DiagnosticFormatOptions FormatOpts = DiagnosticFormatOptions()); private: + /// Begins a new in-flight diagnostic. + InFlightDiagnostic beginDiagnostic(const Diagnostic &D); + + /// Ends an in-flight diagnostic. Once all in-flight diagnostics have ended, + /// they will either be emitted, or captured by an open transaction. + void endDiagnostic(const InFlightDiagnostic &D); + /// Called when tentative diagnostic is about to be flushed, /// to apply any required transformations e.g. copy string arguments /// to extend their lifetime. void onTentativeDiagnosticFlush(Diagnostic &diagnostic); - /// Flush the active diagnostic. - void flushActiveDiagnostic(); - - /// Retrieve the active diagnostic. - Diagnostic &getActiveDiagnostic() { return *ActiveDiagnostic; } + /// Retrieve the stored active diagnostic for a given InFlightDiagnostic. + detail::ActiveDiagnostic & + getActiveDiagnostic(const InFlightDiagnostic &diag); /// Generate DiagnosticInfo for a Diagnostic to be passed to consumers. std::optional @@ -1162,7 +1185,7 @@ namespace swift { /// Handle a new diagnostic, which will either be emitted, or added to an /// active transaction. - void handleDiagnostic(Diagnostic &&diag); + void handleDiagnostic(detail::ActiveDiagnostic &&diag); /// Clear any tentative diagnostics. void clearTentativeDiagnostics(); @@ -1291,12 +1314,12 @@ namespace swift { } bool hasErrors() const { - ArrayRef diagnostics(Engine.TentativeDiagnostics.begin() + - PrevDiagnostics, - Engine.TentativeDiagnostics.end()); + ArrayRef diagnostics( + Engine.TentativeDiagnostics.begin() + PrevDiagnostics, + Engine.TentativeDiagnostics.end()); for (auto &diagnostic : diagnostics) { - auto behavior = Engine.state.determineBehavior(diagnostic); + auto behavior = Engine.state.determineBehavior(diagnostic.Diag); if (behavior == DiagnosticBehavior::Fatal || behavior == DiagnosticBehavior::Error) return true; @@ -1361,14 +1384,14 @@ namespace swift { // The first diagnostic is assumed to be the parent. If this is not an // error or warning, we'll assert later when trying to add children. - Diagnostic &parent = Engine.TentativeDiagnostics[PrevDiagnostics]; + Diagnostic &parent = Engine.TentativeDiagnostics[PrevDiagnostics].Diag; // Associate the children with the parent. for (auto diag = Engine.TentativeDiagnostics.begin() + PrevDiagnostics + 1; diag != Engine.TentativeDiagnostics.end(); ++diag) { - diag->setIsChildNote(true); - parent.addChildNote(std::move(*diag)); + diag->Diag.setIsChildNote(true); + parent.addChildNote(std::move(diag->Diag)); } // Erase the children, they'll be emitted alongside their parent. diff --git a/lib/AST/DiagnosticEngine.cpp b/lib/AST/DiagnosticEngine.cpp index a26d6eafec562..34c6ec51ab86e 100644 --- a/lib/AST/DiagnosticEngine.cpp +++ b/lib/AST/DiagnosticEngine.cpp @@ -205,11 +205,14 @@ static char extractCharBefore(SourceManager &SM, SourceLoc Loc) { return chars[0]; } +detail::ActiveDiagnostic &InFlightDiagnostic::getActiveDiag() const { + return Engine->getActiveDiagnostic(*this); +} + InFlightDiagnostic &InFlightDiagnostic::highlight(SourceRange R) { assert(IsActive && "Cannot modify an inactive diagnostic"); if (Engine && R.isValid()) - Engine->getActiveDiagnostic() - .addRange(toCharSourceRange(Engine->SourceMgr, R)); + getDiag().addRange(toCharSourceRange(Engine->SourceMgr, R)); return *this; } @@ -217,15 +220,14 @@ InFlightDiagnostic &InFlightDiagnostic::highlightChars(SourceLoc Start, SourceLoc End) { assert(IsActive && "Cannot modify an inactive diagnostic"); if (Engine && Start.isValid()) - Engine->getActiveDiagnostic() - .addRange(toCharSourceRange(Engine->SourceMgr, Start, End)); + getDiag().addRange(toCharSourceRange(Engine->SourceMgr, Start, End)); return *this; } InFlightDiagnostic &InFlightDiagnostic::highlightChars(CharSourceRange Range) { assert(IsActive && "Cannot modify an inactive diagnostic"); if (Engine && Range.getStart().isValid()) - Engine->getActiveDiagnostic().addRange(Range); + getDiag().addRange(Range); return *this; } @@ -260,7 +262,7 @@ InFlightDiagnostic &InFlightDiagnostic::fixItRemove(SourceRange R) { charRange = CharSourceRange(charRange.getStart(), charRange.getByteLength()+1); } - Engine->getActiveDiagnostic().addFixIt(Diagnostic::FixIt(charRange, {}, {})); + getDiag().addFixIt(Diagnostic::FixIt(charRange, {}, {})); return *this; } @@ -270,8 +272,7 @@ InFlightDiagnostic::fixItReplace(SourceRange R, StringRef FormatString, auto &SM = Engine->SourceMgr; auto charRange = toCharSourceRange(SM, R); - Engine->getActiveDiagnostic().addFixIt( - Diagnostic::FixIt(charRange, FormatString, Args)); + getDiag().addFixIt(Diagnostic::FixIt(charRange, FormatString, Args)); return *this; } @@ -307,9 +308,8 @@ InFlightDiagnostic::fixItReplaceChars(SourceLoc Start, SourceLoc End, ArrayRef Args) { assert(IsActive && "Cannot modify an inactive diagnostic"); if (Engine && Start.isValid()) - Engine->getActiveDiagnostic().addFixIt( - Diagnostic::FixIt(toCharSourceRange(Engine->SourceMgr, Start, End), - FormatString, Args)); + getDiag().addFixIt(Diagnostic::FixIt( + toCharSourceRange(Engine->SourceMgr, Start, End), FormatString, Args)); return *this; } @@ -350,7 +350,7 @@ SourceLoc DiagnosticEngine::getBestAddImportFixItLoc(SourceFile *SF) const { InFlightDiagnostic &InFlightDiagnostic::fixItAddImport(StringRef ModuleName) { assert(IsActive && "Cannot modify an inactive diagnostic"); - auto decl = Engine->ActiveDiagnostic->getDecl(); + auto decl = getDiag().getDecl(); if (!decl) return *this; @@ -428,16 +428,14 @@ InFlightDiagnostic &InFlightDiagnostic::fixItExchange(SourceRange R1, auto text1 = SM.extractText(charRange1); auto text2 = SM.extractText(charRange2); - Engine->getActiveDiagnostic().addFixIt( - Diagnostic::FixIt(charRange1, "%0", {text2})); - Engine->getActiveDiagnostic().addFixIt( - Diagnostic::FixIt(charRange2, "%0", {text1})); + getDiag().addFixIt(Diagnostic::FixIt(charRange1, "%0", {text2})); + getDiag().addFixIt(Diagnostic::FixIt(charRange2, "%0", {text1})); return *this; } InFlightDiagnostic & InFlightDiagnostic::limitBehavior(DiagnosticBehavior limit) { - Engine->getActiveDiagnostic().setBehaviorLimit(limit); + getDiag().setBehaviorLimit(limit); return *this; } @@ -496,30 +494,33 @@ InFlightDiagnostic::wrapIn(const Diagnostic &wrapper) { // so we don't get a None return or influence future diagnostics. DiagnosticState tempState; Engine->state.swap(tempState); - llvm::SaveAndRestore - limit(Engine->getActiveDiagnostic().BehaviorLimit, - DiagnosticBehavior::Unspecified); - Engine->WrappedDiagnostics.push_back(*Engine->diagnosticInfoForDiagnostic( - Engine->getActiveDiagnostic(), /* includeDiagnosticName= */ false)); + auto &ActiveDiag = getActiveDiag(); + auto &Diag = ActiveDiag.Diag; + + llvm::SaveAndRestore limit( + Diag.BehaviorLimit, DiagnosticBehavior::Unspecified); + + ActiveDiag.WrappedDiagnostics.push_back(*Engine->diagnosticInfoForDiagnostic( + Diag, /* includeDiagnosticName= */ false)); Engine->state.swap(tempState); - auto &wrapped = Engine->WrappedDiagnostics.back(); + auto &wrapped = ActiveDiag.WrappedDiagnostics.back(); // Copy and update its arg list. - Engine->WrappedDiagnosticArgs.emplace_back(wrapped.FormatArgs); - wrapped.FormatArgs = Engine->WrappedDiagnosticArgs.back(); + ActiveDiag.WrappedDiagnosticArgs.emplace_back(wrapped.FormatArgs); + wrapped.FormatArgs = ActiveDiag.WrappedDiagnosticArgs.back(); // Overwrite the ID and arguments with those from the wrapper. - Engine->getActiveDiagnostic().ID = wrapper.ID; - Engine->getActiveDiagnostic().Args = wrapper.Args; + Diag.ID = wrapper.ID; + Diag.Args = wrapper.Args; // Intentionally keeping the original GroupID here // Set the argument to the diagnostic being wrapped. ASSERT(wrapper.getArgs().front().getKind() == DiagnosticArgumentKind::Diagnostic); - Engine->getActiveDiagnostic().Args.front() = &wrapped; + Diag.Args.front() = &wrapped; return *this; } @@ -530,7 +531,7 @@ void InFlightDiagnostic::flush() { IsActive = false; if (Engine) - Engine->flushActiveDiagnostic(); + Engine->endDiagnostic(*this); } void Diagnostic::addChildNote(Diagnostic &&D) { @@ -1354,32 +1355,48 @@ void DiagnosticState::updateFor(DiagnosticBehavior behavior) { previousBehavior = behavior; } -void DiagnosticEngine::flushActiveDiagnostic() { - assert(ActiveDiagnostic && "No active diagnostic to flush"); - handleDiagnostic(std::move(*ActiveDiagnostic)); - ActiveDiagnostic.reset(); +InFlightDiagnostic DiagnosticEngine::beginDiagnostic(const Diagnostic &D) { + unsigned idx = ActiveDiagnostics.size(); + ActiveDiagnostics.emplace_back(D); + NumActiveDiags += 1; + return InFlightDiagnostic(*this, idx); +} + +void DiagnosticEngine::endDiagnostic(const InFlightDiagnostic &D) { + // Decrement the number of active diagnostics. We wait until all in-flight + // diagnostics have ended to ensure a FIFO ordering. + ASSERT(NumActiveDiags > 0 && "Unbalanced call to endDiagnostic"); + NumActiveDiags -= 1; + if (NumActiveDiags > 0) + return; + + for (auto &D : ActiveDiagnostics) + handleDiagnostic(std::move(D)); + + ActiveDiagnostics.clear(); +} + +detail::ActiveDiagnostic & +DiagnosticEngine::getActiveDiagnostic(const InFlightDiagnostic &diag) { + return ActiveDiagnostics[diag.Idx]; } -void DiagnosticEngine::handleDiagnostic(Diagnostic &&diag) { +void DiagnosticEngine::handleDiagnostic(detail::ActiveDiagnostic &&diag) { if (TransactionCount == 0) { - emitDiagnostic(diag); - WrappedDiagnostics.clear(); - WrappedDiagnosticArgs.clear(); + emitDiagnostic(diag.Diag); } else { - onTentativeDiagnosticFlush(diag); + onTentativeDiagnosticFlush(diag.Diag); TentativeDiagnostics.emplace_back(std::move(diag)); } } void DiagnosticEngine::clearTentativeDiagnostics() { TentativeDiagnostics.clear(); - WrappedDiagnostics.clear(); - WrappedDiagnosticArgs.clear(); } void DiagnosticEngine::emitTentativeDiagnostics() { for (auto &diag : TentativeDiagnostics) { - emitDiagnostic(diag); + emitDiagnostic(diag.Diag); } clearTentativeDiagnostics(); } @@ -1410,11 +1427,15 @@ DiagnosticEngine::diagnosticInfoForDiagnostic(const Diagnostic &diagnostic, loc = decl->getLoc(); // If the location of the decl is invalid still, try to pretty-print the - // declaration into a buffer and capture the source location there. + // declaration into a buffer and capture the source location there. Make + // sure we don't have an active request running since printing AST can + // kick requests that may themselves emit diagnostics. This won't help the + // underlying cycle, but it at least stops us from overflowing the stack. if (loc.isInvalid()) { - loc = evaluateOrDefault( - decl->getASTContext().evaluator, PrettyPrintDeclRequest{decl}, - SourceLoc()); + PrettyPrintDeclRequest req(decl); + auto &eval = decl->getASTContext().evaluator; + if (!eval.hasActiveRequest(req)) + loc = evaluateOrDefault(eval, req, SourceLoc()); } } diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index 50925acd9a1c2..84d810a10fda1 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -5092,9 +5092,6 @@ namespace { // If the property is settable, we don't know whether the // user wanted the getter or setter. Provide notes for each. if (isSettable) { - // Flush the primary diagnostic. We have notes to add. - primaryDiag.flush(); - // Add notes for the getter and setter, respectively. de.diagnose(modifierLoc, diag::expr_selector_add_modifier, false, var) diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index 525c8ec622840..e1ad24ab0f54c 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -1923,7 +1923,6 @@ bool MissingOptionalUnwrapFailure::diagnoseAsError() { "#default value#" "> }"); } - diag.flush(); offerDefaultValueUnwrapFixIt(varDecl->getDeclContext(), initializer); offerForceUnwrapFixIt(initializer); @@ -3150,7 +3149,7 @@ void ContextualFailure::tryFixIts(InFlightDiagnostic &diagnostic) const { if (tryIntegerCastFixIts(diagnostic)) return; - if (tryProtocolConformanceFixIt(diagnostic)) + if (tryProtocolConformanceFixIt()) return; if (tryTypeCoercionFixIt(diagnostic)) @@ -3521,8 +3520,7 @@ bool ContextualFailure::tryTypeCoercionFixIt( return false; } -bool ContextualFailure::tryProtocolConformanceFixIt( - InFlightDiagnostic &diagnostic) const { +bool ContextualFailure::tryProtocolConformanceFixIt() const { auto innermostTyCtx = getDC()->getInnermostTypeContext(); if (!innermostTyCtx) return false; @@ -3556,8 +3554,6 @@ bool ContextualFailure::tryProtocolConformanceFixIt( if (!shouldOfferFixIt) return false; - diagnostic.flush(); - // Let's build a list of protocols that the context does not conform to. SmallVector missingProtoTypeStrings; SmallVector missingProtocols; @@ -4090,7 +4086,6 @@ bool SubscriptMisuseFailure::diagnoseAsError() { } else { diag.fixItReplace(SourceRange(memberExpr->getDotLoc(), memberExpr->getLoc()), "[<#index#>]"); } - diag.flush(); if (auto overload = getOverloadChoiceIfAvailable(locator)) { emitDiagnosticAt(overload->choice.getDecl(), diag::kind_declared_here, @@ -5355,8 +5350,6 @@ bool MissingArgumentsFailure::diagnoseAsError() { diag.fixItInsertAfter(getRawAnchor().getEndLoc(), fixIt.str()); } - diag.flush(); - if (auto selectedOverload = getCalleeOverloadChoiceIfAvailable(locator)) { if (auto *decl = selectedOverload->choice.getDeclOrNull()) { emitDiagnosticAt(decl, diag::decl_declared_here, decl); @@ -5724,8 +5717,6 @@ bool MissingArgumentsFailure::diagnoseInvalidTupleDestructuring() const { diagnostic.fixItRemove(TE->getLParenLoc()).fixItRemove(TE->getRParenLoc()); } - diagnostic.flush(); - // Add a note which points to the overload choice location. emitDiagnosticAt(decl, diag::decl_declared_here, decl); return true; @@ -6126,8 +6117,6 @@ bool ExtraneousArgumentsFailure::diagnoseAsError() { } } - diag.flush(); - // If all of the parameters are anonymous, let's point out references // to make it explicit where parameters are used in complex closure body, // which helps in situations where braces are missing for potential inner @@ -8621,8 +8610,6 @@ void MissingRawRepresentableInitFailure::fixIt( .fixItInsert(range.Start, rawReprObjType->getString() + "(rawValue: ") .fixItInsertAfter(range.End, ")"); } else if (valueObjType) { - diagnostic.flush(); - std::string fixItBefore = RawReprType->getString() + "(rawValue: "; std::string fixItAfter; diff --git a/lib/Sema/CSDiagnostics.h b/lib/Sema/CSDiagnostics.h index 5c65d8a23c067..db63643637066 100644 --- a/lib/Sema/CSDiagnostics.h +++ b/lib/Sema/CSDiagnostics.h @@ -726,7 +726,7 @@ class ContextualFailure : public FailureDiagnostic { /// Try to add a fix-it to conform the decl context (if it's a type) to the /// protocol - bool tryProtocolConformanceFixIt(InFlightDiagnostic &diagnostic) const; + bool tryProtocolConformanceFixIt() const; private: Type resolve(Type rawType) const { diff --git a/lib/Sema/ImportResolution.cpp b/lib/Sema/ImportResolution.cpp index 0b4df8782715f..e14ef37dfb046 100644 --- a/lib/Sema/ImportResolution.cpp +++ b/lib/Sema/ImportResolution.cpp @@ -1159,7 +1159,6 @@ CheckInconsistentAccessLevelOnImport::evaluate( error.fixItInsert(implicitImport->getStartLoc(), diag::inconsistent_implicit_access_level_on_import_fixit, otherAccessLevel); - error.flush(); diags.diagnose(implicitImport, diag::inconsistent_implicit_access_level_on_import_silence); } @@ -1352,7 +1351,6 @@ ScopedImportLookupRequest::evaluate(Evaluator &evaluator, emittedDiag->fixItReplace(SourceRange(import->getKindLoc()), getImportKindString(*actualKind)); - emittedDiag->flush(); if (decls.size() == 1) ctx.Diags.diagnose(decls.front(), diag::decl_declared_here, diff --git a/lib/Sema/TypeCheckAccess.cpp b/lib/Sema/TypeCheckAccess.cpp index df58d18e1b2c3..56c702a1e0a59 100644 --- a/lib/Sema/TypeCheckAccess.cpp +++ b/lib/Sema/TypeCheckAccess.cpp @@ -363,12 +363,10 @@ void AccessControlCheckerBase::checkTypeAccess( static void highlightOffendingType(InFlightDiagnostic &diag, const TypeRepr *complainRepr) { if (!complainRepr) { - diag.flush(); return; } diag.highlight(complainRepr->getSourceRange()); - diag.flush(); if (auto *declRefTR = dyn_cast(complainRepr)) { const ValueDecl *VD = declRefTR->getBoundDecl(); @@ -2480,7 +2478,7 @@ class DeclAvailabilityChecker : public DeclVisitor { ); if (refRange.isValid()) diag.highlight(refRange); - diag.flush(); + PGD->diagnose(diag::name_declared_here, PGD->getName()); } diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index a290483e08c72..bb64bc738022b 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -2036,7 +2036,6 @@ static void diagnoseChangesByAccessNote( if (fixItLoc.isInvalid()) fixItLoc = attr->getRangeWithAt().Start; } - diag.flush(); if (!fixItLoc) fixItLoc = VD->getAttributeInsertionLoc(true); @@ -4028,7 +4027,6 @@ class DeclChecker : public DeclVisitor { nominal->getDeclaredType()); diag.highlight(extTypeRepr->getSourceRange()); if (firstNominalIsNotMostSpecific) { - diag.flush(); Type mostSpecificProtocol = extTypeNominal->getDeclaredType(); ED->diagnose(diag::composition_in_extended_type_alternative, mostSpecificProtocol) diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp index 7b32dc99b585f..52d8705d7b072 100644 --- a/lib/Sema/TypeCheckPattern.cpp +++ b/lib/Sema/TypeCheckPattern.cpp @@ -1010,7 +1010,6 @@ void repairTupleOrAssociatedValuePatternIfApplicable( auto trailingParen = SourceRange(enumElementInnerPat->getEndLoc()); diag.fixItRemove(leadingParen).fixItRemove(trailingParen); } - diag.flush(); addDeclNote(); enumElementInnerPat = semantic; } else { diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index a1350bfd42a99..825de49b1eccb 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -4049,16 +4049,14 @@ static void diagnoseProtocolStubFixit( // Issue diagnostics for witness types. if (auto MissingTypeWitness = dyn_cast(VD)) { - std::optional diag; if (isa(DC->getSelfNominalTypeDecl())) { auto expectedTy = getTupleConformanceTypeWitness(DC, MissingTypeWitness); - diag.emplace(Diags.diagnose(MissingTypeWitness, diag::no_witnesses_type_tuple, - MissingTypeWitness, expectedTy)); + Diags.diagnose(MissingTypeWitness, diag::no_witnesses_type_tuple, + MissingTypeWitness, expectedTy); } else { - diag.emplace(Diags.diagnose(MissingTypeWitness, diag::no_witnesses_type, - MissingTypeWitness)); + Diags.diagnose(MissingTypeWitness, diag::no_witnesses_type, + MissingTypeWitness); } - diag.value().flush(); continue; } @@ -4208,7 +4206,6 @@ void ConformanceChecker::checkNonFinalClassWitness(ValueDecl *requirement, // If the main diagnostic is emitted on the conformance, we want to // attach the fix-it to the note that shows where the initializer is // defined. - fixItDiag.value().flush(); fixItDiag.emplace(diags.diagnose(ctor, diag::decl_declared_here, ctor)); } @@ -4387,7 +4384,6 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) { if (diagLoc == witness->getLoc()) { fixDeclarationName(diag, witness, requirement->getName()); } else { - diag.flush(); diags.diagnose(witness, diag::decl_declared_here, witness); } } @@ -4568,7 +4564,6 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) { if (diagLoc == witness->getLoc()) { addOptionalityFixIts(adjustments, ctx, witness, diag); } else { - diag.flush(); diags.diagnose(witness, diag::decl_declared_here, witness); } } @@ -5661,7 +5656,6 @@ void ConformanceChecker::resolveValueWitnesses() { // If the main diagnostic is emitted on the conformance, we want // to attach the fix-it to the note that shows where the // witness is defined. - fixItDiag.value().flush(); fixItDiag.emplace( witness->diagnose(diag::make_decl_objc, witness)); } @@ -5681,7 +5675,6 @@ void ConformanceChecker::resolveValueWitnesses() { // If the main diagnostic is emitted on the conformance, we want // to attach the fix-it to the note that shows where the // witness is defined. - fixItDiag.value().flush(); fixItDiag.emplace( witness->diagnose(diag::make_decl_objc, witness)); } @@ -5701,7 +5694,6 @@ void ConformanceChecker::resolveValueWitnesses() { // If the main diagnostic is emitted on the conformance, we want // to attach the fix-it to the note that shows where the // witness is defined. - fixItDiag.value().flush(); fixItDiag.emplace( witness->diagnose(diag::make_decl_objc, witness)); } diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index 40663997609e3..5705760de92ef 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -255,9 +255,7 @@ ModularizationError::diagnose(const ModuleFile *MF, llvm_unreachable("Unhandled ModularizationError::Kind in switch."); }; - auto inFlight = diagnoseError(errorKind); - inFlight.limitBehavior(limit); - inFlight.flush(); + diagnoseError(errorKind).limitBehavior(limit); // We could pass along the `path` information through notes. // However, for a top-level decl a path would just duplicate the diff --git a/validation-test/compiler_crashers_2/1a9cf8aaa2cfa83f.swift b/validation-test/compiler_crashers_2_fixed/1a9cf8aaa2cfa83f.swift similarity index 83% rename from validation-test/compiler_crashers_2/1a9cf8aaa2cfa83f.swift rename to validation-test/compiler_crashers_2_fixed/1a9cf8aaa2cfa83f.swift index 92a703da54eb3..b08add06cc2fb 100644 --- a/validation-test/compiler_crashers_2/1a9cf8aaa2cfa83f.swift +++ b/validation-test/compiler_crashers_2_fixed/1a9cf8aaa2cfa83f.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","signature":"diagnoseInvalidObjCName(swift::ValueDecl*, swift::ObjCAttr*)","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s // REQUIRES: objc_interop @objcMembers class a open extension a { func 0.0 diff --git a/validation-test/compiler_crashers_2/56edea24a97933f.swift b/validation-test/compiler_crashers_2_fixed/56edea24a97933f.swift similarity index 84% rename from validation-test/compiler_crashers_2/56edea24a97933f.swift rename to validation-test/compiler_crashers_2_fixed/56edea24a97933f.swift index f6762eba2d498..f64af92306ad6 100644 --- a/validation-test/compiler_crashers_2/56edea24a97933f.swift +++ b/validation-test/compiler_crashers_2_fixed/56edea24a97933f.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","signature":"swift::isRepresentableInObjC(swift::VarDecl const*, swift::ObjCReason)","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s // REQUIRES: objc_interop class a class b open extension b { @objc c : a diff --git a/validation-test/compiler_crashers_2/5cc8bc3069f97958.swift b/validation-test/compiler_crashers_2_fixed/5cc8bc3069f97958.swift similarity index 86% rename from validation-test/compiler_crashers_2/5cc8bc3069f97958.swift rename to validation-test/compiler_crashers_2_fixed/5cc8bc3069f97958.swift index e80667ec63bb3..996cb30444deb 100644 --- a/validation-test/compiler_crashers_2/5cc8bc3069f97958.swift +++ b/validation-test/compiler_crashers_2_fixed/5cc8bc3069f97958.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","signature":"(anonymous namespace)::TypeResolver::resolveImplicitlyUnwrappedOptionalType(swift::ImplicitlyUnwrappedOptionalTypeRepr*, swift::TypeResolutionOptions, bool)","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s { enum a: b! { } diff --git a/validation-test/compiler_crashers_2/64915463735bcf5b.swift b/validation-test/compiler_crashers_2_fixed/64915463735bcf5b.swift similarity index 86% rename from validation-test/compiler_crashers_2/64915463735bcf5b.swift rename to validation-test/compiler_crashers_2_fixed/64915463735bcf5b.swift index ea0f8f0111370..67ffb2847a5c7 100644 --- a/validation-test/compiler_crashers_2/64915463735bcf5b.swift +++ b/validation-test/compiler_crashers_2_fixed/64915463735bcf5b.swift @@ -1,4 +1,4 @@ // {"kind":"typecheck","signature":"swift::Evaluator::diagnoseCycle(swift::ActiveRequest const&)","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s // REQUIRES: OS=macosx import Distributed typealias DefaultDistributedActorSystem = LocalTestingDistributedActorSystem distributed actor a{distributed... diff --git a/validation-test/compiler_crashers_2/66e337320b1924c.swift b/validation-test/compiler_crashers_2_fixed/66e337320b1924c.swift similarity index 82% rename from validation-test/compiler_crashers_2/66e337320b1924c.swift rename to validation-test/compiler_crashers_2_fixed/66e337320b1924c.swift index 6d712726de2f7..8e41eee816eda 100644 --- a/validation-test/compiler_crashers_2/66e337320b1924c.swift +++ b/validation-test/compiler_crashers_2_fixed/66e337320b1924c.swift @@ -1,3 +1,3 @@ // {"kind":"typecheck","signature":"swift::ProtocolRequiresClassRequest::diagnoseCycle(swift::DiagnosticEngine&) const","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s struct b let b c a = b protocol a : a diff --git a/validation-test/compiler_crashers_2/72eed0e8ff21c1a.swift b/validation-test/compiler_crashers_2_fixed/72eed0e8ff21c1a.swift similarity index 85% rename from validation-test/compiler_crashers_2/72eed0e8ff21c1a.swift rename to validation-test/compiler_crashers_2_fixed/72eed0e8ff21c1a.swift index f4581a132109e..d5639d345e040 100644 --- a/validation-test/compiler_crashers_2/72eed0e8ff21c1a.swift +++ b/validation-test/compiler_crashers_2_fixed/72eed0e8ff21c1a.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","signature":"isParamListRepresentableInLanguage(swift::AbstractFunctionDecl const*, swift::ParameterList const*, swift::ObjCReason)","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s // REQUIRES: objc_interop class a open extension a { @objc b(_) diff --git a/validation-test/compiler_crashers_2/7aa9d3699dddb337.swift b/validation-test/compiler_crashers_2_fixed/7aa9d3699dddb337.swift similarity index 84% rename from validation-test/compiler_crashers_2/7aa9d3699dddb337.swift rename to validation-test/compiler_crashers_2_fixed/7aa9d3699dddb337.swift index 7d32e52511c7b..ef7871d8ee0f6 100644 --- a/validation-test/compiler_crashers_2/7aa9d3699dddb337.swift +++ b/validation-test/compiler_crashers_2_fixed/7aa9d3699dddb337.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","signature":"swift::PatternTypeRequest::evaluate(swift::Evaluator&, swift::ContextualPattern) const","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s // REQUIRES: objc_interop @objcMembers class a open extension a { var b diff --git a/validation-test/compiler_crashers_2/82fe033c6bdba61.swift b/validation-test/compiler_crashers_2_fixed/82fe033c6bdba61.swift similarity index 82% rename from validation-test/compiler_crashers_2/82fe033c6bdba61.swift rename to validation-test/compiler_crashers_2_fixed/82fe033c6bdba61.swift index 68e2502839039..ea43bff0c0236 100644 --- a/validation-test/compiler_crashers_2/82fe033c6bdba61.swift +++ b/validation-test/compiler_crashers_2_fixed/82fe033c6bdba61.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","signature":"swift::DerivedConformance::deriveDecodable(swift::ValueDecl*)","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s struct a { var b, c : Codable { diff --git a/validation-test/compiler_crashers_2/a81ff5cc2d29ef15.swift b/validation-test/compiler_crashers_2_fixed/a81ff5cc2d29ef15.swift similarity index 84% rename from validation-test/compiler_crashers_2/a81ff5cc2d29ef15.swift rename to validation-test/compiler_crashers_2_fixed/a81ff5cc2d29ef15.swift index ee5783b1a903d..8f9d57cb13841 100644 --- a/validation-test/compiler_crashers_2/a81ff5cc2d29ef15.swift +++ b/validation-test/compiler_crashers_2_fixed/a81ff5cc2d29ef15.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","signature":"swift::IsStaticRequest::evaluate(swift::Evaluator&, swift::FuncDecl*) const","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s // REQUIRES: objc_interop @objcMembers class a open extension a { ... diff --git a/validation-test/compiler_crashers_2/ad9313b914fb2.swift b/validation-test/compiler_crashers_2_fixed/ad9313b914fb2.swift similarity index 81% rename from validation-test/compiler_crashers_2/ad9313b914fb2.swift rename to validation-test/compiler_crashers_2_fixed/ad9313b914fb2.swift index 8d25aa55a222f..6c56558edbc85 100644 --- a/validation-test/compiler_crashers_2/ad9313b914fb2.swift +++ b/validation-test/compiler_crashers_2_fixed/ad9313b914fb2.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","signature":"swift::Evaluator::diagnoseCycle(swift::ActiveRequest const&)","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s class a let _ b = a class b : b.c diff --git a/validation-test/compiler_crashers_2/bafa48a4eecbfb62.swift b/validation-test/compiler_crashers_2_fixed/bafa48a4eecbfb62.swift similarity index 87% rename from validation-test/compiler_crashers_2/bafa48a4eecbfb62.swift rename to validation-test/compiler_crashers_2_fixed/bafa48a4eecbfb62.swift index 506b7134048c2..38aef2d70c875 100644 --- a/validation-test/compiler_crashers_2/bafa48a4eecbfb62.swift +++ b/validation-test/compiler_crashers_2_fixed/bafa48a4eecbfb62.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","signature":"diagnoseUnknownType(swift::TypeResolution const&, swift::Type, swift::SourceRange, swift::DeclRefTypeRepr*, swift::optionset::OptionSet)","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s // REQUIRES: objc_interop class b open extension b { @objc c : a diff --git a/validation-test/compiler_crashers_2/bf67776f769fa0f1.swift b/validation-test/compiler_crashers_2_fixed/bf67776f769fa0f1.swift similarity index 84% rename from validation-test/compiler_crashers_2/bf67776f769fa0f1.swift rename to validation-test/compiler_crashers_2_fixed/bf67776f769fa0f1.swift index 0bc770bef97af..ad88a55f6ba3d 100644 --- a/validation-test/compiler_crashers_2/bf67776f769fa0f1.swift +++ b/validation-test/compiler_crashers_2_fixed/bf67776f769fa0f1.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","signature":"(anonymous namespace)::TypeResolver::resolveType(swift::TypeRepr*, swift::TypeResolutionOptions)","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s // REQUIRES: objc_interop class a open extension a { @objc b : _ diff --git a/validation-test/compiler_crashers_2/db15a23c5f8aeff.swift b/validation-test/compiler_crashers_2_fixed/db15a23c5f8aeff.swift similarity index 83% rename from validation-test/compiler_crashers_2/db15a23c5f8aeff.swift rename to validation-test/compiler_crashers_2_fixed/db15a23c5f8aeff.swift index 91e705fd10182..6d49f28bbc024 100644 --- a/validation-test/compiler_crashers_2/db15a23c5f8aeff.swift +++ b/validation-test/compiler_crashers_2_fixed/db15a23c5f8aeff.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","original":"36a5bbda","signature":"swift::SuperclassDeclRequest::diagnoseCycle(swift::DiagnosticEngine&) const","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s { class a: a { } diff --git a/validation-test/compiler_crashers_2/f8296a9a293c6ae7.swift b/validation-test/compiler_crashers_2_fixed/f8296a9a293c6ae7.swift similarity index 85% rename from validation-test/compiler_crashers_2/f8296a9a293c6ae7.swift rename to validation-test/compiler_crashers_2_fixed/f8296a9a293c6ae7.swift index ac8da3cce6fc9..2d875f2714084 100644 --- a/validation-test/compiler_crashers_2/f8296a9a293c6ae7.swift +++ b/validation-test/compiler_crashers_2_fixed/f8296a9a293c6ae7.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","signature":"(anonymous namespace)::TypeResolver::resolveCompositionType(swift::CompositionTypeRepr*, swift::TypeResolutionOptions)","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s // REQUIRES: objc_interop class a open extension a { @objc b : Int & diff --git a/validation-test/compiler_crashers_2/fca26dd570bcdf1c.swift b/validation-test/compiler_crashers_2_fixed/fca26dd570bcdf1c.swift similarity index 85% rename from validation-test/compiler_crashers_2/fca26dd570bcdf1c.swift rename to validation-test/compiler_crashers_2_fixed/fca26dd570bcdf1c.swift index 395d470a2d3b0..ac6ae7e300572 100644 --- a/validation-test/compiler_crashers_2/fca26dd570bcdf1c.swift +++ b/validation-test/compiler_crashers_2_fixed/fca26dd570bcdf1c.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","signature":"(anonymous namespace)::TypeResolver::resolveVarargType(swift::VarargTypeRepr*, swift::TypeResolutionOptions)","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s // REQUIRES: objc_interop class a open extension a { @objc b : Int... diff --git a/validation-test/compiler_crashers_2/ff105cea796d442f.swift b/validation-test/compiler_crashers_2_fixed/ff105cea796d442f.swift similarity index 86% rename from validation-test/compiler_crashers_2/ff105cea796d442f.swift rename to validation-test/compiler_crashers_2_fixed/ff105cea796d442f.swift index 7792cf2aea778..c47fa2fdd7fe8 100644 --- a/validation-test/compiler_crashers_2/ff105cea796d442f.swift +++ b/validation-test/compiler_crashers_2_fixed/ff105cea796d442f.swift @@ -1,5 +1,5 @@ // {"kind":"typecheck","signature":"swift::InFlightDiagnostic swift::diagnoseAttrWithRemovalFixIt&>(swift::Decl const*, swift::DeclAttribute const*, swift::Diag<>&)","signatureAssert":"Assertion failed: (!ActiveDiagnostic && \"Already have an active diagnostic\"), function diagnose"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s // REQUIRES: objc_interop class a open extension a { @objc class b