diff options
Diffstat (limited to 'src/cmd/compile/internal/types/type.go')
-rw-r--r-- | src/cmd/compile/internal/types/type.go | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go index 8499a36edc..2a65b713be 100644 --- a/src/cmd/compile/internal/types/type.go +++ b/src/cmd/compile/internal/types/type.go @@ -5,6 +5,7 @@ package types import ( + "cmd/compile/internal/base" "cmd/internal/obj" "cmd/internal/src" "fmt" @@ -1517,3 +1518,47 @@ var ( TypeVoid = newSSA("void") TypeInt128 = newSSA("int128") ) + +func SetUnderlying(t, underlying *Type) { + if underlying.Etype == TFORW { + // This type isn't computed yet; when it is, update n. + underlying.ForwardType().Copyto = append(underlying.ForwardType().Copyto, t) + return + } + + ft := t.ForwardType() + + // TODO(mdempsky): Fix Type rekinding. + t.Etype = underlying.Etype + t.Extra = underlying.Extra + t.Width = underlying.Width + t.Align = underlying.Align + t.Orig = underlying.Orig + + if underlying.NotInHeap() { + t.SetNotInHeap(true) + } + if underlying.Broke() { + t.SetBroke(true) + } + + // spec: "The declared type does not inherit any methods bound + // to the existing type, but the method set of an interface + // type [...] remains unchanged." + if t.IsInterface() { + *t.Methods() = *underlying.Methods() + *t.AllMethods() = *underlying.AllMethods() + } + + // Update types waiting on this type. + for _, w := range ft.Copyto { + SetUnderlying(w, t) + } + + // Double-check use of type as embedded type. + if ft.Embedlineno.IsKnown() { + if t.IsPtr() || t.IsUnsafePtr() { + base.ErrorfAt(ft.Embedlineno, "embedded type cannot be a pointer") + } + } +} |