{"record":{"id":"e3fb0b35703586b3","repo":"stride3d/stride","slug":"unsupported-element-type-for-min-context-reversetypes-a","errorCode":null,"errorMessage":"Unsupported element type for min: {context.ReverseTypes[a.TypeId].GetElementType()}","messagePattern":"Unsupported element type for min: (.+?)","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs","lineNumber":113,"sourceCode":"        var instruction = context.ReverseTypes[x.TypeId].GetElementType() switch\n        {\n            ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFAbs(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)),\n            ScalarType { Type: Scalar.UInt or Scalar.Int } => builder.InsertData(new GLSLSAbs(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)),\n            _ => throw new NotSupportedException($\"Unsupported element type for abs: {context.ReverseTypes[x.TypeId].GetElementType()}\"),\n        };\n        return new(instruction);\n    }\n    public override SpirvValue CompileFloor(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLFloor, x);\n    public override SpirvValue CompileCeil(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLCeil, x);\n    public override SpirvValue CompileTrunc(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLTrunc, x);\n    public override SpirvValue CompileMin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default)\n    {\n        var instruction = context.ReverseTypes[a.TypeId].GetElementType() switch\n        {\n            ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFMin(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)),\n            ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUMin(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)),\n            ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSMin(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)),\n            _ => throw new NotSupportedException($\"Unsupported element type for min: {context.ReverseTypes[a.TypeId].GetElementType()}\"),\n        };\n        return new(instruction);\n    }\n\n    public override SpirvValue CompileMax(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default)\n    {\n        var instruction = context.ReverseTypes[a.TypeId].GetElementType() switch\n        {\n            ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFMax(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)),\n            ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUMax(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)),\n            ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSMax(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)),\n            _ => throw new NotSupportedException($\"Unsupported element type for max: {context.ReverseTypes[a.TypeId].GetElementType()}\"),\n        };\n        return new(instruction);\n    }\n\n    public override SpirvValue CompileClamp(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue min, SpirvValue max, TextLocation location = default)\n    {","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs#L95-L131","documentation":"CompileMin maps min() to GLSL.FMin (float/double), GLSL.UMin (uint), or GLSL.SMin (int). An operand whose element type is none of these — e.g. bool or a newly introduced scalar type — reaches the default arm and throws NotSupportedException at IntrinsicImplementations.cs:113.","triggerScenarios":"Calling min(a, b) where a's SPIR-V element scalar type is not Float, Double, UInt, or Int (e.g. bool vectors, half types not yet mapped).","commonSituations":"Using min() on booleans, on float16/half values before the backend supports them, or on custom scalar types added to the type system without updating intrinsics.","solutions":["Call min() only with int/uint/float/double (or vectors thereof) operands.","For bools use logical operators; convert other types with explicit casts before min().","Extend CompileMin with a new switch arm (e.g. GLSLFMin16 for float16) if the type should be supported."],"exampleFix":"// before\nbool2 b = min(b1, b2);      // unsupported\n// after\nbool2 b = bool2(min(v1.x, v2.x) != 0, ...)  // or use explicit comparisons","handlingStrategy":"type-guard","validationCode":"// min supports float/double/uint/int element types only\nif (aType.GetElementType() is not ScalarType { Type: Scalar.Float or Scalar.Double or Scalar.Int or Scalar.UInt })\n    throw new ShaderCompileHint(\"min requires numeric scalar element type\");","typeGuard":"static bool IsMinSupported(BaseType t) => t.GetElementType() is ScalarType s && s.Type is Scalar.Float or Scalar.Double or Scalar.Int or Scalar.UInt;","tryCatchPattern":"try { result = intrinsic.CompileMin(table, context, builder, functionType, a, b); }\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"element type for min\"))\n{ diagnostics.Report(location, ex.Message); }","preventionTips":["Use min() with int/uint/float/double operands only.","Handle booleans with conditional logic, not min().","Keep intrinsic dispatch tables in sync with the scalar type enum."],"tags":["shader","intrinsics","spirv","glm"],"backgroundTag":"unsupported-dtype","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"}