@@ -238,6 +238,8 @@ class ExpressionTimer {
238238
239239 AnchorType getAnchor () const { return Anchor; }
240240
241+ SourceRange getAffectedRange () const ;
242+
241243 unsigned getWarnLimit () const {
242244 return Context.TypeCheckerOpts .WarnLongExpressionTypeChecking ;
243245 }
@@ -5459,9 +5461,17 @@ class ConstraintSystem {
54595461
54605462 // / Determine if we've already explored too many paths in an
54615463 // / attempt to solve this expression.
5462- bool isExpressionAlreadyTooComplex = false ;
5463- bool getExpressionTooComplex (size_t solutionMemory) {
5464- if (isExpressionAlreadyTooComplex)
5464+ std::pair<bool , SourceRange> isAlreadyTooComplex = {false , SourceRange ()};
5465+
5466+ // / If optional is not nil, result is guaranteed to point at a valid
5467+ // / location.
5468+ Optional<SourceRange> getTooComplexRange () const {
5469+ auto range = isAlreadyTooComplex.second ;
5470+ return range.isValid () ? range : Optional<SourceRange>();
5471+ }
5472+
5473+ bool isTooComplex (size_t solutionMemory) {
5474+ if (isAlreadyTooComplex.first )
54655475 return true ;
54665476
54675477 auto CancellationFlag = getASTContext ().CancellationFlag ;
@@ -5472,7 +5482,9 @@ class ConstraintSystem {
54725482 MaxMemory = std::max (used, MaxMemory);
54735483 auto threshold = getASTContext ().TypeCheckerOpts .SolverMemoryThreshold ;
54745484 if (MaxMemory > threshold) {
5475- return isExpressionAlreadyTooComplex= true ;
5485+ // No particular location for OoM problems.
5486+ isAlreadyTooComplex.first = true ;
5487+ return true ;
54765488 }
54775489
54785490 if (Timer && Timer->isExpired ()) {
@@ -5481,27 +5493,29 @@ class ConstraintSystem {
54815493 // emitting an error.
54825494 Timer->disableWarning ();
54835495
5484- return isExpressionAlreadyTooComplex = true ;
5496+ isAlreadyTooComplex = {true , Timer->getAffectedRange ()};
5497+ return true ;
54855498 }
54865499
54875500 // Bail out once we've looked at a really large number of
54885501 // choices.
54895502 if (CountScopes > getASTContext ().TypeCheckerOpts .SolverBindingThreshold ) {
5490- return isExpressionAlreadyTooComplex = true ;
5503+ isAlreadyTooComplex.first = true ;
5504+ return true ;
54915505 }
54925506
54935507 return false ;
54945508 }
54955509
5496- bool getExpressionTooComplex (SmallVectorImpl<Solution> const &solutions) {
5497- if (isExpressionAlreadyTooComplex )
5510+ bool isTooComplex (SmallVectorImpl<Solution> const &solutions) {
5511+ if (isAlreadyTooComplex. first )
54985512 return true ;
54995513
55005514 size_t solutionMemory = 0 ;
55015515 for (auto const & s : solutions) {
55025516 solutionMemory += s.getTotalMemory ();
55035517 }
5504- return getExpressionTooComplex (solutionMemory);
5518+ return isTooComplex (solutionMemory);
55055519 }
55065520
55075521 // If the given constraint is an applied disjunction, get the argument function
0 commit comments