@@ -194,6 +194,8 @@ class ExpressionTimer {
194194
195195 AnchorType getAnchor () const { return Anchor; }
196196
197+ SourceRange getAffectedRange () const ;
198+
197199 unsigned getWarnLimit () const {
198200 return Context.TypeCheckerOpts .WarnLongExpressionTypeChecking ;
199201 }
@@ -5415,9 +5417,17 @@ class ConstraintSystem {
54155417
54165418 // / Determine if we've already explored too many paths in an
54175419 // / attempt to solve this expression.
5418- bool isExpressionAlreadyTooComplex = false ;
5419- bool getExpressionTooComplex (size_t solutionMemory) {
5420- if (isExpressionAlreadyTooComplex)
5420+ std::pair<bool , SourceRange> isAlreadyTooComplex = {false , SourceRange ()};
5421+
5422+ // / If optional is not nil, result is guaranteed to point at a valid
5423+ // / location.
5424+ Optional<SourceRange> getTooComplexRange () const {
5425+ auto range = isAlreadyTooComplex.second ;
5426+ return range.isValid () ? range : Optional<SourceRange>();
5427+ }
5428+
5429+ bool isTooComplex (size_t solutionMemory) {
5430+ if (isAlreadyTooComplex.first )
54215431 return true ;
54225432
54235433 auto CancellationFlag = getASTContext ().CancellationFlag ;
@@ -5428,7 +5438,9 @@ class ConstraintSystem {
54285438 MaxMemory = std::max (used, MaxMemory);
54295439 auto threshold = getASTContext ().TypeCheckerOpts .SolverMemoryThreshold ;
54305440 if (MaxMemory > threshold) {
5431- return isExpressionAlreadyTooComplex= true ;
5441+ // No particular location for OoM problems.
5442+ isAlreadyTooComplex.first = true ;
5443+ return true ;
54325444 }
54335445
54345446 if (Timer && Timer->isExpired ()) {
@@ -5437,24 +5449,29 @@ class ConstraintSystem {
54375449 // emitting an error.
54385450 Timer->disableWarning ();
54395451
5440- return isExpressionAlreadyTooComplex = true ;
5452+ isAlreadyTooComplex = {true , Timer->getAffectedRange ()};
5453+ return true ;
54415454 }
54425455
54435456 // Bail out once we've looked at a really large number of
54445457 // choices.
54455458 if (CountScopes > getASTContext ().TypeCheckerOpts .SolverBindingThreshold ) {
5446- return isExpressionAlreadyTooComplex = true ;
5459+ isAlreadyTooComplex.first = true ;
5460+ return true ;
54475461 }
54485462
54495463 return false ;
54505464 }
54515465
5452- bool getExpressionTooComplex (SmallVectorImpl<Solution> const &solutions) {
5466+ bool isTooComplex (SmallVectorImpl<Solution> const &solutions) {
5467+ if (isAlreadyTooComplex.first )
5468+ return true ;
5469+
54535470 size_t solutionMemory = 0 ;
54545471 for (auto const & s : solutions) {
54555472 solutionMemory += s.getTotalMemory ();
54565473 }
5457- return getExpressionTooComplex (solutionMemory);
5474+ return isTooComplex (solutionMemory);
54585475 }
54595476
54605477 // If the given constraint is an applied disjunction, get the argument function
0 commit comments