@@ -236,36 +236,23 @@ struct RestrictionOrFix {
236236
237237
238238class ExpressionTimer {
239- public:
240- using AnchorType = llvm::PointerUnion<Expr *, ConstraintLocator *>;
241-
242- private:
243- AnchorType Anchor;
244- ASTContext &Context;
239+ ConstraintSystem &CS;
245240 llvm::TimeRecord StartTime;
246241
247242 // / The number of seconds from creation until
248243 // / this timer is considered expired.
249244 unsigned ThresholdInSecs;
250245
251- bool PrintDebugTiming;
252246 bool PrintWarning;
253247
254248public:
255249 const static unsigned NoLimit = (unsigned ) -1 ;
256250
257- ExpressionTimer (AnchorType Anchor, ConstraintSystem &CS,
258- unsigned thresholdInSecs);
251+ ExpressionTimer (ConstraintSystem &CS, unsigned thresholdInSecs);
259252
260253 ~ExpressionTimer ();
261254
262- AnchorType getAnchor () const { return Anchor; }
263-
264- SourceRange getAffectedRange () const ;
265-
266- unsigned getWarnLimit () const {
267- return Context.TypeCheckerOpts .WarnLongExpressionTypeChecking ;
268- }
255+ unsigned getWarnLimit () const ;
269256 llvm::TimeRecord startedAt () const { return StartTime; }
270257
271258 // / Return the elapsed process time (including fractional seconds)
@@ -2159,7 +2146,9 @@ struct ClosureIsolatedByPreconcurrency {
21592146// / solution of which assigns concrete types to each of the type variables.
21602147// / Constraint systems are typically generated given an (untyped) expression.
21612148class ConstraintSystem {
2149+ private:
21622150 ASTContext &Context;
2151+ SourceRange CurrentRange;
21632152
21642153public:
21652154 DeclContext *DC;
@@ -5390,6 +5379,9 @@ class ConstraintSystem {
53905379 // / \returns The selected conjunction.
53915380 Constraint *selectConjunction ();
53925381
5382+ void diagnoseTooComplex (SourceLoc fallbackLoc,
5383+ SolutionResult &result);
5384+
53935385 // / Solve the system of constraints generated from provided expression.
53945386 // /
53955387 // / \param target The target to generate constraints from.
@@ -5487,6 +5479,8 @@ class ConstraintSystem {
54875479 compareSolutions (ConstraintSystem &cs, ArrayRef<Solution> solutions,
54885480 const SolutionDiff &diff, unsigned idx1, unsigned idx2);
54895481
5482+ void startExpressionTimer ();
5483+
54905484public:
54915485 // / Increase the score of the given kind for the current (partial) solution
54925486 // / along the current solver path.
@@ -5524,7 +5518,6 @@ class ConstraintSystem {
55245518 std::optional<unsigned > findBestSolution (SmallVectorImpl<Solution> &solutions,
55255519 bool minimize);
55265520
5527- public:
55285521 // / Apply a given solution to the target, producing a fully
55295522 // / type-checked target or \c None if an error occurred.
55305523 // /
@@ -5577,7 +5570,14 @@ class ConstraintSystem {
55775570 // / resolved before any others.
55785571 void optimizeConstraints (Expr *e);
55795572
5580- void startExpressionTimer (ExpressionTimer::AnchorType anchor);
5573+ // / Set the current sub-expression (of a multi-statement closure, etc) for
5574+ // / the purposes of diagnosing "reasonable time" errors.
5575+ void startExpression (ASTNode node);
5576+
5577+ // / The source range of the target being type checked.
5578+ SourceRange getCurrentSourceRange () const {
5579+ return CurrentRange;
5580+ }
55815581
55825582 // / Determine if we've already explored too many paths in an
55835583 // / attempt to solve this expression.
@@ -5590,53 +5590,7 @@ class ConstraintSystem {
55905590 return range.isValid () ? range : std::optional<SourceRange>();
55915591 }
55925592
5593- bool isTooComplex (size_t solutionMemory) {
5594- if (isAlreadyTooComplex.first )
5595- return true ;
5596-
5597- auto CancellationFlag = getASTContext ().CancellationFlag ;
5598- if (CancellationFlag && CancellationFlag->load (std::memory_order_relaxed))
5599- return true ;
5600-
5601- auto markTooComplex = [&](SourceRange range, StringRef reason) {
5602- if (isDebugMode ()) {
5603- if (solverState)
5604- llvm::errs ().indent (solverState->getCurrentIndent ());
5605- llvm::errs () << " (too complex: " << reason << " )\n " ;
5606- }
5607- isAlreadyTooComplex = {true , range};
5608- return true ;
5609- };
5610-
5611- auto used = getASTContext ().getSolverMemory () + solutionMemory;
5612- MaxMemory = std::max (used, MaxMemory);
5613- auto threshold = getASTContext ().TypeCheckerOpts .SolverMemoryThreshold ;
5614- if (MaxMemory > threshold) {
5615- // No particular location for OoM problems.
5616- return markTooComplex (SourceRange (), " exceeded memory limit" );
5617- }
5618-
5619- if (Timer && Timer->isExpired ()) {
5620- // Disable warnings about expressions that go over the warning
5621- // threshold since we're arbitrarily ending evaluation and
5622- // emitting an error.
5623- Timer->disableWarning ();
5624-
5625- return markTooComplex (Timer->getAffectedRange (), " exceeded time limit" );
5626- }
5627-
5628- auto &opts = getASTContext ().TypeCheckerOpts ;
5629-
5630- // Bail out once we've looked at a really large number of choices.
5631- if (opts.SolverScopeThreshold && NumSolverScopes > opts.SolverScopeThreshold )
5632- return markTooComplex (SourceRange (), " exceeded scope limit" );
5633-
5634- // Bail out once we've taken a really large number of steps.
5635- if (opts.SolverTrailThreshold && NumTrailSteps > opts.SolverTrailThreshold )
5636- return markTooComplex (SourceRange (), " exceeded trail limit" );
5637-
5638- return false ;
5639- }
5593+ bool isTooComplex (size_t solutionMemory);
56405594
56415595 bool isTooComplex (ArrayRef<Solution> solutions) {
56425596 if (isAlreadyTooComplex.first )
0 commit comments