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 t = Unalias(t) 29 tpar, _ := t.(*TypeParam) 30 if tpar == nil { 31 return under(t) 32 } 33 34 var su Type 35 if tpar.underIs(func(u Type) bool { 36 if u == nil { 37 return false 38 } 39 if su != nil { 40 u = match(su, u) 41 if u == nil { 42 return false 43 } 44 } 45 // su == nil || match(su, u) != nil 46 su = u 47 return true 48 }) { 49 return su 50 } 51 return nil 52 } 53 54 // coreString is like coreType but also considers []byte 55 // and strings as identical. In this case, if successful and we saw 56 // a string, the result is of type (possibly untyped) string. 57 func coreString(t Type) Type { 58 t = Unalias(t) 59 tpar, _ := t.(*TypeParam) 60 if tpar == nil { 61 return under(t) // string or untyped string 62 } 63 64 var su Type 65 hasString := false 66 if tpar.underIs(func(u Type) bool { 67 if u == nil { 68 return false 69 } 70 if isString(u) { 71 u = NewSlice(universeByte) 72 hasString = true 73 } 74 if su != nil { 75 u = match(su, u) 76 if u == nil { 77 return false 78 } 79 } 80 // su == nil || match(su, u) != nil 81 su = u 82 return true 83 }) { 84 if hasString { 85 return Typ[String] 86 } 87 return su 88 } 89 return nil 90 } 91 92 // If x and y are identical, match returns x. 93 // If x and y are identical channels but for their direction 94 // and one of them is unrestricted, match returns the channel 95 // with the restricted direction. 96 // In all other cases, match returns nil. 97 func match(x, y Type) Type { 98 // Common case: we don't have channels. 99 if Identical(x, y) { 100 return x 101 } 102 103 // We may have channels that differ in direction only. 104 if x, _ := x.(*Chan); x != nil { 105 if y, _ := y.(*Chan); y != nil && Identical(x.elem, y.elem) { 106 // We have channels that differ in direction only. 107 // If there's an unrestricted channel, select the restricted one. 108 switch { 109 case x.dir == SendRecv: 110 return y 111 case y.dir == SendRecv: 112 return x 113 } 114 } 115 } 116 117 // types are different 118 return nil 119 } 120