lang: funcs: Fix structlookup unification bug

We had mapped the field type to a dummy type instead of to T2 the return
type. Fixed now and added some tests.

This broke the unification for the load function lookups.
This commit is contained in:
James Shubin
2021-05-23 22:52:50 -04:00
parent 45b08de874
commit 3e4652dca3
3 changed files with 47 additions and 5 deletions

View File

@@ -238,20 +238,22 @@ func (obj *StructLookupPolyFunc) Unify(expr interfaces.Expr) ([]interfaces.Invar
invariants = append(invariants, invar) invariants = append(invariants, invar)
// We know *some* information about the struct! // We know *some* information about the struct!
// XXX: uncomment this if we're sure that the // Let's hope the unusedField expr won't trip
// unusedField expr won't trip up the solver... // up the solver...
mapped := make(map[string]interfaces.Expr) mapped := make(map[string]interfaces.Expr)
ordered := []string{} ordered := []string{}
for _, x := range t1.Ord { for _, x := range t1.Ord {
// We *don't* need to solve dummyField! // We *don't* need to solve unusedField
unusedField := &interfaces.ExprAny{} unusedField := &interfaces.ExprAny{}
mapped[x] = unusedField mapped[x] = unusedField
if x == field { // the one we care about if x == field { // the one we care about
mapped[x] = dummyField mapped[x] = dummyOut
} }
ordered = append(ordered, x) ordered = append(ordered, x)
} }
mapped[field] = dummyField // redundant =D // We map to dummyOut which is the return type
// and has the same type of the field we want!
mapped[field] = dummyOut // redundant =D
invar = &interfaces.EqualityWrapStructInvariant{ invar = &interfaces.EqualityWrapStructInvariant{
Expr1: dummyStruct, Expr1: dummyStruct,
Expr2Map: mapped, Expr2Map: mapped,

View File

@@ -0,0 +1,5 @@
Vertex: test[passed0a]
Vertex: test[passed0b]
Vertex: test[passed0c]
Vertex: test[passed1]
Vertex: test[passed2]

View File

@@ -0,0 +1,35 @@
$st0 = struct{x1 => 1.0, x5 => 2.1, x15 => 3.2,}
$s0a = if structlookup($st0, "x1") == 1.0 {
"passed0a"
} else {
"failed"
}
test $s0a {}
$s0b = if structlookup($st0, "x5") == 2.1 {
"passed0b"
} else {
"failed"
}
test $s0b {}
$s0c = if structlookup($st0, "x15") == 3.2 {
"passed0c"
} else {
"failed"
}
test $s0c {}
$st1 struct{x1 float; x5 float; x15 float} = struct{x1 => 1.0, x5 => 2.1, x15 => 3.2,}
$s1 = if structlookup($st1, "x5") == 2.1 {
"passed1"
} else {
"failed"
}
test $s1 {}
$st2 = struct{x1 => 1.0, x5 => 2.1, x15 => 3.2,}
$s2 = if structlookup($st2, "x5") == 2.1 {
"passed2"
} else {
"failed"
}
test $s2 {}