| // asmcheck | |
| // Copyright 2026 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| // Test that type assertions and type switch cases that are impossible | |
| // based on shape type analysis are eliminated from generated code. | |
| package codegen | |
| // -- Type switch elimination -- | |
| func switchStringOrBytes[S string | []byte](x S) string { | |
| switch any(x).(type) { | |
| case string: | |
| return "string" | |
| case []byte: | |
| return "[]byte" | |
| } | |
| return "" | |
| } | |
| // In the string instantiation, the []byte case is impossible | |
| // and should be eliminated. | |
| func SwitchStringInst(x string) string { | |
| // amd64:-"type:.*uint8" | |
| return switchStringOrBytes(x) | |
| } | |
| // In the []byte instantiation, the string case is impossible | |
| // and should be eliminated. | |
| func SwitchBytesInst(x []byte) string { | |
| // amd64:-"type:string" | |
| return switchStringOrBytes(x) | |
| } | |
| // -- Comma-ok type assertion elimination -- | |
| func commaOkString[S string | []byte](x S) (string, bool) { | |
| v, ok := any(x).(string) | |
| return v, ok | |
| } | |
| // In the []byte instantiation, .(string) always fails. | |
| // The type comparison against type:string should be eliminated. | |
| func CommaOkStringBytesInst(x []byte) (string, bool) { | |
| // amd64:-"type:string" | |
| return commaOkString(x) | |
| } | |
| // In the string instantiation, the comparison against type:string | |
| // is also eliminated because the assertion always succeeds. | |
| func CommaOkStringStringInst(x string) (string, bool) { | |
| // amd64:-"LEAQ\ttype:string" | |
| return commaOkString(x) | |
| } | |
| // -- Intermediate variable: comma-ok -- | |
| func commaOkViaVar[S string | []byte](x S) (string, bool) { | |
| iface := any(x) | |
| v, ok := iface.(string) | |
| return v, ok | |
| } | |
| func CommaOkViaVarBytesInst(x []byte) (string, bool) { | |
| // amd64:-"type:string" | |
| return commaOkViaVar(x) | |
| } | |
| // -- Intermediate variable: type switch -- | |
| func switchViaVar[S string | []byte](x S) string { | |
| iface := any(x) | |
| switch iface.(type) { | |
| case string: | |
| return "string" | |
| case []byte: | |
| return "[]byte" | |
| } | |
| return "" | |
| } | |
| func SwitchViaVarStringInst(x string) string { | |
| // amd64:-"type:.*uint8" | |
| return switchViaVar(x) | |
| } | |
| func SwitchViaVarBytesInst(x []byte) string { | |
| // amd64:-"type:string" | |
| return switchViaVar(x) | |
| } | |
| // -- All cases eliminated for one instantiation -- | |
| func switchFallsToDefault[S string | []byte | int](x S) string { | |
| switch any(x).(type) { | |
| case string: | |
| return "string" | |
| case []byte: | |
| return "[]byte" | |
| } | |
| return "other" | |
| } | |
| // int instantiation: both cases are impossible. | |
| func SwitchFallsToDefaultIntInst(x int) string { | |
| // amd64:-"type:string" | |
| // amd64:-"type:.*uint8" | |
| return switchFallsToDefault(x) | |
| } |