Source file src/go/types/under.go

     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  }
   117  

View as plain text