stride3d/stride · error · NotImplementedException

Exception of type 'System.NotImplementedException' was…

Error message

Exception of type 'System.NotImplementedException' was thrown.

What it means

LiteralParsers.Match parses floating-point literal suffixes. The scanner first accepts any of f, f16, f32, f64, d, h via Tokens.AnyOf, then maps the matched string to a Suffix. Because AnyOf already restricts the input to six known suffixes, the switch's default arm is defensively unreachable; if it is ever hit (inconsistent tokenizer vs. switch) a bare NotImplementedException is thrown.

Solutions

  1. Ensure every string in the AnyOf list ([f, f16, f32, f64, d, h]) has a matching case in the switch (LiteralParsers.cs:315-324).
  2. If adding a new suffix (e.g. 'df'), add both the AnyOf entry and a Suffix case.
  3. As a hardening measure, return a parse error instead of throwing so malformed suffixes produce a diagnostic.

Example fix

// before
var matched = Tokens.AnyOf(["f", "f16", "f32", "f64", "d", "h", "df"], ...);
suffix = matched switch { "f16" or "h" => ..., _ => throw new NotImplementedException() };
// after
suffix = matched switch
{
    "f16" or "h" => new(16, true, true),
    "f32" or "f" => new(32, true, true),
    "f64" or "d" or "df" => new(64, true, true),
    _ => throw new NotImplementedException()
};
Defensive patterns

Strategy: validation

Validate before calling

var known = new[] { "f", "f16", "f32", "f64", "d", "h" };
if (!known.Contains(candidate)) return false; // not a float suffix; let another parser try

Type guard

bool IsKnownFloatSuffix(string s) => s is "f" or "f16" or "f32" or "f64" or "d" or "h";

Try / catch

try { matched = parser.Match(ref scanner, result, out suffix); }
catch (NotImplementedException ex) { reportParseError(scanner.Location, "Unknown float literal suffix", ex); }

Prevention

When it happens

Trigger: Only via an internal inconsistency: AnyOf matches a suffix string that the switch does not handle — e.g. someone adds a new suffix to the AnyOf list (or changes scanner behavior) without adding a corresponding switch case.

Common situations: Library development: extending the float suffix list in Tokens.AnyOf but forgetting the mapping; custom scanners overriding matching behavior.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs:323

            scanner.Advance(match.Length);
            return true;
        }
        return false;
    }

    public readonly bool Match<TScanner>(ref TScanner scanner, ParseResult result, out Suffix suffix, in ParseError? orError = null)
        where TScanner : struct, IScanner
    {
        suffix = new(32, false, false);
        if (Tokens.AnyOf(["f", "f16", "f32", "f64", "d", "h"], ref scanner, out var matched, advance: true))
        {
            suffix = matched switch
            {
                "f16" or "h" => new(16, true, true),
                "f32" or "f" => new(32, true, true),
                "f64" or "d" => new(64, true, true),

                _ => throw new NotImplementedException()
            };
            return true;
        }
        else return false;
    }
}

public readonly record struct IntegerSuffixParser() : ILiteralParser<Suffix>
{
    public static bool TryMatchAndAdvance<TScanner>(ref TScanner scanner, string match)
        where TScanner : struct, IScanner
    {
        if (Tokens.Literal(match, ref scanner))
        {
            scanner.Advance(match.Length);
            return true;
        }
        return false;

View on GitHub (pinned to 96fad776d2)