@@ -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;
@@ -5384,6 +5373,9 @@ class ConstraintSystem {
53845373 // / \returns The selected conjunction.
53855374 Constraint *selectConjunction ();
53865375
5376+ void diagnoseTooComplex (SourceLoc fallbackLoc,
5377+ SolutionResult &result);
5378+
53875379 // / Solve the system of constraints generated from provided expression.
53885380 // /
53895381 // / \param target The target to generate constraints from.
@@ -5481,6 +5473,8 @@ class ConstraintSystem {
54815473 compareSolutions (ConstraintSystem &cs, ArrayRef<Solution> solutions,
54825474 const SolutionDiff &diff, unsigned idx1, unsigned idx2);
54835475
5476+ void startExpressionTimer ();
5477+
54845478public:
54855479 // / Increase the score of the given kind for the current (partial) solution
54865480 // / along the current solver path.
@@ -5518,7 +5512,6 @@ class ConstraintSystem {
55185512 std::optional<unsigned > findBestSolution (SmallVectorImpl<Solution> &solutions,
55195513 bool minimize);
55205514
5521- public:
55225515 // / Apply a given solution to the target, producing a fully
55235516 // / type-checked target or \c None if an error occurred.
55245517 // /
@@ -5571,7 +5564,14 @@ class ConstraintSystem {
55715564 // / resolved before any others.
55725565 void optimizeConstraints (Expr *e);
55735566
5574- void startExpressionTimer (ExpressionTimer::AnchorType anchor);
5567+ // / Set the current sub-expression (of a multi-statement closure, etc) for
5568+ // / the purposes of diagnosing "reasonable time" errors.
5569+ void startExpression (ASTNode node);
5570+
5571+ // / The source range of the target being type checked.
5572+ SourceRange getCurrentSourceRange () const {
5573+ return CurrentRange;
5574+ }
55755575
55765576 // / Determine if we've already explored too many paths in an
55775577 // / attempt to solve this expression.
@@ -5584,53 +5584,7 @@ class ConstraintSystem {
55845584 return range.isValid () ? range : std::optional<SourceRange>();
55855585 }
55865586
5587- bool isTooComplex (size_t solutionMemory) {
5588- if (isAlreadyTooComplex.first )
5589- return true ;
5590-
5591- auto CancellationFlag = getASTContext ().CancellationFlag ;
5592- if (CancellationFlag && CancellationFlag->load (std::memory_order_relaxed))
5593- return true ;
5594-
5595- auto markTooComplex = [&](SourceRange range, StringRef reason) {
5596- if (isDebugMode ()) {
5597- if (solverState)
5598- llvm::errs ().indent (solverState->getCurrentIndent ());
5599- llvm::errs () << " (too complex: " << reason << " )\n " ;
5600- }
5601- isAlreadyTooComplex = {true , range};
5602- return true ;
5603- };
5604-
5605- auto used = getASTContext ().getSolverMemory () + solutionMemory;
5606- MaxMemory = std::max (used, MaxMemory);
5607- auto threshold = getASTContext ().TypeCheckerOpts .SolverMemoryThreshold ;
5608- if (MaxMemory > threshold) {
5609- // No particular location for OoM problems.
5610- return markTooComplex (SourceRange (), " exceeded memory limit" );
5611- }
5612-
5613- if (Timer && Timer->isExpired ()) {
5614- // Disable warnings about expressions that go over the warning
5615- // threshold since we're arbitrarily ending evaluation and
5616- // emitting an error.
5617- Timer->disableWarning ();
5618-
5619- return markTooComplex (Timer->getAffectedRange (), " exceeded time limit" );
5620- }
5621-
5622- auto &opts = getASTContext ().TypeCheckerOpts ;
5623-
5624- // Bail out once we've looked at a really large number of choices.
5625- if (opts.SolverScopeThreshold && NumSolverScopes > opts.SolverScopeThreshold )
5626- return markTooComplex (SourceRange (), " exceeded scope limit" );
5627-
5628- // Bail out once we've taken a really large number of steps.
5629- if (opts.SolverTrailThreshold && NumTrailSteps > opts.SolverTrailThreshold )
5630- return markTooComplex (SourceRange (), " exceeded trail limit" );
5631-
5632- return false ;
5633- }
5587+ bool isTooComplex (size_t solutionMemory);
56345588
56355589 bool isTooComplex (ArrayRef<Solution> solutions) {
56365590 if (isAlreadyTooComplex.first )
0 commit comments