lang: funcs: core: world: Add unification to schedule return expr
This adds a sneaky unification between the expression of the function return value in the unification. I am not entirely sure how often this will get used, but it could be valuable in the right instance if this isn't already learned through other sources. I'm fairly confident that it isn't incorrect, so in the worst case scenario it's redundant information for the unification solver. This is being added as a separate commit so that it's obvious how this type of unification invariant can be applied.
This commit is contained in:
@@ -142,7 +142,7 @@ func (obj *SchedulePolyFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant
|
|||||||
if cfavInvar.Func != expr {
|
if cfavInvar.Func != expr {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// cfavInvar.Expr is the ExprCall!
|
// cfavInvar.Expr is the ExprCall! (the return pointer)
|
||||||
// cfavInvar.Args are the args that ExprCall uses!
|
// cfavInvar.Args are the args that ExprCall uses!
|
||||||
if len(cfavInvar.Args) == 0 {
|
if len(cfavInvar.Args) == 0 {
|
||||||
return nil, fmt.Errorf("unable to build function with no args")
|
return nil, fmt.Errorf("unable to build function with no args")
|
||||||
@@ -155,6 +155,13 @@ func (obj *SchedulePolyFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant
|
|||||||
var invariants []interfaces.Invariant
|
var invariants []interfaces.Invariant
|
||||||
var invar interfaces.Invariant
|
var invar interfaces.Invariant
|
||||||
|
|
||||||
|
// add the relationship to the returned value
|
||||||
|
invar = &interfaces.EqualityInvariant{
|
||||||
|
Expr1: cfavInvar.Expr,
|
||||||
|
Expr2: dummyOut,
|
||||||
|
}
|
||||||
|
invariants = append(invariants, invar)
|
||||||
|
|
||||||
// add the relationships to the called args
|
// add the relationships to the called args
|
||||||
invar = &interfaces.EqualityInvariant{
|
invar = &interfaces.EqualityInvariant{
|
||||||
Expr1: cfavInvar.Args[0],
|
Expr1: cfavInvar.Args[0],
|
||||||
@@ -180,7 +187,7 @@ func (obj *SchedulePolyFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant
|
|||||||
optsTypeKnown := false
|
optsTypeKnown := false
|
||||||
|
|
||||||
// speculate about the type?
|
// speculate about the type?
|
||||||
if typ, err := cfavInvar.Args[1].Type(); err == nil {
|
if typ, exists := solved[cfavInvar.Args[1]]; exists {
|
||||||
optsTypeKnown = true
|
optsTypeKnown = true
|
||||||
if typ.Kind != types.KindStruct {
|
if typ.Kind != types.KindStruct {
|
||||||
return nil, fmt.Errorf("second arg must be of kind struct")
|
return nil, fmt.Errorf("second arg must be of kind struct")
|
||||||
@@ -234,6 +241,14 @@ func (obj *SchedulePolyFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant
|
|||||||
}
|
}
|
||||||
invariants = append(invariants, invar)
|
invariants = append(invariants, invar)
|
||||||
}
|
}
|
||||||
|
// redundant?
|
||||||
|
if typ, err := cfavInvar.Args[1].Type(); err == nil {
|
||||||
|
invar := &interfaces.EqualsInvariant{
|
||||||
|
Expr: cfavInvar.Args[1],
|
||||||
|
Type: typ,
|
||||||
|
}
|
||||||
|
invariants = append(invariants, invar)
|
||||||
|
}
|
||||||
|
|
||||||
// If we're strict, require it, otherwise let
|
// If we're strict, require it, otherwise let
|
||||||
// in whatever, and let Build() deal with it.
|
// in whatever, and let Build() deal with it.
|
||||||
|
|||||||
Reference in New Issue
Block a user