mirror of
https://github.com/burrowers/garble.git
synced 2026-04-22 15:47:04 +08:00
fix: canonicalize generic field objects for struct hashing
Use `types.Var.Origin()` when mapping and hashing struct fields so selector and declaration sites share the same canonical field identity. This fixes build failures for generic aliases and named types over those aliases. Fixes #924
This commit is contained in:
committed by
Daniel Martí
parent
1b6cc14d93
commit
cb98b4daab
+8
-8
@@ -142,25 +142,25 @@ func debugDirNeedsRebuild() (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
sawBuildInputs := false
|
||||
missingArtifacts := false
|
||||
for _, lpkg := range sharedCache.ListedPackages {
|
||||
if len(lpkg.GarbleActionID) == 0 {
|
||||
continue
|
||||
}
|
||||
if len(lpkg.CompiledGoFiles) > 0 {
|
||||
sawBuildInputs = true
|
||||
if debugArtifactsExistForPkg(fsCache, lpkg, debugCacheKindCompile) {
|
||||
return false, nil
|
||||
if !debugArtifactsExistForPkg(fsCache, lpkg, debugCacheKindCompile) {
|
||||
missingArtifacts = true
|
||||
}
|
||||
}
|
||||
if len(lpkg.SFiles) > 0 {
|
||||
sawBuildInputs = true
|
||||
if debugArtifactsExistForPkg(fsCache, lpkg, debugCacheKindAsm) {
|
||||
return false, nil
|
||||
if !debugArtifactsExistForPkg(fsCache, lpkg, debugCacheKindAsm) {
|
||||
missingArtifacts = true
|
||||
}
|
||||
}
|
||||
}
|
||||
// If no debug artifacts exist yet, force one full rebuild to warm cache.
|
||||
// Once at least one cache entry exists, incremental builds can repopulate
|
||||
// from cache + newly rebuilt packages without forcing -a.
|
||||
return sawBuildInputs, nil
|
||||
// For -debugdir to be complete, we either need artifacts in cache for every
|
||||
// package input, or we need to force one full rebuild with -a.
|
||||
return sawBuildInputs && missingArtifacts, nil
|
||||
}
|
||||
|
||||
+6
-2
@@ -103,11 +103,15 @@ One can reverse a captured panic stack trace as follows:
|
||||
if obj == nil || !obj.IsField() {
|
||||
continue
|
||||
}
|
||||
strct := fieldToStruct[obj]
|
||||
originObj := obj.Origin()
|
||||
strct := fieldToStruct[originObj]
|
||||
if strct == nil {
|
||||
strct = fieldToStruct[obj]
|
||||
}
|
||||
if strct == nil {
|
||||
panic("could not find struct for field " + name.Name)
|
||||
}
|
||||
replaces = append(replaces, hashWithStruct(strct, obj), name.Name)
|
||||
replaces = append(replaces, hashWithStruct(strct, originObj), name.Name)
|
||||
}
|
||||
|
||||
case *ast.CallExpr:
|
||||
|
||||
Vendored
+12
@@ -16,6 +16,11 @@ func main() {
|
||||
|
||||
g2 := GenericGraph[*[]byte]{Content: new([]byte)}
|
||||
g2.Edges = make([]GenericGraph[*[]byte], 1)
|
||||
|
||||
var ga genericAlias
|
||||
ga.list = nil
|
||||
var gan genericAliasNamed
|
||||
gan.list = nil
|
||||
}
|
||||
|
||||
func GenericFunc[GenericParamA, B any](x GenericParamA, y B) {}
|
||||
@@ -66,3 +71,10 @@ func (w *AsyncResult[oldT, newT]) AsResult() Result[newT] {
|
||||
}
|
||||
|
||||
func (w *AsyncResult[oldT, newT]) Redirect(struct {ret newT}) {}
|
||||
|
||||
type genericAlias = generic[int]
|
||||
type generic[T any] struct {
|
||||
list *T
|
||||
}
|
||||
|
||||
type genericAliasNamed genericAlias
|
||||
|
||||
+6
-4
@@ -166,10 +166,11 @@ func recordType(used, origin types.Type, done map[*types.Named]bool, fieldToStru
|
||||
origin := origin.(*types.Struct)
|
||||
for i := range used.NumFields() {
|
||||
field := used.Field(i)
|
||||
fieldToStruct[field] = origin
|
||||
fieldToStruct[field.Origin()] = origin
|
||||
|
||||
if field.Embedded() {
|
||||
recordType(field.Type(), origin.Field(i).Type(), done, fieldToStruct)
|
||||
originField := origin.Field(i)
|
||||
recordType(field.Type(), originField.Type(), done, fieldToStruct)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1237,11 +1238,12 @@ func (tf *transformer) transformGoFile(file *ast.File) *ast.File {
|
||||
// any field is unexported. If that is done, add a test
|
||||
// that ensures unexported fields from different
|
||||
// packages result in different obfuscated names.
|
||||
strct := tf.fieldToStruct[obj]
|
||||
originObj := obj.Origin()
|
||||
strct := tf.fieldToStruct[originObj]
|
||||
if strct == nil {
|
||||
panic("could not find struct for field " + name)
|
||||
}
|
||||
node.Name = hashWithStruct(strct, obj)
|
||||
node.Name = hashWithStruct(strct, originObj)
|
||||
if flagDebug { // TODO(mvdan): remove once https://go.dev/issue/53465 if fixed
|
||||
log.Printf("%s %q hashed with struct fields to %q", debugName, name, node.Name)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user