Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go/types, cmd/compile/internal/types2: provide unique ID to identify instantiations of the same original type #46794

Open
mdempsky opened this issue Jun 16, 2021 · 1 comment

Comments

@mdempsky
Copy link
Member

@mdempsky mdempsky commented Jun 16, 2021

In both unified IR and types2, an operation that seems useful is to take an instantiated Named and decompose it into the (original) TypeName and type arguments.

Currently there's a Named.Orig method, but it's not always the case that Named.Orig is idempotent. E.g., there are at least test cases where it's necessary to apply it twice.

This is a placeholder issue to look into this further before Go 1.18.

/cc @griesemer @findleyr

@mdempsky
Copy link
Member Author

@mdempsky mdempsky commented Jun 16, 2021

noder/writer.go code:

case *types2.Named:
// Type aliases can refer to uninstantiated generic types, so we
// might see len(TParams) != 0 && len(TArgs) == 0 here.
// TODO(mdempsky): Revisit after #46477 is resolved.
assert(len(typ.TParams()) == len(typ.TArgs()) || len(typ.TArgs()) == 0)
// TODO(mdempsky): Why do we need to loop here?
orig := typ
for orig.TArgs() != nil {
orig = orig.Orig()
}
w.code(typeNamed)
w.obj(orig.Obj(), typ.TArgs())

types2/typestring.go code:

if instanceHashing != 0 {
// For local defined types, use the (original!) TypeName's position
// to disambiguate. This is overkill, and could probably instead
// just be the pointer value (if we assume a non-moving GC) or
// a unique ID (like cmd/compile uses). But this works for now,
// and is convenient for debugging.
// TODO(mdempsky): I still don't fully understand why typ.orig.orig
// can differ from typ.orig, or whether looping more than twice is
// ever necessary.
typ := obj.typ.(*Named)
for typ.orig != typ {
typ = typ.orig
}
if orig := typ.obj; orig.pkg != nil && orig.parent != orig.pkg.scope {
fmt.Fprintf(buf, "@%q", orig.pos)
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant