lang: funcs: Hint the struct_lookup functions better

If we have static information, use it to help unification.
This commit is contained in:
James Shubin
2024-08-21 19:00:51 -04:00
parent 82cac572ca
commit 8594b6e2a9
3 changed files with 35 additions and 0 deletions

View File

@@ -125,6 +125,16 @@ func (obj *StructLookupFunc) FuncInfer(partialType *types.Type, partialValues []
// This can happen at runtime too, but we save it here for Build()! // This can happen at runtime too, but we save it here for Build()!
obj.field = s // store for later obj.field = s // store for later
// Figure out more about the sig if any information is known statically.
if len(partialType.Ord) > 0 && partialType.Map[partialType.Ord[0]] != nil {
obj.Type = partialType.Map[partialType.Ord[0]] // assume this
if obj.Type.Kind == types.KindStruct && obj.Type.Map != nil {
if typ, exists := obj.Type.Map[s]; exists {
obj.Out = typ
}
}
}
// This isn't precise enough because we must guarantee that the field is // This isn't precise enough because we must guarantee that the field is
// in the struct and that ?1 is actually a struct, but that's okay it is // in the struct and that ?1 is actually a struct, but that's okay it is
// something that we'll verify at build time! // something that we'll verify at build time!

View File

@@ -132,6 +132,16 @@ func (obj *StructLookupOptionalFunc) FuncInfer(partialType *types.Type, partialV
// This can happen at runtime too, but we save it here for Build()! // This can happen at runtime too, but we save it here for Build()!
//obj.field = s // don't store for this optional lookup version! //obj.field = s // don't store for this optional lookup version!
// Figure out more about the sig if any information is known statically.
if len(partialType.Ord) > 0 && partialType.Map[partialType.Ord[0]] != nil {
obj.Type = partialType.Map[partialType.Ord[0]] // assume this
if obj.Type.Kind == types.KindStruct && obj.Type.Map != nil {
if typ, exists := obj.Type.Map[s]; exists {
obj.Out = typ
}
}
}
// This isn't precise enough because we must guarantee that the field is // This isn't precise enough because we must guarantee that the field is
// in the struct and that ?1 is actually a struct, but that's okay it is // in the struct and that ?1 is actually a struct, but that's okay it is
// something that we'll verify at build time! (Or skip it for optional!) // something that we'll verify at build time! (Or skip it for optional!)

View File

@@ -0,0 +1,15 @@
-- main.mcl --
import "fmt"
$st = struct{
field1 => "value1",
field2 => "value2",
}
class test_struct_lookup($v1, $v2) {
test "test-${v1}-${v2}" {}
}
include test_struct_lookup($st->field1, $st->field2)
-- OUTPUT --
Vertex: test[test-value1-value2]