stride3d/stride · error · NotImplementedException

Unsupported integer suffix

Error message

Unsupported integer suffix

What it means

ComputeLiteralType maps an IntegerLiteral's suffix (bit Size and Signedness) to a ScalarType. 8-bit and 16-bit signed/unsigned arms are commented out, and only 32/64-bit are handled; any other suffix combination (e.g. Size 8 or 16, or an invalid Size like 48) throws NotImplementedException('Unsupported integer suffix').

Solutions

  1. Use 32-bit or 64-bit integer literal suffixes (new(32,...) or new(64,...)) when creating IntegerLiterals for this pipeline
  2. Pre-assign literal.Type before calling CompileConstantLiteral so ComputeLiteralType is skipped (literal.Type ??= ... in CompileConstantLiteral)
  3. Uncomment/restore the 8/16-bit arms in ComputeLiteralType (Context.Constants.cs lines 363-368) if small integer types are needed

Example fix

// before
var lit = new IntegerLiteral(new(16, false, true), someShort, location);
CompileConstantLiteral(lit); // throws: Unsupported integer suffix
// after
var lit = new IntegerLiteral(new(32, false, true), (int)someShort, location);
CompileConstantLiteral(lit); // ScalarType.Int
Defensive patterns

Strategy: validation

Validate before calling

bool IsSupportedIntSuffix(LiteralSuffix s) =>
    (s.Size == 32 || s.Size == 64) && (s.Signed || !s.Signed);

Type guard

static bool IsInt32Or64(IntegerLiteral l) => l.Suffix.Size is 32 or 64;

Try / catch

try
{
    var result = context.CompileConstantLiteral(intLiteral);
}
catch (NotImplementedException ex) when (ex.Message == "Unsupported integer suffix")
{
    // widen to 32-bit and retry
    var widened = new IntegerLiteral(new(32, false, intLiteral.Suffix.Signed), intLiteral.IntValue, default);
    var result = context.CompileConstantLiteral(widened);
}

Prevention

When it happens

Trigger: Creating an IntegerLiteral with Suffix Size 8 or 16 (whose mapping to ScalarType.SByte/Short/UByte/UShort is commented out) or a non-standard Size, then letting ComputeLiteralType run (literal.Type not pre-set) via CompileConstantLiteral.

Common situations: Constructing IntegerLiteral(new(8,...), ...) or new(16,...) for byte/short constants and passing them to CompileConstantLiteral without pre-assigning literal.Type; custom literal construction in tooling code.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/e9c751e1f7e87aa0. Report an issue: GitHub.

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs:371

        return result;
    }

    public static ScalarType ComputeLiteralType(Literal literal)
    {
        return literal switch
        {
            BoolLiteral lit => ScalarType.Boolean,
            IntegerLiteral lit => lit.Suffix switch
            {
                //{ Signed: true, Size: 8 } => ScalarType.SByte,
                //{ Signed: true, Size: 16 } => ScalarType.Short,
                { Signed: true, Size: 32 } => ScalarType.Int,
                { Signed: true, Size: 64 } => ScalarType.Int64,
                //{ Signed: false, Size: 8 } => ScalarType.UByte,
                //{ Signed: false, Size: 16 } => ScalarType.UShort,
                { Signed: false, Size: 32 } => ScalarType.UInt,
                { Signed: false, Size: 64 } => ScalarType.UInt64,
                _ => throw new NotImplementedException("Unsupported integer suffix")
            },
            FloatLiteral lit => lit.Suffix.Size switch
            {
                //16 => ScalarType.Half,
                32 => ScalarType.Float,
                64 => ScalarType.Double,
                _ => throw new NotImplementedException("Unsupported float")
            },
            _ => throw new NotSupportedException($"Unsupported literal type: {literal.GetType()}"),
        };
    }
}

View on GitHub (pinned to 96fad776d2)