Source file test/codegen/shape_assert.go

     1  // asmcheck
     2  
     3  // Copyright 2026 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  // Test that type assertions and type switch cases that are impossible
     8  // based on shape type analysis are eliminated from generated code.
     9  
    10  package codegen
    11  
    12  // -- Type switch elimination --
    13  
    14  func switchStringOrBytes[S string | []byte](x S) string {
    15  	switch any(x).(type) {
    16  	case string:
    17  		return "string"
    18  	case []byte:
    19  		return "[]byte"
    20  	}
    21  	return ""
    22  }
    23  
    24  // In the string instantiation, the []byte case is impossible
    25  // and should be eliminated.
    26  func SwitchStringInst(x string) string {
    27  	// amd64:-"type:.*uint8"
    28  	return switchStringOrBytes(x)
    29  }
    30  
    31  // In the []byte instantiation, the string case is impossible
    32  // and should be eliminated.
    33  func SwitchBytesInst(x []byte) string {
    34  	// amd64:-"type:string"
    35  	return switchStringOrBytes(x)
    36  }
    37  
    38  // -- Comma-ok type assertion elimination --
    39  
    40  func commaOkString[S string | []byte](x S) (string, bool) {
    41  	v, ok := any(x).(string)
    42  	return v, ok
    43  }
    44  
    45  // In the []byte instantiation, .(string) always fails.
    46  // The type comparison against type:string should be eliminated.
    47  func CommaOkStringBytesInst(x []byte) (string, bool) {
    48  	// amd64:-"type:string"
    49  	return commaOkString(x)
    50  }
    51  
    52  // In the string instantiation, the comparison against type:string
    53  // is also eliminated because the assertion always succeeds.
    54  func CommaOkStringStringInst(x string) (string, bool) {
    55  	// amd64:-"LEAQ\ttype:string"
    56  	return commaOkString(x)
    57  }
    58  
    59  // -- Intermediate variable: comma-ok --
    60  
    61  func commaOkViaVar[S string | []byte](x S) (string, bool) {
    62  	iface := any(x)
    63  	v, ok := iface.(string)
    64  	return v, ok
    65  }
    66  
    67  func CommaOkViaVarBytesInst(x []byte) (string, bool) {
    68  	// amd64:-"type:string"
    69  	return commaOkViaVar(x)
    70  }
    71  
    72  // -- Intermediate variable: type switch --
    73  
    74  func switchViaVar[S string | []byte](x S) string {
    75  	iface := any(x)
    76  	switch iface.(type) {
    77  	case string:
    78  		return "string"
    79  	case []byte:
    80  		return "[]byte"
    81  	}
    82  	return ""
    83  }
    84  
    85  func SwitchViaVarStringInst(x string) string {
    86  	// amd64:-"type:.*uint8"
    87  	return switchViaVar(x)
    88  }
    89  
    90  func SwitchViaVarBytesInst(x []byte) string {
    91  	// amd64:-"type:string"
    92  	return switchViaVar(x)
    93  }
    94  
    95  // -- All cases eliminated for one instantiation --
    96  
    97  func switchFallsToDefault[S string | []byte | int](x S) string {
    98  	switch any(x).(type) {
    99  	case string:
   100  		return "string"
   101  	case []byte:
   102  		return "[]byte"
   103  	}
   104  	return "other"
   105  }
   106  
   107  // int instantiation: both cases are impossible.
   108  func SwitchFallsToDefaultIntInst(x int) string {
   109  	// amd64:-"type:string"
   110  	// amd64:-"type:.*uint8"
   111  	return switchFallsToDefault(x)
   112  }
   113  

View as plain text