{"record":{"id":"d0d009409899582a","repo":"stride3d/stride","slug":"exception-of-type-system-notimplementedexception-was-thrown-d0d009","errorCode":null,"errorMessage":"Exception of type 'System.NotImplementedException' was thrown.","messagePattern":"Exception of type 'System\\.NotImplementedException' was thrown\\.","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs","lineNumber":323,"sourceCode":"            scanner.Advance(match.Length);\n            return true;\n        }\n        return false;\n    }\n\n    public readonly bool Match<TScanner>(ref TScanner scanner, ParseResult result, out Suffix suffix, in ParseError? orError = null)\n        where TScanner : struct, IScanner\n    {\n        suffix = new(32, false, false);\n        if (Tokens.AnyOf([\"f\", \"f16\", \"f32\", \"f64\", \"d\", \"h\"], ref scanner, out var matched, advance: true))\n        {\n            suffix = matched switch\n            {\n                \"f16\" or \"h\" => new(16, true, true),\n                \"f32\" or \"f\" => new(32, true, true),\n                \"f64\" or \"d\" => new(64, true, true),\n\n                _ => throw new NotImplementedException()\n            };\n            return true;\n        }\n        else return false;\n    }\n}\n\npublic readonly record struct IntegerSuffixParser() : ILiteralParser<Suffix>\n{\n    public static bool TryMatchAndAdvance<TScanner>(ref TScanner scanner, string match)\n        where TScanner : struct, IScanner\n    {\n        if (Tokens.Literal(match, ref scanner))\n        {\n            scanner.Advance(match.Length);\n            return true;\n        }\n        return false;","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs#L305-L341","documentation":"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.","triggerScenarios":"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.","commonSituations":"Library development: extending the float suffix list in Tokens.AnyOf but forgetting the mapping; custom scanners overriding matching behavior.","solutions":["Ensure every string in the AnyOf list ([f, f16, f32, f64, d, h]) has a matching case in the switch (LiteralParsers.cs:315-324).","If adding a new suffix (e.g. 'df'), add both the AnyOf entry and a Suffix case.","As a hardening measure, return a parse error instead of throwing so malformed suffixes produce a diagnostic."],"exampleFix":"// before\nvar matched = Tokens.AnyOf([\"f\", \"f16\", \"f32\", \"f64\", \"d\", \"h\", \"df\"], ...);\nsuffix = matched switch { \"f16\" or \"h\" => ..., _ => throw new NotImplementedException() };\n// after\nsuffix = matched switch\n{\n    \"f16\" or \"h\" => new(16, true, true),\n    \"f32\" or \"f\" => new(32, true, true),\n    \"f64\" or \"d\" or \"df\" => new(64, true, true),\n    _ => throw new NotImplementedException()\n};","handlingStrategy":"validation","validationCode":"var known = new[] { \"f\", \"f16\", \"f32\", \"f64\", \"d\", \"h\" };\nif (!known.Contains(candidate)) return false; // not a float suffix; let another parser try","typeGuard":"bool IsKnownFloatSuffix(string s) => s is \"f\" or \"f16\" or \"f32\" or \"f64\" or \"d\" or \"h\";","tryCatchPattern":"try { matched = parser.Match(ref scanner, result, out suffix); }\ncatch (NotImplementedException ex) { reportParseError(scanner.Location, \"Unknown float literal suffix\", ex); }","preventionTips":["Keep the AnyOf suffix list and the switch mapping in sync — change them together.","Add unit tests that drive the parser through every accepted suffix string.","On library upgrade, re-run literal parsing tests before shipping new suffix support."],"tags":["shader-parsing","lexer","literals","internal-invariant"],"backgroundTag":"internal-invariant-violation","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"}