lang: unification, interfaces: Add a skip invariant
This is a cleaner way of telling the type unifier that we don't want this particular expression in the solution set at the end.
This commit is contained in:
@@ -170,6 +170,9 @@ func DebugSolverState(solved map[interfaces.Expr]*types.Type, equalities []inter
|
||||
case *interfaces.AnyInvariant:
|
||||
// skip, not used in the examples I care about
|
||||
|
||||
case *interfaces.SkipInvariant:
|
||||
// we don't care about this one
|
||||
|
||||
default:
|
||||
s += fmt.Sprintf("%v\n", equality)
|
||||
}
|
||||
@@ -249,6 +252,10 @@ func SimpleInvariantSolver(invariants []interfaces.Invariant, expected []interfa
|
||||
case *interfaces.CallFuncArgsValueInvariant:
|
||||
equalities = append(equalities, invariant)
|
||||
|
||||
case *interfaces.SkipInvariant:
|
||||
// drop it for now
|
||||
//equalities = append(equalities, invariant)
|
||||
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unknown invariant type: %T", x)
|
||||
}
|
||||
@@ -296,6 +303,8 @@ func SimpleInvariantSolver(invariants []interfaces.Invariant, expected []interfa
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//skipExprs := make(map[interfaces.Expr]struct{})
|
||||
|
||||
// XXX: if these partials all shared the same variable definition, would
|
||||
// it all work??? Maybe we don't even need the first map prefix...
|
||||
listPartials := make(map[interfaces.Expr]map[interfaces.Expr]*types.Type)
|
||||
@@ -1074,6 +1083,11 @@ Loop:
|
||||
// a generator invariant wants to read them...
|
||||
continue
|
||||
|
||||
case *interfaces.SkipInvariant:
|
||||
//skipExprs[eq.Expr] = struct{}{} // save
|
||||
used = append(used, eqi) // mark equality as used up
|
||||
continue
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown invariant type: %T", eqx)
|
||||
}
|
||||
@@ -1334,6 +1348,12 @@ Loop:
|
||||
solutions := []*interfaces.EqualsInvariant{}
|
||||
// FIXME: can we do this loop in a deterministic, sorted way?
|
||||
for expr, typ := range solved {
|
||||
// Don't do this here, or the current Unifier struct machinery
|
||||
// will see it as a bug. Do it there until we change the API.
|
||||
//if _, exists := skipExprs[expr]; exists {
|
||||
// continue
|
||||
//}
|
||||
|
||||
invar := &interfaces.EqualsInvariant{
|
||||
Expr: expr,
|
||||
Type: typ,
|
||||
|
||||
@@ -72,7 +72,13 @@ func (obj *Unifier) Unify() error {
|
||||
|
||||
// build a list of what we think we need to solve for to succeed
|
||||
exprs := []interfaces.Expr{}
|
||||
skips := make(map[interfaces.Expr]struct{})
|
||||
for _, x := range invariants {
|
||||
if si, ok := x.(*interfaces.SkipInvariant); ok {
|
||||
skips[si.Expr] = struct{}{}
|
||||
continue
|
||||
}
|
||||
|
||||
exprs = append(exprs, x.ExprList()...)
|
||||
}
|
||||
exprMap := ExprListToExprMap(exprs) // makes searching faster
|
||||
@@ -137,6 +143,10 @@ func (obj *Unifier) Unify() error {
|
||||
// programming error ?
|
||||
return fmt.Errorf("unexpected invalid solution at: %p", x)
|
||||
}
|
||||
if _, exists := skips[x.Expr]; exists {
|
||||
continue
|
||||
}
|
||||
|
||||
if obj.Debug {
|
||||
obj.Logf("solution: %p => %+v\t(%+v)", x.Expr, x.Type, x.Expr.String())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user