Skip to content

Commit b616220

Browse files
committed
Most tests pass
1 parent 65e1fc6 commit b616220

File tree

3 files changed

+58
-4
lines changed

3 files changed

+58
-4
lines changed

src/Draco.Compiler/Internal/Solver/ConstraintSolver.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public Argument Arg(SyntaxNode? syntax, BindingTask<BoundLvalue> lvalue, Diagnos
6868
/// <param name="diagnostics">The bag to report diagnostics to.</param>
6969
public void Solve(DiagnosticBag diagnostics)
7070
{
71-
while (this.ApplyRulesOnce(diagnostics)) { }
71+
this.SolveUntilFixpoint(diagnostics);
7272

7373
// Check for uninferred locals
7474
this.CheckForUninferredLocals(diagnostics);
@@ -77,6 +77,11 @@ public void Solve(DiagnosticBag diagnostics)
7777
this.CheckForIncompleteInference(diagnostics);
7878
}
7979

80+
private void SolveUntilFixpoint(DiagnosticBag diagnostics)
81+
{
82+
while (this.ApplyRulesOnce(diagnostics)) { }
83+
}
84+
8085
private void CheckForUninferredLocals(DiagnosticBag diagnostics)
8186
{
8287
foreach (var local in this.localVariables)

src/Draco.Compiler/Internal/Solver/ConstraintSolver_Rules.cs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Collections.Immutable;
34
using System.Diagnostics;
45
using System.Linq;
@@ -455,7 +456,38 @@ private static void FailOverload(Overload overload)
455456
/// </summary>
456457
private void FailRemainingRules()
457458
{
458-
// TODO
459-
throw new NotImplementedException();
459+
var previousStoreSize = this.constraintStore.Count;
460+
while (true)
461+
{
462+
// We unify type variables with the error type
463+
foreach (var typeVar in this.typeVariables)
464+
{
465+
var unwrapped = typeVar.Substitution;
466+
if (unwrapped is TypeVariable unwrappedTv) UnifyAsserted(unwrappedTv, WellKnownTypes.UninferredType);
467+
}
468+
469+
var constraintsToRemove = new List<Constraint>();
470+
471+
// We can also solve all overload constraints by failing them instantly
472+
foreach (var overload in this.constraintStore.Query<Overload>())
473+
{
474+
FailOverload(overload);
475+
constraintsToRemove.Add(overload);
476+
}
477+
478+
this.constraintStore.RemoveAll(constraintsToRemove);
479+
480+
// Assume this solves everything
481+
this.SolveUntilFixpoint(DiagnosticBag.Empty);
482+
483+
// Check for exit condition
484+
if (previousStoreSize == this.constraintStore.Count) break;
485+
previousStoreSize = this.constraintStore.Count;
486+
}
487+
488+
if (this.constraintStore.Count > 0)
489+
{
490+
throw new InvalidOperationException("fallback operation could not solve all constraints");
491+
}
460492
}
461493
}

src/Draco.Compiler/Internal/Solver/ConstraintStore.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,19 @@ public IEnumerable<TConstraint> Query<TConstraint>(Func<TConstraint, bool>? pred
101101
}
102102
}
103103

104+
/// <summary>
105+
/// Removes all constraints in the given sequence.
106+
/// </summary>
107+
/// <param name="constraints">The constraints to remove.</param>
108+
public void RemoveAll(IEnumerable<Constraint> constraints)
109+
{
110+
foreach (var constraint in constraints)
111+
{
112+
if (!this.constraints.TryGetValue(constraint.GetType(), out var list)) ThrowConstraintNotFound(constraint);
113+
if (!list.Remove(constraint)) ThrowConstraintNotFound(constraint);
114+
}
115+
}
116+
104117
/// <summary>
105118
/// Removes all constraints in the given sequence.
106119
/// </summary>
@@ -112,7 +125,7 @@ public void RemoveAll<TConstraint>(IEnumerable<TConstraint> constraints)
112125
var list = this.GetConstraintList(typeof(TConstraint));
113126
foreach (var constraint in constraints)
114127
{
115-
if (!list.Remove(constraint)) throw new InvalidOperationException($"Constraint {constraint} not found in the store.");
128+
if (!list.Remove(constraint)) ThrowConstraintNotFound(constraint);
116129
}
117130
}
118131

@@ -125,4 +138,8 @@ private List<Constraint> GetConstraintList(Type type)
125138
}
126139
return list;
127140
}
141+
142+
[DoesNotReturn]
143+
private static void ThrowConstraintNotFound(Constraint constraint) =>
144+
throw new InvalidOperationException($"Constraint {constraint} not found in the store.");
128145
}

0 commit comments

Comments
 (0)