Source file src/go/types/under.go
1 // Code generated by "go test -run=Generate -write=all"; DO NOT EDIT. 2 // Source: ../../cmd/compile/internal/types2/under.go 3 4 // Copyright 2011 The Go Authors. All rights reserved. 5 // Use of this source code is governed by a BSD-style 6 // license that can be found in the LICENSE file. 7 8 package types 9 10 // under returns the true expanded underlying type. 11 // If it doesn't exist, the result is Typ[Invalid]. 12 // under must only be called when a type is known 13 // to be fully set up. 14 func under(t Type) Type { 15 if t := asNamed(t); t != nil { 16 return t.under() 17 } 18 return t.Underlying() 19 } 20 21 // If t is not a type parameter, coreType returns the underlying type. 22 // If t is a type parameter, coreType returns the single underlying 23 // type of all types in its type set if it exists, or nil otherwise. If the 24 // type set contains only unrestricted and restricted channel types (with 25 // identical element types), the single underlying type is the restricted 26 // channel type if the restrictions are always the same, or nil otherwise. 27 func coreType(t Type) Type { 28 tpar, _ := t.(*TypeParam) 29 if tpar == nil { 30 return under(t) 31 } 32 33 var su Type 34 if tpar.underIs(func(u Type) bool { 35 if u == nil { 36 return false 37 } 38 if su != nil { 39 u = match(su, u) 40 if u == nil { 41 return false 42 } 43 } 44 // su == nil || match(su, u) != nil 45 su = u 46 return true 47 }) { 48 return su 49 } 50 return nil 51 } 52 53 // coreString is like coreType but also considers []byte 54 // and strings as identical. In this case, if successful and we saw 55 // a string, the result is of type (possibly untyped) string. 56 func coreString(t Type) Type { 57 tpar, _ := t.(*TypeParam) 58 if tpar == nil { 59 return under(t) // string or untyped string 60 } 61 62 var su Type 63 hasString := false 64 if tpar.underIs(func(u Type) bool { 65 if u == nil { 66 return false 67 } 68 if isString(u) { 69 u = NewSlice(universeByte) 70 hasString = true 71 } 72 if su != nil { 73 u = match(su, u) 74 if u == nil { 75 return false 76 } 77 } 78 // su == nil || match(su, u) != nil 79 su = u 80 return true 81 }) { 82 if hasString { 83 return Typ[String] 84 } 85 return su 86 } 87 return nil 88 } 89 90 // If x and y are identical, match returns x. 91 // If x and y are identical channels but for their direction 92 // and one of them is unrestricted, match returns the channel 93 // with the restricted direction. 94 // In all other cases, match returns nil. 95 func match(x, y Type) Type { 96 // Common case: we don't have channels. 97 if Identical(x, y) { 98 return x 99 } 100 101 // We may have channels that differ in direction only. 102 if x, _ := x.(*Chan); x != nil { 103 if y, _ := y.(*Chan); y != nil && Identical(x.elem, y.elem) { 104 // We have channels that differ in direction only. 105 // If there's an unrestricted channel, select the restricted one. 106 switch { 107 case x.dir == SendRecv: 108 return y 109 case y.dir == SendRecv: 110 return x 111 } 112 } 113 } 114 115 // types are different 116 return nil 117 } 118