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  

View as plain text