Skip to content

Commit 5bf0cf6

Browse files
authored
Merge pull request #26199 from xedin/fix-component-finalization
[CSStep] Properly finalize component step without follow-up steps
2 parents 6d73ed3 + 731ec39 commit 5bf0cf6

File tree

4 files changed

+31
-20
lines changed

4 files changed

+31
-20
lines changed

lib/Sema/CSStep.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ StepResult ComponentStep::take(bool prevFailed) {
277277
// allowed in the solution.
278278
if (!CS.solverState->allowsFreeTypeVariables() && CS.hasFreeTypeVariables()) {
279279
if (!CS.shouldAttemptFixes())
280-
return done(/*isSuccess=*/false);
280+
return finalize(/*isSuccess=*/false);
281281

282282
// Let's see if all of the free type variables are associated with
283283
// generic parameters and if so, let's default them to `Any` and continue
@@ -298,7 +298,7 @@ StepResult ComponentStep::take(bool prevFailed) {
298298

299299
auto *anchor = locator->getAnchor();
300300
if (!(anchor && locator->isForGenericParameter()))
301-
return done(/*isSuccess=*/false);
301+
return finalize(/*isSuccess=*/false);
302302

303303
// Increment the score for every missing generic argument
304304
// to make ranking of the solutions with different number
@@ -324,14 +324,14 @@ StepResult ComponentStep::take(bool prevFailed) {
324324
auto *fix =
325325
ExplicitlySpecifyGenericArguments::create(CS, missingParams, locator);
326326
if (CS.recordFix(fix))
327-
return done(/*isSuccess=*/false);
327+
return finalize(/*isSuccess=*/false);
328328
}
329329
}
330330

331331
// If this solution is worse than the best solution we've seen so far,
332332
// skip it.
333333
if (CS.worseThanBestSolution())
334-
return done(/*isSuccess=*/false);
334+
return finalize(/*isSuccess=*/false);
335335

336336
// If we only have relational or member constraints and are allowing
337337
// free type variables, save the solution.
@@ -341,7 +341,7 @@ StepResult ComponentStep::take(bool prevFailed) {
341341
case ConstraintClassification::Member:
342342
continue;
343343
default:
344-
return done(/*isSuccess=*/false);
344+
return finalize(/*isSuccess=*/false);
345345
}
346346
}
347347

@@ -350,31 +350,31 @@ StepResult ComponentStep::take(bool prevFailed) {
350350
getDebugLogger() << "(found solution " << getCurrentScore() << ")\n";
351351

352352
Solutions.push_back(std::move(solution));
353-
return done(/*isSuccess=*/true);
353+
return finalize(/*isSuccess=*/true);
354354
}
355355

356-
StepResult ComponentStep::resume(bool prevFailed) {
356+
StepResult ComponentStep::finalize(bool isSuccess) {
357+
// If this was a single component, there is nothing to be done,
358+
// because it represents the whole constraint system at some
359+
// point of the solver path.
360+
if (IsSingle)
361+
return done(isSuccess);
362+
357363
// Rewind all modifications done to constraint system.
358364
ComponentScope.reset();
359365

360-
if (!IsSingle && isDebugMode()) {
366+
if (isDebugMode()) {
361367
auto &log = getDebugLogger();
362-
log << (prevFailed ? "failed" : "finished") << " component #" << Index
368+
log << (isSuccess ? "finished" : "failed") << " component #" << Index
363369
<< ")\n";
364370
}
365371

366372
// If we came either back to this step and previous
367373
// (either disjunction or type var) failed, it means
368374
// that component as a whole has failed.
369-
if (prevFailed)
375+
if (!isSuccess)
370376
return done(/*isSuccess=*/false);
371377

372-
// If this was a single component, there is nothing to be done,
373-
// because it represents the whole constraint system at some
374-
// point of the solver path.
375-
if (IsSingle)
376-
return done(/*isSuccess=*/true);
377-
378378
assert(!Solutions.empty() && "No Solutions?");
379379

380380
// For each of the partial solutions, subtract off the current score.

lib/Sema/CSStep.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,8 @@ class ComponentStep final : public SolverStep {
374374
}
375375

376376
StepResult take(bool prevFailed) override;
377-
StepResult resume(bool prevFailed) override;
377+
378+
StepResult resume(bool prevFailed) override { return finalize(!prevFailed); }
378379

379380
// The number of disjunction constraints associated with this component.
380381
unsigned disjunctionCount() const { return NumDisjunctions; }
@@ -398,6 +399,10 @@ class ComponentStep final : public SolverStep {
398399
// let's return it to the graph.
399400
CS.CG.setOrphanedConstraint(OrphanedConstraint);
400401
}
402+
403+
/// Finalize current component by either cleanup if sub-tasks
404+
/// have failed, or solution generation and minimization.
405+
StepResult finalize(bool isSuccess);
401406
};
402407

403408
template <typename P> class BindingStep : public SolverStep {

test/Constraints/generics.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ func test9215114<T: P19215114, U: Q19215114>(_ t: T) -> (U) -> () {
224224
}
225225

226226
// <rdar://problem/21718970> QoI: [uninferred generic param] cannot invoke 'foo' with an argument list of type '(Int)'
227-
class Whatever<A: Numeric, B: Numeric> { // expected-note 2 {{'A' declared as parameter to type 'Whatever'}}
227+
class Whatever<A: Numeric, B: Numeric> { // expected-note 2 {{'A' declared as parameter to type 'Whatever'}} expected-note {{'B' declared as parameter to type 'Whatever'}}
228228
static func foo(a: B) {}
229229

230230
static func bar() {}
@@ -233,7 +233,9 @@ class Whatever<A: Numeric, B: Numeric> { // expected-note 2 {{'A' declared as p
233233
Whatever.foo(a: 23) // expected-error {{generic parameter 'A' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{9-9=<<#A: Numeric#>, Int>}}
234234

235235
// <rdar://problem/21718955> Swift useless error: cannot invoke 'foo' with no arguments
236-
Whatever.bar() // expected-error {{generic parameter 'A' could not be inferred}} expected-note {{explicitly specify the generic arguments to fix this issue}} {{9-9=<<#A: Numeric#>, <#B: Numeric#>>}}
236+
// TODO(diagnostics): We should try to produce a single note in this case.
237+
Whatever.bar() // expected-error {{generic parameter 'A' could not be inferred}} expected-note 2 {{explicitly specify the generic arguments to fix this issue}} {{9-9=<<#A: Numeric#>, <#B: Numeric#>>}}
238+
// expected-error@-1 {{generic parameter 'B' could not be inferred}}
237239

238240
// <rdar://problem/27515965> Type checker doesn't enforce same-type constraint if associated type is Any
239241
protocol P27515965 {

test/decl/typealias/generic.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ typealias C<T> = MyType<String, T>
6565
typealias D<T1, T2, T3> = MyType<T2, T1> // expected-note 3 {{'T3' declared as parameter to type 'D'}}
6666

6767
typealias E<T1, T2> = Int // expected-note {{generic type 'E' declared here}}
68+
// expected-note@-1 {{'T1' declared as parameter to type 'E'}}
69+
// expected-note@-2 {{'T2' declared as parameter to type 'E'}}
6870

6971
typealias F<T1, T2> = (T1) -> T2
7072

@@ -73,7 +75,9 @@ typealias G<S1, S2> = A<S1, S2>
7375

7476
let _ : E<Int, Float> = 42
7577
let _ : E<Float> = 42 // expected-error {{generic type 'E' specialized with too few type parameters (got 1, but expected 2)}}
76-
let _ : E = 42 // expected-error {{cannot convert value of type 'Int' to specified type 'E'}}
78+
let _ : E = 42
79+
// expected-error@-1 {{generic parameter 'T1' could not be inferred}}
80+
// expected-error@-2 {{generic parameter 'T2' could not be inferred}}
7781
let _ : D = D(a: 1, b: 2)
7882
// expected-error@-1 {{generic parameter 'T3' could not be inferred}}
7983
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{14-14=<Int, Int, Any>}}

0 commit comments

Comments
 (0)