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