{"record":{"id":"dfe849d67f9c3b24","repo":"stride3d/stride","slug":"unsupported-type-for-withelementtype-symbol","errorCode":null,"errorMessage":"Unsupported type for WithElementType: {symbol}","messagePattern":"Unsupported type for WithElementType: (.+?)","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs","lineNumber":742,"sourceCode":"    {\n        ScalarType s => 1,\n        VectorType v => v.Size,\n        MatrixType m => m.Rows * m.Columns,\n        _ => throw new NotSupportedException($\"Unsupported type for GetElementCount: {symbol}\"),\n    };\n    public static ScalarType GetElementType(this SymbolType symbol) => symbol switch\n    {\n        ScalarType s => s,\n        VectorType v => v.BaseType,\n        MatrixType m => m.BaseType,\n        _ => throw new NotSupportedException($\"Unsupported type for GetElementType: {symbol}\"),\n    };\n    public static SymbolType WithElementType(this SymbolType symbol, ScalarType elementType) => symbol switch\n    {\n        ScalarType s => elementType,\n        VectorType v => v.BaseType == elementType ? v : v with { BaseType = elementType },\n        MatrixType m => m.BaseType == elementType ? m : m with { BaseType = elementType },\n        _ => throw new NotSupportedException($\"Unsupported type for WithElementType: {symbol}\"),\n    };\n    public static bool IsSignedInteger(this SymbolType symbol) => symbol is ScalarType { Type: Scalar.Int or Scalar.Int64 };\n    public static bool IsUnsignedInteger(this SymbolType symbol) => symbol is ScalarType { Type: Scalar.UInt or Scalar.UInt64 };\n    public static bool IsFloating(this SymbolType symbol) => symbol is ScalarType { Type: Scalar.Half or Scalar.Float or Scalar.Double };\n    public static bool IsInteger(this SymbolType symbol) => symbol.IsSignedInteger() || symbol.IsUnsignedInteger();\n    public static bool IsNumber(this SymbolType symbol) => symbol.IsInteger() || symbol.IsFloating();\n    public static bool IsSigned(this SymbolType symbol) => symbol.IsSignedInteger() || symbol.IsFloating();\n    public static bool IsUnsigned(this SymbolType symbol) => symbol.IsUnsignedInteger();\n    public static bool IsSignedIntegerVector(this SymbolType symbol)\n        => symbol.IsSignedInteger() || symbol is VectorType v && v.BaseType.IsSignedInteger();\n    public static bool IsUnsignedIntegerVector(this SymbolType symbol)\n        => symbol.IsUnsignedInteger() || symbol is VectorType v && v.BaseType.IsUnsignedInteger();\n    public static bool IsIntegerVector(this SymbolType symbol)\n        => symbol.IsInteger() || symbol is VectorType v && v.BaseType.IsInteger();\n    public static bool IsFloatingVector(this SymbolType symbol)\n        => symbol.IsFloating() || symbol is VectorType v && v.BaseType.IsFloating();\n    public static bool IsNumberVector(this SymbolType symbol)\n        => symbol.IsNumber() || symbol is VectorType v && v.BaseType.IsNumber();","sourceCodeStart":724,"sourceCodeEnd":760,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs#L724-L760","documentation":"WithElementType rebuilds a SymbolType with a new scalar element type (returns a new scalar, or a vector/matrix with the base type replaced). It throws NotSupportedException for SymbolTypes without an element type — arrays, structs, pointers, images, etc.","triggerScenarios":"Calling WithElementType() on a non-numeric SymbolType while rewriting types, e.g. during numeric type promotion/demotion or implicit conversion insertion in SPIR-V building.","commonSituations":"Shader code containing arrays/structs reaches a numeric-type rewrite helper that only understands scalar/vector/matrix, often after a language or IR change introduced new SymbolType kinds.","solutions":["Ensure the caller only invokes WithElementType on Scalar/Vector/Matrix types.","Add an ArrayType arm (rebuild array with new element base type) if arrays should be supported.","Narrow the call site with a type check before rewriting the type.","Inspect the failing symbol's kind to identify which new type variant needs handling."],"exampleFix":"// before\nvar newType = symbolType.WithElementType(ScalarType.Float);\n// after\nvar newType = symbolType switch\n{\n    ScalarType => (SymbolType)ScalarType.Float,\n    VectorType v => v with { BaseType = ScalarType.Float },\n    MatrixType m => m with { BaseType = ScalarType.Float },\n    _ => throw new NotSupportedException($\"Cannot replace element type of {symbolType}\")\n};","handlingStrategy":"type-guard","validationCode":"bool canRewrite = t is ScalarType or VectorType or MatrixType;","typeGuard":"static bool SupportsElementTypeRewrite(SymbolType t) => t is ScalarType or VectorType or MatrixType;","tryCatchPattern":"try { newType = symbol.WithElementType(scalar); } catch (NotSupportedException) { /* use type-specific rewrite */ }","preventionTips":["Restrict numeric rewrites to numeric types","Add match arms for arrays if rewrite should propagate into them","Keep WithElementType/GetElementType/GetElementCount arms in sync","Test type rewrites against every SymbolType subclass"],"tags":["spirv","shader-compiler","unsupported-type"],"backgroundTag":"unsupported-operation","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}