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  

View as plain text