Skip to main content
Version: Next

Diagnostics reference

This page mirrors the authoritative diagnostic catalogue in docs/diagnostics.md. Preserve these GS#### meanings when configuring suppressions, warning promotion, or tooling.

Every diagnostic emitted by gsc carries a stable GS#### identifier, a severity level, a human-readable message, and a source location (file, line, column). This document enumerates all identifiers so that project files can suppress or promote them using standard MSBuild properties.

Persistent managed references​

Code Severity Meaning Remedy 
GS0604 Error Invalid persistent-reference type, origin, permission, initialization, scoped escape, or suspension of a temporary borrow. Use an admitted GC-owned location and compatible runtime; initialize non-null handles on every path, weaken permissions explicitly, and evaluate suspending values before borrowing. Unknown borrowed storage is never copied into a replacement location. 
GS0605 Error A rich anonymous field with an omitted type has no unambiguous heap-storable inferred type. Add an explicit field type; nil, untyped lambdas/method groups, cycles, and ref-like values are not widened to object. 
GS0606 Error adapt[I](source) cannot produce a complete exact forwarding plan. Supply an interface target and a non-null admitted source whose accessible public instance members exactly match every required slot. Static abstract/virtual members and operators require a separate design. 

Severity levels​

Level Meaning 
Error Compilation cannot succeed; gsc exits with code 1. 
Warning Compilation succeeds; gsc exits with code 0 unless /warnaserror is in effect. 
Info Informational; never affects the exit code. 

Suppressing and promoting diagnostics​

gsc accepts the following command-line flags (all also available via the Gsharp.NET.Sdk MSBuild SDK through the matching MSBuild properties):

Flag MSBuild property Effect 
/nowarn:<ids> <NoWarn> Suppress the listed warning IDs. Errors cannot be suppressed. 
/warnaserror <TreatWarningsAsErrors>true</TreatWarningsAsErrors> Promote every warning to an error. 
/warnaserror+:<ids> <WarningsAsErrors> Promote only the listed IDs to errors. 
/warnaserror-:<ids> — Exempt the listed IDs from a global /warnaserror. 

IDs may be given as GS0001, 0001, or the bare integer 1; all three forms are equivalent.

Source-level, scoped suppression​

The flags above are whole-compilation. To turn an analyzer diagnostic, or a compiler warning, off for one declaration or one range of statements, annotate the source with @SuppressDiagnostic:

@SuppressDiagnostic("GSA0005")
func RewriteFieldAssignmentExpression(node BoundFieldAssignmentExpression) BoundExpression {
// GSA0005 is suppressed here, and nowhere else.
}

func Elsewhere() {
@SuppressDiagnostic("GSA0005", "GSA0007") {
// suppressed only inside these braces
}

// still reported here
}

The annotation is compiler-intrinsic: it names no type, needs no assembly reference, and is never written to metadata. Its scope is the span of the declaration or block it precedes; nesting adds identifiers and never removes them. An argument that is not a constant string shaped like a diagnostic ID is reported as GS9305.

The same scopes also filter the compiler's own GS#### diagnostics, in gsc, the language server and every EmitResult, but only warnings: as with C#'s #pragma warning disable, a compiler error cannot be suppressed. The check uses the diagnostic's own severity before /warnaserror promotion, so a suppressed warning stays suppressed under <TreatWarningsAsErrors>. cs2gs emits @SuppressDiagnostic("GS0612") where it drops a C# ! from a by-reference argument (ref x!), and for a #pragma warning disable CS8600/CS8601/CS8604/CS8620 region that covers a whole declaration.

Example .gsproj snippet:

<PropertyGroup>
<!-- suppress a noisy warning -->
<NoWarn>GS0168</NoWarn>
<!-- treat a specific warning as an error -->
<WarningsAsErrors>GS0176</WarningsAsErrors>
</PropertyGroup>

Diagnostic catalogue​

Lexer diagnostics (GS0001–GS0005)​

ID Severity Description Example trigger 
GS0001 Error Bad character input. Source contains a character that is not part of the GSharp alphabet (e.g. `). 
GS0002 Error Unterminated comment. A /* that has no matching */. 
GS0003 Error Unterminated string literal. A " that has no closing " before end-of-line or end-of-file. 
GS0004 Error Invalid number literal. 9999999999999999999 is out of range for int. 
GS0005 Error Unexpected token. Parser expected one token kind but found another (e.g. missing ) or ;). 

Binder / semantic diagnostics (GS0100–GS0189)​

Enum exhaustiveness. Enum switches cover named constants only. [Flags] does not add unnamed bit combinations as required switch arms. This rule is identical for imported CLR enums and source-declared enums. If a switch expression receives a value that matches no arm, compiled and interpreted execution fail with Unmatched switch expression value. instead of producing a default value.

ID Severity Description Example trigger 
GS0100 Error Not all code paths return a value. A non-void function is missing a return on some branch. 
GS0101 Error Parameter already declared. Two parameters share the same name. 
GS0102 Error Symbol already declared. A variable or function name is used twice in the same scope. 
GS0103 Retired Previously: a same-package receiver clause on a non-aggregate type (enum, interface, non-struct alias) was rejected. Every receiver clause is now an extension regardless of the receiver's owning package or kind, so any receiver type is now valid; this diagnostic is no longer emitted. — 
GS0104 Error Reserved; not currently emitted. Zero-field data class/data struct declarations are supported with trivial equality/hash/ToString/copy semantics and no synthesized Deconstruct. — 
GS0105 Error inline struct requires exactly one field. inline struct Foo { a int; b int } has two fields. 
GS0106 Error inline cannot be combined with data. inline data struct Foo { … } is not legal. (Historical: the record keyword was removed by; pre-removal this diagnostic also covered inline record.) 
GS0107 Error inline struct cannot be combined with open. open inline struct Foo { … } is not legal. 
GS0108 Error Inline struct synthesised member conflicts with an explicit declaration. An inline struct auto-generates certain member names that cannot be re-declared. 
GS0109 Error record was an alias for data struct and could not be combined with data. GS0307 replaces this on legacy sources. data record Foo { … } — use data struct Foo or data class Foo. 
GS0110 Error Empty enum declaration. enum Color {} — an enum must have at least one member. 
GS0111 Error Duplicate enum member. Two members in the same enum share a name. 
GS0112 Error Undefined enum member. Color.Purple where Purple is not a declared member of Color. 
GS0113 Error Undefined type. A type name referenced in code does not exist. 
GS0114 Error Invalid array length. Array length must be a non-negative integer literal. 
GS0115 Error Array literal length mismatch. [3]int{1, 2} — literal has 2 elements but length is 3. 
GS0116 Error Type is not indexable. x[0] where x is bool or another type with no array/slice/map element access and no CLR indexer. Arrays, slices, maps, CLR indexers, and Span[T] / ReadOnlySpan[T] are all indexable. 
GS0117 Error Invalid argument type for a built-in function. len(42) — len cannot be applied to an int. 
GS0118 Error A try statement requires at least one catch or finally clause. try { f() } with no catch or finally. 
GS0119 Error Type is not disposable. using x = Foo() where Foo provides no public Dispose() method. 
GS0120 Error Invalid break or continue. break used outside of a loop. 
GS0121 Error Invalid return. return used outside of a function. 
GS0122 Error Void function cannot return an expression. return 42 inside a function declared without a return type. 
GS0123 Error Missing return expression. return with no value inside a function that returns int. 
GS0124 Error Expression must have a value. A void call used in a value position (e.g. x = fmt.Println()), or an untyped local whose initializer never produces a value (let a = throw e, let a = if c { return 1 } else { return 2 }). 
GS0125 Error Variable not defined. x referenced before being declared. 
GS0126 Error Name is not a variable. len = 5 — len is a function, not a variable. 
GS0127 Error Variable is read-only. Assignment to a const or let-bound name. 
GS0128 Error Unary operator not defined for type. !42 — ! is not defined for int. 
GS0129 Error Binary operator not defined for types. true + 1 — + is not defined for (bool, int). 
GS0130 Error Undefined function. A call to a function name that was never declared. 
GS0131 Error Name is not a function. x() where x is an int variable. 
GS0132 Error await has no enclosing function to make suspending. await someTask where no enclosing function exists. A plain func may await: the await is a suspension point that colours the awaiting function — see GS0574/GS0575/GS0576 for the positions that reject it. 
GS0133 Error Expression is not awaitable. await 42 — int is not a Task or Task[T]. 
GS0134 Error Expression is not async-enumerable. await for x in 42 — int does not implement IAsyncEnumerable[T]. 
GS0135 Error async modifier in a type clause is only valid before sequence[T], (T) -> R, or func(...). async int in a type position. 
GS0136 Error yield outside an iterator function. yield return 1 in a function that returns int, not sequence[int]. 
GS0137 Error go operand is not a call expression. go x + 1 — only function calls may follow go. 
GS0138 Error defer operand is not a call expression. defer x + 1. 
GS0139 Error Receive operator <- requires a channel. <-42. 
GS0140 Error Send operator <- requires a channel on the left. 42 <- x. 
GS0141 Error close requires a channel operand. close(42). 
GS0142 Error select with no cases. select {} is unreachable. 
GS0143 Error select has more than one default arm. Two default: arms inside one select. 
GS0144 Error Wrong number of arguments to function. f(1, 2) when f requires three arguments. 
GS0145 Error Variadic parameter is not the last parameter. func f(a ...int, b string). 
GS0146 Error Variadic parameter only allowed on top-level function declarations. Variadic parameter on a closure or method. 
GS0147 Error Too few arguments for variadic function. Calling a variadic function with fewer than the minimum required arguments. 
GS0148 Error Generic function has wrong number of type arguments. f[int, string]() when f takes only one type parameter. 
GS0149 Error Type is not generic. int[string] — int accepts no type arguments. 
GS0150 Error Type-parameter variance position violation. A covariant type parameter used in a contravariant position. 
GS0151 Error Type argument inference failed. The compiler could not infer a type argument from the call arguments. 
GS0152 Error Type argument does not satisfy constraint. f[MyStruct]() where MyStruct does not implement the required interface constraint. 
GS0153 Error Constraint is neither an interface, a class, nor a type parameter. A generic type-parameter constraint must be an interface (any interface — sealed or not, generic or not;), a base class, or another type parameter ([TBase, TDerived TBase], C#'s where TDerived : TBase); a value type such as a struct or enum is rejected. 
GS0154 Error Wrong argument type. A free, instance, extension, or shared call argument has no permitted conversion to its parameter type. 
GS0155 Error Cannot convert type. Outside call-argument matching, no built-in or user-defined conversion exists; use a compatible value or an API that performs the transformation (for example, Parse/TryParse for text). 
GS0156 Error Cannot convert implicitly; explicit conversion exists. var x int32 = 3.14 — write var x int32 = int32(3.14) to apply the available explicit conversion. 
GS0157 Error Cannot find type (possibly missing import). A package-qualified type name that resolves to nothing. 
GS0158 Error Cannot find member. A field or property access that does not resolve. 
GS0159 Error Cannot resolve function call. A function name does not resolve, or its nullable receiver lacks valid non-null narrowing. 
GS0160 Error Ambiguous overload. A call that matches more than one overload equally well. Generic candidates are filtered against their where-constraints; the constraint-disjoint case usually resolves to one candidate, but two candidates with mutually-incomparable constraint specificity remain ambiguous and report this code. 
GS0161 Error copy/with receiver is not a data struct. .copy(…) used on a plain struct. 
GS0162 Error Named arguments only supported for data struct .copy(…). Named arguments passed to a regular function. 
GS0163 Error Deconstruction field count mismatch. let (a, b) = p where p is a data struct with three fields. 
GS0164 Error Deconstruction requires a tuple, data struct, or accessible Deconstruct method. Deconstruction attempted on a type without a supported deconstruction shape. 
GS0165 Error Top-level statements may appear in at most one package per compilation. Two or more package declarations in a single compilation each contain top-level statements. 
GS0166 Warning Top-level statements conflict with an explicit Main function. Both top-level statements and a func Main() are present; TLS wins and the explicit Main is shadowed. 
GS0167 Error Multi-assignment target/value count mismatch. a, b = 1, 2, 3 — three values for two targets. 
GS0168 Error fallthrough must be the last statement of a switch case body. fallthrough followed by more statements in the same case body (a trailing fallthrough is legal Go-style control flow). 
GS0169 Error Duplicate default arm in switch. Two default: arms inside one switch statement. 
GS0170 Error Switch case value is not a constant expression. case x: where x is a mutable variable. 
GS0171 Error Switch case type is incompatible with the switch expression. switch (s) { case 42: } where s is string. 
GS0172 Error Property pattern requires a struct or class value. A property pattern { Field: value } applied to a non-struct/class type. 
GS0173 Error Undefined field on type. Accessing a struct field that was never declared. 
GS0174 Error Relational pattern operator not defined for type. case > 5: where the switched type doesn't support >. 
GS0175 Error List pattern requires an array or slice. List pattern [a, b] applied to a non-array/slice value. 
GS0176 Error Switch expression is missing a default arm. A switch expression that cannot be proven exhaustive and has no default. 
GS0177 Error Switch expression on enum is not exhaustive. One or more named enum constants not covered and no default arm. 
GS0178 Error Switch statement on enum is not exhaustive. One or more named enum constants not covered and no default arm. 
GS0179 Error Switch expression arm type mismatch. Different arms of a switch expression produce incompatible types. 
GS0180 Error Accessibility modifier not allowed here. pub or priv used on a local variable or inside a function body. 
GS0181 Error Base class is not open. Inheriting from a class that was not declared open. 
GS0182 Error Method is overridable; override required. Redefining an open method without the override keyword. 
GS0183 Error No matching open base method for override. override keyword present but no base class defines a matching open method. 
GS0184 Error Cannot override a non-open base method. override targets a method that was not declared open. 
GS0185 Error Override signature mismatch. An override method has different parameter types or return type than the base. Also an override property whose by-ref return does not match the base slot's: ref may only override ref, and by-value only by-value. 
GS0186 Error (historical — removed) Interface method may not have a body. Default-interface methods are now supported (see GS0318–GS0321). 
GS0187 Error Class or struct does not implement interface method. A class or struct claims to implement an interface but a required method is absent. 
GS0188 Error Class or struct cannot implement a sealed interface from a different package. A class or struct implements a sealed interface defined outside its package. 
GS0189 Error The return type of an async func(...) type clause is implicitly wrapped in Task; do not write Task[…] explicitly. async func(int) Task[int] in a type position. 

Async state-machine diagnostics (GS0190)​

ID Severity Description Example trigger 
GS0190 Error Async state machine unavailable for this function. An async func uses a language feature that the GSharp async emitter does not yet support (e.g. await inside a nested try block). 

Character literal diagnostics (GS0191–GS0195)​

ID Severity Description Example trigger 
GS0191 Error Unterminated character literal. A ' that has no closing ' before end-of-line. 
GS0192 Error Empty character literal; a character literal must contain exactly one code unit or escape. '' with nothing inside. 
GS0193 Error Character literal contains more than one code unit; use a string literal instead. 'ab'. 
GS0194 Error Unrecognised escape sequence in character literal. '\q'. 
GS0195 Error Malformed Unicode escape in character literal. '\u00G0'. 

Attribute / annotation diagnostics (GS0196–GS0211)​

Kotlin-style attribute syntax (@Foo(...)) and the @Attribute declaration sugar. The following diagnostics cover parsing, resolution, use-site validation, and the compiler-recognised attribute set.

ID Severity Description Example trigger 
GS0196 Error Annotation name expected after @. @ func Foo() {} — bare @ with no identifier. 
GS0197 Error Annotation target is not a recognized use-site kind. @bogus:Foo func Bar() {} — must be one of field, param, return, type, method, property, event, module, assembly, genericparam. 
GS0198 Error Attribute type could not be found. @DoesNotExist func Foo() {} — neither DoesNotExist nor DoesNotExistAttribute resolves to a type. 
GS0199 Error Attribute name is ambiguous between Foo and FooAttribute. Both types are in scope; qualify to disambiguate. 
GS0200 Error Type is not an attribute class (it does not derive from System.Attribute). @int func Foo() {}. 
GS0201 Error Attribute target is not valid at this position. @field:Obsolete func Foo() {} — field is not allowed on a function. 
GS0202 Error Attribute arguments must be compile-time constants. @Trace(myVar) — argument is not a primitive, string, typeof, enum, or 1-D array thereof. 
GS0203 Error Class tagged @Attribute cannot also declare an explicit base class. @Attribute class Trace : Other {} — the @Attribute sugar implies : System.Attribute. 
GS0204 Warning (Error if IsError=true) Reference to a symbol marked [Obsolete]. Calling a function, instantiating a class (Old(5)), writing a struct literal (Old{}), naming a struct/class/interface/enum in a type clause, reading an obsolete parameter, reading/writing an obsolete var/let/const, reading an obsolete enum member (Color.Red), or reading/writing an obsolete struct/class field (p.Old) — all declared with @Obsolete("use Bar"). Severity is promoted to error when the attribute's second argument is true. 
GS0205 Error Attribute is reserved for compiler synthesis. @CompilerGenerated, @Extension, @AsyncStateMachine, @Nullable, or @NullableContext written in user source. 
GS0206 Error Annotations are only allowed on variable declarations, not on this statement. @Obsolete\nreturn inside a function body — annotations may precede var/let/const but no other statement kind. 
GS0207 Error Parameter {name} is annotated @EnumeratorCancellation but has type {type}; only System.Threading.CancellationToken parameters can carry this annotation. @EnumeratorCancellation placed on a string parameter. 
GS0208 Error Parameter {name} is annotated @EnumeratorCancellation but its enclosing function is not an async sequence (does not return IAsyncEnumerable[T]). @EnumeratorCancellation on a sync function or a non-sequence async function. 
GS0209 Error Attribute {name} is not valid on this position; its [AttributeUsage] permits only: {targets}. Applying a @field-targeted attribute to a method. 
GS0210 Error Duplicate attribute {name}; this attribute type does not allow multiple applications (AllowMultiple = false). Two @Trace(...) annotations on the same declaration. 
GS0211 Error (repurposed) Attribute [DllImport] was historically rejected wholesale; well-formed @DllImport-annotated P/Invoke declarations are now accepted (see GS0322–GS0329 for shape-specific diagnostics). The slot is reserved for any future blanket-rejection use. n/a — no longer fired. 
GS0212 Error Function {name} is marked @Conditional but does not return void; conditional methods must return void because calls may be elided at the call site. @Conditional("DEBUG") func Probe() int32 { return 0 }. 

Class / constructor diagnostics (GS0213–GS0217)​

User class constructor flow — explicit init(...) constructors, primary constructors, and base(...) initializers.

ID Severity Description Example trigger 
GS0213 Error A base-constructor argument list requires an explicit base class. init() : base(1) { } written on a class with no : BaseType clause. 
GS0214 Error Class {base} has no accessible constructor that takes {N} argument(s). init() : base(1, 2) when the base only declares init(). 
GS0215 Error Class {name} cannot declare both a primary constructor and an explicit init constructor. class Customer(id int32) { init(name string) { } }. 
GS0216 Error Class {name} declares multiple init constructors; only a single explicit constructor is supported. Two init(...) declarations in the same class body. 
GS0217 Retired Previously: generic class with an explicit init constructor cannot be constructed. Generic classes with explicit init(...) constructors are now supported; this diagnostic is no longer emitted. — 

Delegate conversion diagnostics (GS0218)​

ID Severity Description Example trigger 
GS0218 Error Cannot convert method group {name} to {type}. No overload matches the target delegate signature. var a Action = SomeOverloaded where no overload of SomeOverloaded has signature () -> void. 

String interpolation diagnostics (GS0220–GS0225)​

Interpolation holes (${expr,alignment:format}) and the interpolated-string-handler pattern report the following.

ID Severity Description Example trigger 
GS0220 Error Interpolation alignment clause is not a constant integer. "${x,abc}" — the value after the , in ${expr,alignment[:format]} must be a constant integer (e.g. ${x,5} or ${x,-8:X4}). 
GS0221 Error An interpolated string passed to an [InterpolatedStringHandler] parameter could not satisfy [InterpolatedStringHandlerArgument] forwarding. The forwarded argument names an unknown parameter, the receiver cannot be forwarded, or no handler constructor matches (int, int, …forwarded[, out bool]). 
GS0222 Error Unterminated interpolation hole; expected a closing }. "v=${a + b" — the ${ opens a hole that the delimiter-aware scanner never closes before end of file. 
GS0223 Error Empty interpolation hole; expected an expression between ${ and }. "x=${}" — a hole must contain an expression. 
GS0224 Error Empty format specifier; expected a format string after :. "${n:}" — a : clause must be followed by a non-empty format string. 
GS0225 Error Newline in the literal portion of an interpolated string; only ${ … } holes may span lines. A raw newline appears outside a hole, e.g. a "… opened on one line with no closing " before the line break. (Multiline holes themselves are legal.) 

Note: originally proposed GS0212–GS0216 for the malformed-hole diagnostics, but those codes were already taken; the implemented codes are GS0222–GS0225.

By-ref-like (ref struct) diagnostics (GS0219)​

A by-ref-like type — a CLR ref struct carrying System.Runtime.CompilerServices.IsByRefLikeAttribute, such as System.Span[T], System.ReadOnlySpan[T], or System.Runtime.CompilerServices.DefaultInterpolatedStringHandler — is stack-only. G# permits declaring and using such a value as an ordinary local, but the CLR forbids any use that would let it reach the heap. Those escapes are rejected with GS0219.

G# can also declare its own by-ref-like value types with a ref modifier on a struct declaration:

ref struct Window {
Items ReadOnlySpan[int32] // a ref struct may hold by-ref-like fields
Label string
}

Such a type is emitted with System.Runtime.CompilerServices.IsByRefLikeAttribute (and the C# compiler's [Obsolete] guard marker), so the CLR treats it as stack-only. The same escape rules below apply to user-declared ref struct types exactly as they do to imported ones. The only relaxation is that a ref struct may itself hold by-ref-like fields (it is stack-only too); a static field of a ref struct is still rejected.

ID Severity Description Example trigger 
GS0219 Error A by-ref-like (ref struct) value is used in a position that would let it escape the stack: boxing / converting it to a reference type (object, an interface, a delegate base), storing it in a field of a non-ref-struct (instance, primary-constructor, or static — including an auto-property's compiler-synthesized backing field), capturing it in a closure, declaring it as a local in an async function or an iterator (where it would be hoisted into the heap-allocated state machine), using it as a generic type argument, or returning it from a function when its value scope is explicit or implicitly scoped. A ref parameter of ref-struct type is implicitly value-scoped; use @UnscopedRef only when its value may intentionally escape. var o object = span (box); a class/struct field typed Span[int32]; struct X { prop Values Span[int32] } (auto-property backing field); ref struct X { shared { prop Values Span[int32] } } (static backing field); capturing a ReadOnlySpan[char] local inside func() { ... }; declaring a Span[int32] local in an async function; List[ReadOnlySpan[int32]]; func f(ref s Span[int32]) Span[int32] { return s } — add @UnscopedRef to opt out. 

A computed property of a by-ref-like type is fine — it has no backing field, so nothing reaches the heap — and so is an instance auto-property inside a ref struct. Indexers cannot reach this rule at all: G# has no auto-indexer form (a bodiless indexer is GS0371), so an indexer never synthesizes a backing field.

The scoped modifier can be placed on a parameter to indicate that the ref struct (or managed-pointer) value must not be returned or stored beyond the call site:

import System
// `scoped` means `s` cannot be returned or escape.
func firstElement(scoped s ReadOnlySpan[int32]) int32 {
return s[0]
}

Span element access diagnostics (GS0226)​

/§2 makes spans indexable: a Span[T] / ReadOnlySpan[T] indexer returns a managed pointer (ref T / ref readonly T), and a read in rvalue position auto-dereferences to the pointee T (§1). A Span[T] element write span[i] = v stores through the ref T. A ReadOnlySpan[T] element is ref readonly T, so writing through it is a hard error (GS0226); reading it is always permitted.

ID Severity Description Example trigger 
GS0226 Error Cannot assign through a read-only span element (ReadOnlySpan[T] is read-only). var s ReadOnlySpan[int32] = arr then s[0] = 1 — a ReadOnlySpan[T] indexer is ref readonly T; use Span[T] to write. 

Pointer / by-ref diagnostics (GS9001–GS9011)​

ID Severity Description Example trigger 
GS0586 Error Generic local function requires a lexical owner whose direct generic-local hosting is unsupported. A generic local inside a generic class takes a closed private method group or creates a nested literal requiring that class's generic access domain. Use a named member or an owner-independent helper. 
GS0587 Error The extension keyword before a receiver clause is retired; every receiver clause now declares an extension. Remove extension. func extension (c Color) Rank() int32 { ... } — drop extension: func (c Color) Rank() int32 { ... } means exactly the same thing. 
GS0588 Error A ref-returning function cannot be converted to a delegate or function-type value; call it directly instead. A ref-returning function LITERAL is only supported as let name = func (...) ref T { ... }, a directly-callable local function. let at = func(xs []int32, i int32) ref int32 { return ref xs[i] } followed by let cb = at (bare-name delegate conversion), or passing a func (...) ref T { ... } literal as an argument, or var at = func (...) ref T { ... } (only a let local-function declaration is the direct-call shape). 
GS0589 Error A struct member cannot return a reference to its own instance state; this is implicitly scoped. Mark the member @UnscopedRef (import System.Diagnostics.CodeAnalysis) to allow it (the CS8170 analogue). struct Acc { var Total int32; func slot() ref int32 { return ref this.Total } } — add import System.Diagnostics.CodeAnalysis and @UnscopedRef above func slot. 
GS0590 Error @UnscopedRef is invalid where no ref-scope contract exists. An interface implementation may not add it unless its selected slot has it; an override is checked only when its signature is ref-safety-relevant. @UnscopedRef on a receiver-clause func, free function, class member, shared member, private interface helper, by-value parameter, or explicitly scoped parameter; on any annotated implementation of an unannotated interface slot; or on an annotated ref-safety-relevant override of an unannotated slot. 
GS0591 Error Cannot return a reference obtained through a read-only receiver (an in parameter, a ref readonly alias, or a ref readonly result): the receiver is defensively copied into function-local storage before the call, so the returned reference would point into that copy (the CS8156 analogue). func fromIn(in a Acc) ref readonly int32 { return ref a.Slot() } where Slot is @UnscopedRef — take the receiver by ref instead of in, or return the value. 
GS0592 Error A tuple-destructuring arrow-lambda parameter pattern requires at least two elements — G# has no 1-tuples. let f = ((x int32)) -> x — add a second element, or use an ordinary parameter ((x int32) -> x) instead. 
GS0607 Error partial is not valid here; only a func member of a partial class or partial struct (including a data class or data struct) may be partial. partial prop P int32 { … }, partial func F() at top level, partial func on an interface member, or a partial method with a receiver clause or explicit-interface qualifier (partial func (IFoo) Bar()) — all out of scope. 
GS0608 Error A partial method must be declared inside a partial class or partial struct, including a data class or data struct (the C# CS0751 analogue). class A { partial func F() int32; … } — mark the enclosing type partial. 
GS0609 Error A partial method has no implementing part; every partial method declared in G# must be implemented by exactly one part with a body. G# deliberately diverges from C#, which silently elides an unimplemented void partial method and its call sites. partial class A { partial func F() int32; } with no second part — add the implementing part, or drop partial and give the declaration a body. 
GS0610 Error A partial method must have exactly one signature-only declaring part and one implementing part with a body. Two parts that both have bodies, two parts that are both signature-only, or an implementing part with no declaring part (the C# CS0759 analogue). 
GS0611 Error The declaring and implementing parts of a partial method disagree on some aspect of the signature — return type, parameter names/modifiers, accessibility, open/override, async/suspend, ref return, or type parameters; also a return or parameter type whose IDENTICAL spelling resolves to two different types across the two files' imports. A textually different parameter type never reaches GS0611: the grouping key treats it as a distinct, unmatched overload and reports GS0609/GS0610 instead. partial func F(x int32) int32; paired with partial func F(y int32) int32 { … } — the parameter names differ. 
GS0612 Warning A by-reference argument's storage type differs from the parameter type only in reference nullability (the C# CS8620/CS8601 analogue). The storage is shared, so a nil can flow through it: the warning fires for any difference at a ref parameter, for nullable storage at a non-null in parameter, for a nullable out parameter over non-null storage, and for any nested difference (List[string?] against List[string]). A platform (T!) position never warns. GS0612 reads declared types, not C#'s flow state, so it can fire where csc is silent (a string? local that holds a non-nil value). A value-type int32? is a different runtime type and is GS0154, not GS0612. Suppressible with @SuppressDiagnostic("GS0612"). var s string? = nil then f(&s) where f(ref s string) — give the storage the parameter's type, or narrow into a non-null local first. 
GS0613 Error A named attribute argument selects neither a constructor parameter nor a writable public property or field. Correct the name; use name: value for a constructor parameter or Name = value for a property/field. 
GS0614 Error A named attribute argument's constant value is not assignable to the selected property or field type. Supply a constant of the member's declared type. 
GS0615 Error A selected named attribute property or field has a type that cannot be encoded in a CLR custom-attribute blob. Change the attribute member to a primitive, string, System.Type, object, enum, or one-dimensional array thereof. 
GS0616 Error An attribute constructor argument appears after a property or field assignment. Move every positional or name: value constructor argument before all Name = value member assignments. 
GS0617 Error A shared class declares an init(…) constructor, a primary constructor, a deinit, a shared { } block, or an open or override method, property or event. A shared class has only shared members, declared directly in its body, and a shared member is never virtual; remove the declaration or modifier, or drop shared. 
GS0618 Error shared is combined with open, sealed, abstract or data. A shared class is neither inheritable nor instantiable; remove the conflicting modifier. 
GS0619 Error A shared class lists a base class or an interface. Remove the base-type clause, or drop shared. 
GS0620 Error An explicit abstract property has a non-abstract owner, a private required accessor, a body or bare auto-property form, or a conflicting open or explicit-interface modifier. Declare an abstract class and a non-private, bodyless accessor list; use abstract override prop to reabstract a base slot. 
GS0621 Error A property that replaces a positional data member has no getter. Add a getter so the positional value remains readable. 
GS0622 Error A positional member follows a braced or content initializer in a composite literal. Move positional members before composite elements so constructor arguments keep source evaluation order. 
GS0623 Error A data class or struct declares PrintMembers(StringBuilder) with a shape other than an instance, non-generic, synchronous (neither async nor suspend) method returning bool whose accessibility is private (a sealed type that starts the slot) or protected, marked override exactly when the type has an inherited slot. A compatible PrintMembers replaces the synthesized one; remove it to use the synthesized print members, or fix its shape. 
GS0624 Error A guard leaves a bool initializer, or assignment/coalescing/ternary conversion hides the boolean in a nullable result. Parenthesize the entire initializer to make the boundary explicit: if let v = (a && b ? x : y) or if let v = (cached = a && b). 
GS0625 Error A guard let or while let has a && guard after its bindings. Only if let accepts a guard. Test the condition in a separate statement, or parenthesize the initializer if the && belongs to it. 
GS0626 Error A top-level || follows the bindings of an if let, guard let or while let. Only && introduces a guard. Parenthesize the initializer if the || belongs to it. 
GS9001 Error Cannot take the address of a non-lvalue. &(1 + 2) — the operand is a temporary expression. 
GS9002 Error Argument must be passed by ref. A ref parameter called without the ref modifier. 
GS9003 Error Variable not definitely assigned before ref use. ref x where x has not been assigned. 
GS9004 Error By-ref value cannot escape its declaration scope. Returning a *T (managed-pointer) value from a function, capturing a *T local in a closure, hoisting a *T local into an async/iterator state machine, or using a *T return type in a function literal. Also raised when returning a ref struct parameter annotated as scoped. 
GS9005 Error Cannot take the address of a constant. &myConst where myConst is declared const. 
GS9006 Error Pointer type cannot be a field type. A struct or class field (including static shared fields and top-level globals) declared with a *T (managed-pointer) type outside an unsafe context. Inside an unsafe context *T is an unmanaged pointer and IS legal as a field type. 
GS9009 Error Readonly storage cannot be passed to a writable ref or out parameter. An imported ref/out parameter receives the readonly address in view. 
GS9010 Error A ref/out/in parameter of the enclosing function cannot be captured by a closure because the closure may outlive the caller's argument. func Foo(ref x int32) { let Bad = func(a int32) int32 { x = x + 1; return a } } — Bad captures the ref parameter x. 
GS9011 Error A ref/var ref LOCAL alias of the enclosing function cannot be captured by a closure because the closure may outlive the storage it aliases. func Foo() { var arr = []int32{1}; var ref alias = arr[0]; var f = func() { alias = alias + 1 } } — f captures the ref-alias local alias. 
GS0398 Error Unmanaged pointer to a non-blittable pointee. An unsafe-context *T whose pointee T is a managed reference type or otherwise non-blittable (e.g. *string, or a struct with a managed field); only blittable primitives, pointers-to-pointers, and blittable user/value structs are legal pointees. 
GS0399 Error stackalloc element type must be a blittable (unmanaged) type. A stackalloc [n]T whose element type T is a managed reference type or otherwise non-blittable (e.g. stackalloc [4]string); only blittable primitives and pointers are legal stackalloc element types. 
GS0400 Error A fixed statement requires an unsafe context. A fixed <name> *T = <source> {... } statement used outside an unsafe context (function, unsafe {... } block, or unsafe type). Because it binds a raw unmanaged pointer, fixed is legal only inside unsafe, consistent with *T pointer gating. 
GS0401 Error A fixed statement source is not pinnable, or the pointer's element type does not match. The source of a fixed statement must be a managed array/slice ([]T), a string, a span-like type exposing a public instance ref T GetPinnableReference() (e.g. System.Span[T] / System.ReadOnlySpan[T]), or a fixed-size buffer field of a variable, and the bound pointer's pointee type must match the buffer's element type (uint16/char interchangeable for string). Reported for a non-pinnable source (e.g. a scalar, a type without GetPinnableReference, or a fixed-size buffer of a call result) or a pointee/element-type mismatch. A fixed-size buffer reached through an already-fixed variable reports GS0507 instead. 
GS0402 Error The operand of an increment/decrement operator must be writable storage or a writable ref-returning call. A prefix or postfix ++/-- applied to something that is not writable storage, e.g. 5++, (a + b)--, or a by-value function-call result. Mutable variables, fields, properties, indexed elements, pointers, and writable ref-returning calls are valid targets. 
GS0403 Error Cannot dereference, index, or perform arithmetic on a void pointer *void. A true void-element pointer *void (C# void*) carries no element type, so *p, p[i], p + i, p - i, and p - q are rejected; cast it to a typed pointer *T (e.g. *int32(p)) first. Casts to/from typed pointers and nint, and comparison/equality, are allowed. 
GS0404 Error A managed function-pointer type *func(...) R requires an unsafe context. A managed function-pointer type clause *func(T1, T2) R used outside an unsafe context; like the raw pointer *T, a function pointer is only legal inside unsafe. 
GS0405 Error Cannot take the address of this method as a function pointer. &Method where the operand is not a single static/free, non-generic method (e.g. an instance method, an overloaded method group, or a generic method), or it is used outside an unsafe context. 
GS0406 Error A fixed-size buffer field fixed name [N]T requires an unsafe context. A fixed name [N]T buffer field declared in a non-unsafe struct; declare it inside an unsafe struct. 
GS0407 Error A fixed-size buffer field must have a fixed-length array element type [N]T. A fixed name <T> field whose type clause is not a fixed-length array [N]T. 
GS0408 Error A fixed-size buffer field must have a positive length. A fixed name [N]T field with N <= 0. 
GS0409 Error Fixed-size buffer element type is not supported. A fixed name [N]T field whose element type is not a blittable primitive (bool, int8…int64, uint8…uint64, char, float32, float64). 
GS0411 Error A count-inferred stackalloc []T requires an initializer. A count-inferred stackalloc []T written without a brace-delimited initializer, so its length is undeterminable (e.g. stackalloc []int32). Supply an initializer (stackalloc []int32{1, 2, 3}) or spell the count explicitly (stackalloc [n]T). 
GS0412 Error A stackalloc [n]T{…} initializer length must match the explicit count. A stackalloc [n]T{…} whose explicit constant count n disagrees with the number of initializer elements (e.g. stackalloc [2]int32{1, 2, 3}). As in C#, the two must match; use the count-inferred stackalloc []T{…} to avoid repeating the length. 
GS9007 Error A type may contain at most one shared block. A class or struct with two shared { ... } blocks; merge them into one. 

Native slice diagnostics (GS0600–GS0603)​

Code Severity Meaning Remedy 
GS0600 Error Native slices require compatible Gsharp.Runtime.Values support and the .NET 10 target. Use the matching SDK runtime reference; no fallback to arrays occurs. 
GS0601 Error Invalid native-buffer type, element, sharing conversion or literal shape. Supply one heap-storable element type, preserve element nullability when sharing, and use positional literal elements (AppendRange for ranges). 
GS0602 Error A selected native element/value-field write would suspend while its location is borrowed. Evaluate the suspending value before selecting the element. Ordinary async slice values and segment-local borrows are supported. 
GS0603 Error A store requires writable elements but its descriptor is readonly slice[T]. Use a writable alias or explicitly clone; readonly views are not deep immutable copies. 

Reference closure diagnostics (GS9100)​

ID Severity Description Example trigger 
GS9100 Warning One or more assemblies supplied via /r: depend (transitively) on assemblies that were not also supplied, so the reference set is not a complete transitive closure. The compiler degrades gracefully — members whose signatures live in the missing assemblies are skipped rather than aborting the build — but the affected members become invisible. The message names the missing assemblies. Add the missing package/project reference (the SDK passes @(ReferencePathWithRefAssemblies), MSBuild's full transitive closure, so this normally only appears with a hand-rolled /r: set). Suppress with /nowarn:GS9100. gsc /r:LibAsmA.dll app.gs where LibAsmA.dll references DepAsmB.dll and DepAsmB.dll is not also passed. 

Analyzer host diagnostics (GS9300–GS9319, reserved)​

The GS9300–GS9319 block is reserved for the G# analyzer framework host: gsc loading and running GSharpDiagnosticAnalyzer assemblies passed via /gsanalyzer:.

ID Severity Description 
GS9300 Warning An analyzer threw an exception; it is disabled for the remainder of the compilation. The message names the analyzer type and the exception. 
GS9301 Error An analyzer assembly passed via /gsanalyzer: failed to load or contains no analyzers. 
GS9302 Info An analyzer exceeded its time budget in an interactive host and was disabled for subsequent runs. 
GS9303 Warning An analyzer was built against a different GSharp.Core version than the host; the load is attempted anyway. 
GS9304 Warning An analyzer reported a diagnostic whose ID is not declared in its SupportedDiagnostics; the diagnostic is suppressed. 
GS9305 Error @SuppressDiagnostic was given an argument that is not a constant string shaped like a diagnostic ID, or no argument at all. 
GS9306 Error @ExtensionOwner, synthesized by cs2gs to preserve a migrated C# static extension class's CLR owner-type identity, was used outside the one shape it supports: a top-level extension function carrying a single typeof(T) argument naming a non-generic class declared in the same package. 
GS9307 Error @Oblivious / @NullabilityEnabled was written in a shape it does not support: with arguments, with a target specifier, or both annotations on the same declaration. Neither takes arguments; the nearest annotation decides whether the unadorned reference types written inside it are oblivious (T!). 

Source-generator host diagnostics (GS9200–GS9219)​

The GS9200–GS9219 block belongs to gsgen, the Roslyn source-generator host. gsgen runs before gsc, and the SDK relays its diagnostics into the build; an error fails the build. A generator's own diagnostics keep the generator's IDs (for example SYSLIB1043).

ID Severity Description 
GS9200 Error gsgen failed outright: an invalid response file, a missing input file, or an unexpected exception. The message carries the reason. 
GS9201 Reserved Reserved: parse-fatal G# input. 
GS9202 Reserved Reserved: the C# stub rendered from the G# declarations did not re-parse (a host bug). 
GS9203 Warning A generator threw, or its assembly could not be loaded. That generator's output is skipped and the others still run. 
GS9204 Info A G# type in a declaration signature has no C# spelling in the stub, so generators see it as object. 
GS9205 Reserved Reserved: analyzer assembly load failure (reported as GS9203 today). 
GS9206 Reserved Reserved: a generator matched nothing although its trigger attribute appears in user code. 
GS9207 Info A note about the gsgen invocation, such as an unrecognized or malformed argument that was ignored. 
GS9208 Error A generated implementing part of a partial method could not take its declaring part's header. It is reported at the declaring part in two cases. First, the generated implementation names a parameter differently: its body uses the generated names, so the header is left as generated and gsc reports the two parts as mismatched. Second, an alias the header needs is already bound to a different target in the generated file: either by the generated code, or by another file's declaring part whose header went into the same file. Give the alias one meaning across the partial class's files, or spell the type without it. 
GS9209 Error A generator declared a positional parameter list on a G# data class or data struct that already has one (partial data types). Only one part of a data type may state it, so the generated part keeps its list and gsc also reports the two parts (GS0482). It is reported at your positional list. Remove your list if the generator is meant to supply it. 

Internal diagnostics (GS9996–GS9999)​

These diagnostics indicate a fatal compiler or runtime execution failure. If you encounter them, please file an issue.

ID Severity Description 
GS9996 Error Source generator execution failure. gsc could not locate or launch gsgen, gsgen timed out, or it exited nonzero without producing its own diagnostics. 
GS9997 Error Fatal compiler I/O error. An unrecoverable file-system error occurred (permission denied, disk full, etc.) before or during assembly writing. 
GS9998 Error Internal compiler error (emit-time failure). The emit pipeline encountered an unexpected state and could not produce valid IL. The diagnostic message includes the exception type and a brief description of the failure. 
GS9999 Error Historical: an unexpected exception caught by the tree-walking evaluator. No product driver produces it; the emitted test oracle synthesizes it as the assertion surface for uncaught runtime exceptions. 

Interpreter compiled-only boundaries (retired)​

Storage-dependent unsafe constructs were compiled-only in the former tree evaluator (GS0513 for unmanaged &/*, plus legacy GS9999 guards). The evaluator and its diagnostics have been deleted: every driver executes emitted code, where these constructs run natively.

Documentation diagnostics (GS0227–GS0231)​

Code Severity Message 
GS0227 Warning Documentation comment is not attached to a declaration. 
GS0228 Warning Missing documentation comment on public member {name}. (opt-in) 
GS0229 Warning Documentation @param {name} does not match any parameter of {symbol}. 
GS0230 Warning Unsupported documentation Markdown: {detail}. 
GS0231 Warning Unknown documentation tag {tag}. Valid tags are: @param, @typeparam, @returns, @remarks, @value, @exception, @seealso. 

Data struct diagnostics (GS0232)​

Every data struct synthesizes a fixed contract of value-semantics members — Equals(object), Equals(Name), GetHashCode(), ToString(), op_Equality(Name, Name), op_Inequality(Name, Name), and Deconstruct(out T1, out T2, …). Hand-written versions are rejected so the contract stays predictable and so consumers (G# and external.NET) can rely on the synthesized IL.

Update. ToString is no longer the Kotlin Name(F=v) form with the invariant culture; it is the C# record format Name { F = v } with the current culture, built around a synthesized PrintMembers(StringBuilder), and every data type implements IEquatable<Self>. A hand-written ToString (GS0487) or PrintMembers (GS0623) of the compatible shape replaces the synthesized member. Deconstruct, equality and hashing are unchanged. Known gaps: #4876 (GS0387 over an abstract PrintMembers), #4877 (imported non-data intermediary), #4874 (cs2gs duplicates a repeated base parameter).

Code Severity Message 
GS0232 Error Data struct {type} synthesizes member {member}; it cannot be declared explicitly. 

Named delegate type diagnostics (GS0233)​

delegate Name(parameters) ReturnType; declares a real CLR MulticastDelegate-derived named delegate type so C# consumers see a conventional handler type and G# events can carry first-class custom delegate types. Generic declarations such as delegate Predicate[T any](value T) bool; emit a generic delegate TypeDef, so the former GS0234 ("generic delegate declaration not yet supported") has been retired. GS0233 applies only while recovering a malformed legacy declaration; GS0535 rejects the retired type Name = delegate func(...) spelling.

Code Severity Message 
GS0233 Error Named delegate declaration requires 'func(...)' after 'delegate' (retired type Name = delegate … recovery form only; the canonical spelling is delegate Name(params) ReturnType; — see GS0535). 

Ref-kind parameter diagnostics (GS0235–GS0243)​

G# supports explicit ref, out, and in parameter passing modes at both call sites and method-definition sites. These diagnostics cover modifier mismatches, assignment requirements, and invalid parameter shapes. The async/iterator ban reuses the existing GS0226 family.

Code Severity Message 
GS0235 Error Argument {index} (parameter {name}) passes with ref-kind {actual} but the parameter is declared {expected}. 
GS0236 Error An 'out var/let/_' inline declaration is only valid on an 'out' argument. 
GS0237 Error Cannot assign to 'in' parameter {name} — it is read-only. 
GS0238 Error The 'out' parameter {name} must be assigned on every path before the function returns. 
GS0239 Error The variable {name} must be definitely assigned before it can be passed by 'ref'. 
GS0240 Error Override of {name} must match the base ref-kind on parameter {parameter} ({baseKind} vs {overrideKind}). 
GS0241 Error A variadic parameter cannot carry a ref-kind modifier ('ref'/'out'/'in'). 
GS0242 Retired Previously: an argument written without in at an in parameter was rejected. It is now passed by readonly reference, as in C# — the address of an lvalue of the parameter type, otherwise the address of a readonly temp holding the (implicitly converted) value; this diagnostic is no longer emitted. 
GS0243 Error A pointer type '*T' is not a valid parameter type; use the appropriate ref-kind modifier instead (e.g. 'ref T', 'out T', 'in T'). 

Cause/fix examples:

  • GS0235 — fire when the call-site modifier doesn't match the declaration: f(x) where f(ref x int32) requires f(&x) or f(ref x). Fix: add the matching modifier; if the parameter is by-value, drop any unwanted ref/out/in.
  • GS0236 — out var n outside an out argument: e.g. func g(int32) {} then g(out var n). Fix: only use the inline declaration when the parameter is declared out.
  • GS0237 — assignment to an in parameter inside the body: func h(in p int32) { p = 0 }. Fix: copy to a local for any mutation, or change the parameter to ref.
  • GS0238 — a missing write before return on an out parameter: func k(out r int32) bool { if cond { r = 1; return true } return false } — the false branch fails to assign r. Fix: assign on every path.
  • GS0239 — passing an uninitialized variable by ref: var x int32; f(ref x) with no prior assignment. Fix: assign before the call (e.g. var x = 0).
  • GS0240 — override changes the ref-kind of an inherited parameter: func override f(in p int32) { … } when the base declares f(ref p int32). Fix: match the base declaration.
  • GS0241 — variadic combined with ref-kind: func g(ref values ...int32) {}. Fix: remove the modifier or remove the variadic decoration.
  • GS0242 (retired) — f(x) where f(in x int32) used to be rejected. It now binds like C#: f(x) passes x itself, and f(x + 1) or f(someInt32) at an in int64 parameter passes a readonly temp holding the converted value. An argument with no implicit conversion to the parameter type reports the ordinary GS0154, and ref/out parameters still require their modifier (GS0235).
  • GS0243 — declaring a parameter whose type is the raw pointer *T: func f(p *int32). Fix: use a ref-kind modifier instead — func f(ref p int32) (or in/out).

Named-argument diagnostics (GS0244–GS0247)​

Named arguments at call sites — Foo(timeout: 30, retries: 3) — for free functions, user methods, user constructors, user extension functions, imported CLR methods and constructors, imported extension methods, and inherited CLR instance methods (including delegate Invoke). Indirect calls through a function-typed or delegate-typed variable, and variadic call sites, intentionally do not accept named arguments because the call target does not preserve parameter names. The diagnostics below flag malformed or unresolvable named-argument call sites.

Code Severity Message 
GS0244 Error Positional argument cannot follow a named argument. 
GS0245 Error Named argument {name} is specified more than once. 
GS0246 Error The best overload of {callee} does not have a parameter named {name}. 
GS0247 Error Named argument {name} specifies a parameter for which a positional argument has already been given. 

Cause/fix examples:

  • GS0244 — Foo(1, name: "a", 2). Fix: move every named argument to the trailing positions, or pass the named one positionally.
  • GS0245 — Foo(timeout: 1, timeout: 2). Fix: remove the duplicate.
  • GS0246 — Foo(qty: 3) when Foo has no parameter named qty. Fix: use the correct parameter name. Also fires when calling through a function-typed/delegate variable, or when targeting a variadic parameter list (parameter names are not addressable in those cases).
  • GS0247 — Foo(1, x: 2) when Foo(x int32, y int32) is bound — the positional 1 already filled x. Fix: drop one or the other.

Ref-aliasing local diagnostics (GS0256–GS0258)​

let ref / var ref declarations create aliasing locals — locals whose IL slots are managed pointers T& and alias another lvalue (let ref m = arr[i], var ref v = c.Field). The diagnostics below flag malformed or illegal ref-alias declarations.

Code Severity Message 
GS0256 Error The right-hand side of a 'ref' local declaration must be an lvalue (variable, field, indexer, or dereference). 
GS0257 Error A 'ref' local cannot be initialized from an expression with a narrower escape scope than the local itself. 
GS0258 Error A 'ref' local cannot be declared here — only inside non-async, non-iterator function bodies (no top-level, no const). 

Cause/fix examples:

  • GS0256 — let ref m = 1 + 2 or let ref m = foo(). The RHS must denote storage you can take the address of. Fix: alias an addressable expression (let ref m = arr[0], let ref m = c.Value, let ref m = *p), or drop ref and copy the value.
  • GS0257 — Reserved for the full ref-safety analysis. Will fire when the RHS storage cannot live as long as the alias (e.g. a ref returned from a callee that captured a shorter-lived local). V1 has no ref returns, so this code is defined for forward compatibility and currently does not fire.
  • GS0258 — let ref m = n at top level, inside async func, inside an iterator (yield-returning) function, or written as const ref. Fix: move the declaration into a synchronous, non-iterator function body and use let ref / var ref (not const ref). Top-level ref locals would require a static field of T&, which the CLR forbids; async / iterator bodies would lift the slot onto a state-machine field, which the CLR likewise forbids.

Conditional expression diagnostics (GS0259–GS0263)​

The conditional expression cond ? a : b is available in value contexts and in ref/out/in argument payloads. GS0259 is retired for ordinary value-context conditionals; the remaining diagnostics still fire in their byref contexts, and GS0263 covers the value-context "no common type" failure.

Code Severity Message 
GS0259 Error (retired) Conditional lvalue expression (cond ? a : b) is only legal as the payload of a 'ref'/'out'/'in' argument modifier or as the operand of '&'. Now only fires for the legacy inner-ref-modifier shape outside ref context. 
GS0260 Error Both branches of a conditional ref-argument must produce lvalues of the same type, but the true branch is {trueType} and the false branch is {falseType}. 
GS0261 Error An 'out var'/'out let'/'out _' inline declaration cannot appear inside a branch of a conditional ref-argument (the new local would only conditionally exist). Declare the local before the call instead. 
GS0262 Error Inner ref-kind modifier {innerModifier} on a conditional ref-argument branch must match the outer modifier {outerModifier}. 
GS0263 Error Conditional expression branches have no common result type — the true branch is {trueType} and the false branch is {falseType}. Add an explicit conversion to align the two arms. 

Cause/fix examples:

  • GS0260 — bump(ref true ? a32 : b64) where a32 int32 and b64 int64. Fix: align the branch types (e.g. introduce a local of the wider type or use a value ternary outside the ref).
  • GS0261 — produce(out true ? a : out var n) — the inline out var n would declare a local that only exists on one branch. Fix: declare var n int32 before the call.
  • GS0262 — bump(ref true ? in a : ref b) — the inner in does not match the outer ref. Fix: use bump(ref true ? a : b) (the generalized form requires no inner modifiers).
  • GS0263 — var x = pick ? true : "no" — bool and string have no common type. Fix: explicitly convert one arm (e.g. pick ? "yes" : "no").

Ref-return diagnostics (GS0248–GS0255)​

ref-returning functions use declarations of the form func f(...) ref T { ... } and return a managed pointer T& rather than a copied value, paired with the return ref <expr> statement form. The diagnostics below guard the declaration and return-site rules.

Code Severity Message 
GS0248 Error A 'ref' return modifier requires an explicit return type clause (e.g. 'ref int32'). 
GS0249 Error 'ref' return is not legal on an {async/iterator} function; the state-machine rewriter cannot hoist a managed pointer. 
GS0250 Error 'ref' return modifier is redundant when the declared return type is already a managed pointer ('*T'); write 'ref T' instead. 
GS0251 Error 'return ref' is not allowed in {functionName} because its declaration does not specify a 'ref' return type. 
GS0252 Error Function {functionName} returns by reference; use return ref <expr> instead of a plain 'return'. 
GS0253 Error The operand of 'return ref' must be an lvalue (variable, field, array element, or '*p'). 
GS0254 Error Cannot return a managed pointer to function-local storage or through a scoped parameter; the reference would escape its permitted scope. 
GS0255 Error Override of {memberName} must match the base return ref-kind: base returns {expected}, this declaration returns {actual}. 

Cause/fix examples:

  • GS0248 — func f(x int32) ref { return ref x } — ref requires the element type. Fix: func f(x int32) ref int32.
  • GS0249 — async func f() ref int32 { ... } or a yield-iterator body. Fix: drop ref from the return — async / iterator state-machine fields cannot hold managed pointers.
  • GS0250 — func f(p *int32) ref *int32 { return p }. Fix: write ref int32 (or drop ref and return the pointer).
  • GS0251 — a return ref x statement in a function whose declaration is func f() int32. Fix: add ref to the return type, or drop ref from the return statement.
  • GS0252 — a plain return x in a ref-returning function. Fix: write return ref x.
  • GS0253 — return ref (a + b) or return ref Foo(). Fix: alias an addressable expression first (let ref t = arr[i]; return ref t) or restructure to return a pointer to durable storage.
  • GS0254 — func f() ref int32 { var x = 0; return ref x }, or func f(out x int32) ref int32 { x = 0; return ref x }. Fix: do not return references to function locals; for an implicitly scoped out parameter, add @UnscopedRef only when the API contract intentionally permits the reference to escape. Also reported for return ref this.n inside a function literal declared in a struct member: the literal captures this by value, so the reference would alias the closure's copy rather than the caller's struct, and @UnscopedRef cannot change that. Fix: return a reference into heap storage (an array element or a class field), or make the literal a member function.
  • GS0255 — overriding a base method declared int32 with a ref int32 override (or vice versa). Fix: match the base return ref-kind exactly.

Ref-returning property / indexer diagnostics (GS0578-GS0579)​

The by-ref return also applies to prop: prop Value ref int32 { get { return ref this.slot } }, its arrow sugar prop Value ref int32 -> this.slot, and the indexer form prop this[i int32] ref int32 -> this.items[i]. The getter returns a managed pointer, so a CLR consumer can alias the storage (ref int slot = ref holder.Value).

The form is restricted to the computed, read-only shapes, and the two diagnostics below enforce that. Everything else about a ref-returning getter -- return ref <lvalue> vs a plain return, the lvalue rule, and the escape rule -- is the existing GS0248-GS0255 surface above, because the accessor body is bound with the getter as its enclosing function.

Code Severity Message 
GS0578 Error Property {name} cannot return by reference here: a 'ref' return needs a concrete getter with a body to name the storage it aliases. 
GS0579 Error Property {name} returns by reference, so it cannot declare a {set/init} accessor: a caller writes through the returned reference instead of calling a setter. 

Cause/fix examples:

  • GS0578 -- prop Slot ref int32 (an auto-property), prop Slot ref int32 { get } (a bodiless slot), or the same requirement inside an interface. An auto-property's getter only copies out of its compiler-synthesized backing field, and an abstract or interface slot names no storage at all. Fix: give the getter a body on a concrete class, struct, or shared block -- prop Slot ref int32 { get { return ref this.storage } } or prop Slot ref int32 -> this.storage.
  • GS0579 -- prop Value ref int32 { get { return ref slot } set(v) { slot = v } }. The returned reference already is the write path, so a setter is a second, contradictory one (C# spells the same rule CS8147). Fix: drop the set/init accessor, or drop the ref from the declaration.

Method-overloading and optional-parameter diagnostics (GS0264–GS0267)​

The v0 "one declaration per name" rule, so G# user functions can carry overload sets (differing by parameter types or ref-kinds) and optional parameters with default values. The diagnostics below cover overload-set construction and overload resolution.

Code Severity Message 
GS0264 Error An overload of {name} with signature {signature} is already declared. Two overloads must differ by parameter types or ref-kinds. 
GS0265 Error Optional parameter {parameterName} is invalid: {reason}. 
GS0266 Error Call to {name} is ambiguous between multiple overloads. Disambiguate with explicit types or named arguments. 
GS0267 Error No overload of {name} is applicable to the given argument list. 

Cause/fix examples:

  • GS0264 — two func F(x int32) {} declarations, or two declarations that differ only in return type. Fix: change the parameter list (different types, arity, or ref-kinds); return type alone is not a distinguishing signature.
  • GS0265 — a default-value expression that is not constant, a parameter whose default depends on another parameter, an optional parameter preceding a required one without all trailing parameters also optional, or an optional ref/out parameter. Fix: use a compile-time-constant default, place optional parameters at the end of the list, and avoid combining ref/out with defaults.
  • GS0266 — Greet("ada") when both Greet(string) and Greet(name string) are visible via different paths. Fix: rename one, change one signature, or use a named argument that only one overload accepts.
  • GS0267 — Greet(42) when only Greet(string) is declared. Fix: pass a value of the expected type, or add an overload covering the new argument shape.

if let, guard let, and while let binding diagnostics (GS0296–GS0297, GS0624–GS0626)​

The nullable-binding forms share GS0296. guard let additionally requires its failure branch to exit. Every binding initializer ends at a top-level && or ||; GS0624–GS0626 report the shapes where that matters.

Code Severity Message 
GS0296 Error The right-hand side of an if let / guard let / while let binding must be of nullable type; non-nullable initializers have nothing to strip. 
GS0297 Error A guard let else block can fall through instead of unconditionally exiting with return, throw, break, or continue. 

Cause/fix examples:

  • GS0296 — let s = "hi"; while let v = s { ... }. Fix: either use a plain boolean loop condition or pass a nullable value. Binding only makes sense when the RHS has type T?; the same rule applies to if let and guard let.
  • GS0297 — guard let v = s else { var x = 1 }. Fix: make the else block exit the enclosing scope — return, throw, break, or continue. The binding is only in scope after the guard precisely because the else cannot fall through.
  • GS0624 — if let v = a && b ? x : y { … }. The && starts the guard, so the initializer is just a. Fix: if let v = (a && b ? x : y) { … }.
  • GS0624 also covers if let v = cached = a && b when cached is nullable: use (cached = a && b) to preserve the old value and body execution, or (cached = a) && b to select the new guard explicitly.
  • GS0625 — while let line = reader.ReadLine() && line.Length > 0 { … }. Fix: test the condition at the start of the body (if line.Length == 0 { break }).
  • GS0626 — if let v = maybe || fallback { … }. Fix: if you meant a fallback value, write maybe ?? fallback; if the || belongs to the initializer, parenthesize it.

Top-level-statement diagnostics (GS0285–GS0287)​

The three diagnostics below cover the project-shape / placement / return-shape rules that the synthesized entry point depends on.

Code Severity Message Example trigger 
GS0285 Error Top-level statements are not allowed in a library project. A .gsproj with <OutputType>Library</OutputType> whose .gs source contains statements at the file root. Set <OutputType>Exe</OutputType> or move the statements into an explicit func Main(). Mirrors C# CS8805. 
GS0286 Warning Top-level statements should form a single contiguous block within a file. A .gs file that interleaves declarations between top-level statements, e.g. var x = 1; func helper() {}; var y = 2. Both the C# style (TLS first, then decls) and the Go style (decls first, then TLS) are accepted; only interleaved layouts trigger the warning. 
GS0287 Error Top-level statements mix bare return; and return <expr>;. TLS that contains both return (no value) and return 0 — the synthesized <Main>$ must have a single return type, so choose one shape. 

Field declaration var / let requirement (GS0288)​

Field declarations inside a struct, class, or shared block must carry a leading var (mutable) or let (read-only) keyword. The keyword distinguishes mutable from read-only storage and keeps type bodies visually consistent with property, event, and method members.

Code Severity Message Example trigger 
GS0288 Error Field declarations require a var (mutable), let (read-only), or const (compile-time constant) keyword. struct Point { X int32 } — must be written as var X int32 (mutable), let X int32 (read-only), or const X int32 = … (constant). 

Cause/fix — struct Point { x int32; y int32 } → struct Point { var x int32; var y int32 } (or let for read-only, const for a compile-time constant). The parser recovers by treating the field as var, but the error still fires.

Inline field initializer diagnostics (GS0375–GS0377)​

const/let/var fields in a type body may carry an inline = expr initializer. Instance initializers run before each constructor body in declaration order; const fields fold to compile-time literal fields; static (shared) initializers run in the static constructor.

Code Severity Message 
GS0375 Error A const field requires an initializer (e.g. const X int32 = 10). 
GS0376 Error A const field initializer must be a compile-time constant expression. 
GS0377 Error A field initializer cannot reference the instance member or constructor parameter {name} (field initializers run before the constructor body, so this is not available). Assign it in an init(...) constructor instead. 

protected accessibility diagnostics (GS0379–GS0380)​

The protected access modifier (CIL family) makes a member accessible within its declaring type and the bodies of derived types only. Because protection is only meaningful where a derived type can exist, protected is restricted to members of an inheritable open class. A protected override method, property or event is exempt, because the base member dictates its accessibility: a non-open (CLR-sealed) class may declare one.

Code Severity Message 
GS0379 Error '{Type}.{member}' is inaccessible due to its protection level: a 'protected' member is only accessible within '{Type}' and types derived from it, and an instance member only through a receiver of the accessing type or a type derived from it. 
GS0380 Error 'protected' is only allowed on members of an 'open class' (a type that can be inherited). Mark the enclosing class 'open', or use a different accessibility. 

deinit (finalizer) diagnostics (GS0289–GS0292)​

deinit { … } declares a CLR finalizer on a class. The diagnostics below cover the placement and shape rules.

Code Severity Message Example trigger 
GS0289 Error deinit is only valid on class types (not structs, ref-structs, interfaces, or enums). struct Point { var X int32 deinit { … } } — value types do not have finalizers in the CLR. 
GS0290 Error Only one deinit declaration is allowed per class. A class body that declares deinit { … } twice — the C# finalizer surface only supports a single ~Type() per type. 
GS0291 Error deinit may not declare parameters. deinit(x int32) { … } — a CLR finalizer is parameter-less. 
GS0292 Error deinit may not declare a return type. deinit int32 { … } — a CLR finalizer is void. 

Labeled break / continue diagnostics (GS0293–GS0295)​

Labeled loops and break label / continue label targeting an enclosing loop by name.

Code Severity Message 
GS0293 Error No enclosing loop is labeled <label> (in break <label> / continue <label>). 
GS0294 Retired Previously: labels could only be applied to loop statements. Non-loop labels are now valid goto targets; this diagnostic is no longer emitted. 
GS0295 Warning Label <label> shadows an enclosing loop label of the same name; the inner label wins for nested break / continue. 

Cause/fix:

  • GS0293 — typo or stale name; spell the label exactly as it appears on the enclosing loop.
  • GS0294 — label-prefixes only attach to the three loop forms; remove the prefix on if/switch/etc.
  • GS0295 — rename the inner label so the two are distinguishable, or accept the inner-wins semantics.

If-expression diagnostics (GS0276–GS0277)​

if so that it can sit in value position (let x = if cond { a } else { b }). The diagnostics below guard the two binder rejection paths that are unique to the expression form; the branch-type-mismatch case reuses GS0263 (shared with the ternary).

Code Severity Message Example trigger 
GS0276 Error An if-expression in value position must have an else branch so that all code paths produce a value. let x = if cond { 1 } — the if has no else, so when cond is false there is no value to bind. Add a terminal else { … }, or use the statement form (if cond { x = 1 }). Applies to chained else if shapes too: every chain must end in a terminal else. 
GS0277 Error A block expression in value position must end with a value-producing expression. let x = { let y = 1 } or let x = if cond { } else { 1 }. Add a trailing value ({ let y = 1 y }). Also fires when the last item is a non-expression form (for, while, etc.). Does not fire when the block ends in return, throw, rethrow, break, continue or goto (its type is then never), or where the value is discarded (a void lambda or arrow body). 

Cause/fix examples:

  • GS0276 — let x = if cond { 1 } — the if has no else, so when cond is false there is no value to bind. Add a terminal else { … }, or use the statement form (if cond { x = 1 }). The same rule applies to chained else if shapes: every chain must end in a terminal else.
  • GS0277 — let x = { let y = 1 } or let x = if cond { } else { 1 } has no tail value. Add one, such as { let y = 1 y }.
  • GS0263 also covers if-expression branches with no common result type (e.g. if cond { true } else { "no" }). Mirrors the ternary diagnostic since both forms share ComputeConditionalCommonType.
  • All three codes apply verbatim to the if let expression (let x = if let v = maybe { v } else { fallback }): the terminal else is required, each branch block must end in a value, and the tails must unify. A non-nullable binding initializer additionally reports GS0296.

Null-coalescing compound assignment diagnostics (GS0298–GS0299)​

The ??= null-coalescing compound assignment, in statement or value position. The diagnostics below cover the two shapes the binder rejects up front.

Code Severity Message Example trigger 
GS0298 Error The left-hand side of ??= must be of nullable type. var s = "hi"; s ??= "x" — s has type string (non-nullable), so the operator can never fire. Either declare s string? or use a plain =. 
GS0299 Error The left-hand side of ??= must be assignable: a variable, parameter, field, property, or indexer. compute() ??= "v" — the result of a method call is not an lvalue. Store the value first and ??= into the variable. 

Cause/fix examples:

  • GS0298 — var s = "hi"; s ??= "x". Fix: declare the variable as string? if you intend to default a possibly-missing value; otherwise use a plain =. The compiler will not silently insert a no-op on a non-nullable target.
  • GS0299 — compute() ??= "v". Fix: store the call result in a variable first and ??= into the variable, or write the conditional store by hand. ??= requires an lvalue.
  • A read-only lvalue (let x string? = nil; x ??= "v") reports the existing GS0127 for parity with the simple-assignment path.

Null-conditional indexing diagnostics (GS0300–GS0301)​

The a?[i] null-conditional indexing operator. The diagnostics below cover the two shapes the binder rejects or warns up front.

Code Severity Message 
GS0300 Warning A null-conditional index access uses a non-nullable receiver; use ordinary indexing instead. 
GS0301 Error Null-conditional indexing ?[] is not allowed on the left-hand side of an assignment. Use a plain [] after a nil-check, an if let binding, or the ??= compound assignment instead. 

Cause/fix examples:

  • GS0300 — var a = []int32{1,2}; var x = a?[0]. Fix: the receiver type []int32 is non-nullable, so write a[0] directly. ?[] is intended for receivers whose static type permits nil.
  • GS0301 — dict?["k"] = 1. Fix: nullable receivers do not have an addressable indexed slot when the receiver is nil; check first (if dict != nil { dict["k"] = 1 }) or use a non-nullable local that you've already narrowed.

Switch-expression arm separator deprecation (GS0302)​

-> the lambda operator and migrates switch-expression arms to use : as the pattern/value separator. The legacy -> arm form remains accepted for one release to ease migration, but every legacy arm produces a warning.

Code Severity Message Example trigger 
GS0302 Warning '->' in a switch-expression arm is deprecated; use ':' instead. case 0 -> "zero" — rewrite as case 0: "zero". 

Cause/fix:

  • GS0302 — let label = switch x { case 0 -> "zero"; default -> "other" }. Fix: replace each -> between the pattern and the arm value with :, e.g. case 0: "zero"; default: "other". The behaviour is otherwise identical. A future release will remove the legacy form and turn it into a parse error.

Function-type clause func(...) deprecation (GS0303)​

(T1, T2,...) -> R the canonical function-type clause spelling — the type spelling now matches the lambda expression form. The legacy func(...) R and async func(...) R type-clause spellings remain accepted for one release to ease migration, but every legacy occurrence produces a warning. The managed function-pointer form *func(...) R is distinct and is not deprecated.

Code Severity Message Example trigger 
GS0303 Warning 'func(...)' as a type clause is deprecated; use the arrow form '(...) -> R' instead. The managed function-pointer form '*func(...) R' is a distinct construct and is not deprecated. var f func(int32) int32 = … — rewrite as var f (int32) -> int32 = …. Async variant: async func(T) R → async (T) -> R. 

Cause/fix:

  • GS0303 — var f func(int32) int32 = (x int32) -> x + 1. Fix: rewrite the type clause as var f (int32) -> int32 = (x int32) -> x + 1. Async variant: async func(int32) int32 → async (int32) -> int32. The deprecation applies only to func in type-clause positions; function declarations (func name(...) R { … }), function literals (func(...) R { … } expressions), and *func(...) R managed function-pointer types keep func. Named delegates instead use delegate Name(parameters) ReturnType;, without func. Rewriting a function pointer as *((...) -> R) changes its meaning to a pointer to a managed delegate and produces GS0398. A future release will remove the legacy type-clause spelling and turn it into a parse error.

Lambda binding type-inference diagnostics (GS0304)​

Type inference for let / var bindings whose initializer is a lambda. When the lambda's parameters are fully typed, the binding's type is inferred to the lambda's (T1,...) -> R function type and the user does not need to repeat the function-type clause. If neither side resolves to a concrete type — the binding has no explicit type clause AND the lambda's parameter types are not spelled — the binder reports GS0304.

Code Severity Message Example trigger 
GS0304 Error Cannot infer the type of '<name>' from a lambda with untyped parameters; supply a function-type clause on the binding or annotate the lambda parameters. let f = (x) -> x + 1 — fix by spelling either side, e.g. let f = (x int32) -> x + 1 or let f (int32) -> int32 = (x) -> x + 1. 

Cause/fix:

  • GS0304 — let f = (x) -> x + 1. Either side may carry the types. Spell the lambda parameters: let f = (x int32) -> x + 1, or spell the binding: let f (int32) -> int32 = (x) -> x + 1. Generic method calls that take a lambda (for example xs.Where(x -> x > 0)) still use the existing method-type-inference path and are unaffected.

:= short variable declaration removal (GS0305)​

The Go-style := short variable declaration from the language. The lexer still tokenizes := so the parser can produce a targeted, span-accurate diagnostic with a context-sensitive migration suggestion instead of cascading parse errors. Every occurrence of := — at statement scope, in multi-target assignment, in for / await for range and ellipsis loops, in if / for simple-statement initialisers, and in select case bindings — emits GS0305.

ID Severity Message Example trigger 
GS0305 Error ':=' short variable declaration has been removed; use 'let' (immutable) or 'var' (mutable) instead (e.g. '<migration>'). x := 1 → let x = 1 (or var x = 1). for i := 0 ... 10 → for i in 0 ... 10. for v := range xs → for v in xs. for k, v := range dict → for k, v in dict. await for x := range seq → await for x in seq. case v := <-ch → case let v = <-ch. for i := 0; i < n; i++ → for var i = 0; i < n; i++. if x := init; cond → if var x = init; cond. 

Cause/fix:

  • GS0305 — x := 1. Use let x = 1 when the binding is never rebound, or var x = 1 when it is. For looping forms: for i := 0 ... 10 → for i in 0 ... 10, for v := range xs → for v in xs, for k, v := range dict → for k, v in dict, await for x := range seq → await for x in seq, case v := <-ch { … } → case let v = <-ch { … }. The three-part for init slot accepts a var/let declaration, e.g. for var i = 0; i < n; i++ (previously written as `for i := 0;

Kotlin/Swift-style type-declaration head (GS0306–GS0313)​

The legacy type Name <kind>... aggregate head and the record keyword. The aggregate keyword (class, struct, enum, interface) is the declaration keyword. These diagnostics catalogue the invalid combinations and the legacy migrations.

ID Severity Message 
GS0306 Error A declaration uses the removed type Name <kind> form instead of putting the aggregate-kind keyword first. 
GS0307 Error The record keyword has been removed; use data struct Name (value-typed) or data class Name (reference-typed). 
GS0308 Error inline is applied to an aggregate kind other than struct. 
GS0309 Error open is applied to an aggregate kind other than class. 
GS0310 Error sealed is applied to an aggregate kind other than class or interface. 
GS0311 Error data and inline are combined on the same declaration. 
GS0312 Error open and sealed are combined on the same declaration. 
GS0313 Warning Non-exhaustive switch over a sealed-hierarchy base or discriminated-union enum. 

Cause/fix:

  • GS0306 — type Foo class { … } → class Foo { … }. Same for struct, enum, interface. Type aliases (type Count = int32) and named delegates (delegate Greeter(name string) ) are; unaffected.
  • GS0307 — record Point { x int32; y int32 } → data struct Point(x int32, y int32) (preserves value semantics) or data class Point(x int32, y int32) if reference semantics are desired.
  • GS0308 — inline class Foo → inline struct Foo. Inline classes do not exist; the wrapper must be a value type.
  • GS0309 — open struct Foo, open enum Foo, open interface Foo → drop open. Structs cannot be inherited from, enums and interfaces are open by default.
  • GS0310 — sealed struct Foo → drop sealed. sealed enum Foo → use a discriminated-union enum (enum Foo { … } with payload-bearing cases) or drop sealed.
  • GS0311 — data inline struct Foo → choose one (data struct for the record contract, inline struct for the newtype wrapper).
  • GS0312 — open sealed class Foo → choose one. open admits cross-package subclasses; sealed is the closed Kotlin hierarchy.
  • GS0313 — Add missing cases to the switch, or add a default arm. For sealed class Shape with subclasses Circle, Square, write switch s { case c is Circle: ... case sq is Square: ... }.

Owned-receiver method warning, retired (GS0314)​

Go-style receiver-clause methods (func (r T) M() { ... }) are unconditionally extensions now, whether or not the current package owns T. There is no more owned-instance-method meaning to warn about: a same-package instance method is declared inside the type body, full stop, with no receiver-clause alternative. Operator overloads (func (a T) operator +(b T) T) remain the one receiver-clause form that still attaches to an owned type.

ID Severity Message Example trigger 
GS0314 Retired Previously: a receiver-clause method on an owned class/struct warned that it should move into the type body. The owned-instance-method meaning of the receiver-clause form no longer exists (it is always an extension now), so there is nothing left to warn about; this diagnostic is no longer emitted. — 

Cause/fix:

  • GS0314 is retired. A receiver-clause method on an owned class/struct — func (p Point) Distance() int32 { ... } where Point is declared in the same package — now binds as an extension, exactly like a cross-package or CLR receiver, instead of an instance method. If you intend a real instance method, declare it inside the type body (class Point { ... func Distance() int32 { ... } }); there is no receiver-clause spelling for that anymore. If the declaration was intentionally an extension of an owned type or enum, no change is needed — the old func extension (p Point) Distance() ... marker is itself retired (GS0587); drop the extension word and the plain receiver clause does the same thing unconditionally.

    Migrating off the old warned spelling changes behavior, not just style: interface conformance, override, and private-member access on the old instance-method form now fail to compile (loudly), and a receiver-clause method on an owned struct that mutated a field now silently mutates a throwaway by-value copy instead of the caller's struct (no diagnostic — the same hazard any struct extension method already has).

Named-argument = separator retired (GS0524)​

Named arguments are written name: value. The legacy name = value spelling — deprecated with a one-release GS0315 warning — is retired: = after an identifier in argument position is no longer a separator and parses as an ordinary assignment expression, exactly as = does in every other expression position. GS0315 no longer exists.

ID Severity Description Example trigger 
GS0524 Warning Argument '<name> = …' is an assignment to '<name>', not a named argument — the '=' named-argument separator was retired. Write '<name>: value' for a named argument, or '(<name> = value)' to assign deliberately. Foo(timeout = 30) — write Foo(timeout: 30) for a named argument, or Foo((timeout = 30)) to assign. 

The warning exists because the two readings can differ silently: where name is both an assignable variable in scope and a parameter of the callee, the old spelling now assigns and passes the value positionally instead of binding by name. Where name is not in scope, the change is a loud binder error (GS0125) instead.

Only a bare assignment argument warns. Parenthesising (Foo((timeout = 30))) states the assignment intent unambiguously and is warning-free — it is the spelling cs2gs emits for a value-position assignment. Parameter default values (func f(x int32 = 0)) and with-expression field initializers (p with { x = 10 }) parse on separate paths and are unaffected.

Pattern binding in boolean is expression (GS0525)​

ID Severity Summary Example 
GS0525 Error A boolean is pattern uses the switch binding spelling name is Type, which reads as an incoherent double test in expression position. Write the designation after the type (is Type name) to introduce a pattern variable, or use if let / guard let / while let. if value is text is string { } 

Invalid multi-assignment target (GS0526)​

ID Severity Summary Example 
GS0526 Error A multi-assignment target is not writable storage. Use a variable, field, property, array element, indexer, or pointer dereference. GetValue(), x = 1, 2 

Rectangular arrays (GS0527–GS0530)​

ID Severity Message Example 
GS0527 Error Rectangular array rank is <rank>, but <count> index expression(s) were supplied. let a = [2, 3]int32; let x = a[0] 
GS0528 Error Rectangular array rank <rank> exceeds CLR maximum rank 32. A type or allocation with 33 dimensions. 
GS0529 Error Rectangular array initializer dimensions must be non-negative int32 constants. let n = 2; let a = [n, 2]int32{1, 2, 3, 4} 
GS0530 Error Rectangular array initializer requires <expected> element(s), but <actual> were supplied. let a = [2, 3]int32{1, 2, 3} 

Constructor initializer instance access (GS0531)​

ID Severity Message Example 
GS0531 Error Constructor initializer arguments cannot reference instance member '<name>' before the delegated or base constructor has run. init() : base({ let self = this 1 }) { } 

fallthrough placement (GS0533–GS0534)​

fallthrough has Go semantics: it is legal only as the LAST statement of a non-final switch arm, transferring into the next arm's body without evaluating its pattern or guard. GS0168 (above) reports a misplaced fallthrough; these report the two structural misuses.

ID Severity Message Example 
GS0533 Error 'fallthrough' cannot be used in the final arm of a 'switch' statement. switch x { case 1 { fallthrough } } 
GS0534 Error 'fallthrough' cannot target a 'switch' arm whose pattern declares bindings or that has a 'when' guard — the jump would skip their assignment. case 1 { fallthrough } case string s { ... } 

Retired delegate-declaration spelling (GS0535)​

Named delegates are declared with the standalone delegate Name(parameters) ReturnType; form (trailing semicolon required — it terminates the optional return-type clause the way extern natives and interface bodiless members do, so a void delegate can no longer consume the declaration that follows it). The retired type Name = delegate func(...) spelling reports this error and recovers, and type itself is no longer a reserved keyword (erased aliases type Name = Target parse contextually).

ID Severity Message Example 
GS0535 Error The 'type <Name> = delegate func(...)' spelling is retired. Declare the delegate as 'delegate <Name>(parameters) ReturnType;' (trailing semicolon required; omit the return type for void). type Greeter = delegate func(name string) 

Redundant null assertion (GS0536)​

A user-written !! whose operand is already non-nullable — statically, or through smart-cast narrowing — performs no useful work. The warning marks exactly the operator token so the assertion can be deleted; cs2gs's migrate pipeline consumes it to strip redundant assertions from translated output automatically.

ID Severity Message Example 
GS0536 Warning Redundant '!!': the value is already non-null here. if s != nil { return s!! } 

Method-generic operator declarations (GS0537)​

G# user-defined operators cannot declare method type parameters. Put generic parameters on the containing type; operators on open generic containing types remain supported.

ID Severity Message Example 
GS0537 Error Operator '<name>' cannot declare method type parameters; put generic parameters on the containing type instead. func (left Value) op_Addition[T](right Value) Value 

Native-width emitted constants (GS0538)​

CLR constant metadata has no architecture-independent nint/nuint representation. Use int64/uint64 for a compile-time package constant, or let when runtime native width is required.

ID Severity Message Example 
GS0538 Error Constant '<name>' cannot use native-width type '<type>' when emitted as a field because CLR constant metadata has no native-width representation; use 'int64'/'uint64' or an immutable runtime 'let' binding. const PageSize nint = 4096 

Tuple equality arity mismatch (GS0539)​

Tuple == / != compares element-wise and is only defined between tuple operands of the same arity. Comparing tuples of different arities is an error rather than a constant false, matching C#.

ID Severity Message Example 
GS0539 Error Tuple equality requires operands of equal arity: '<left>' has arity <n> but '<right>' has arity <m>. (1, 2) == (1, 2, 3) 

Named tuple elements (GS0540, GS0541, GS0542, GS0543)​

Tuple types may name elements name-first — (line int32, column int32) — and tuple literals may label them — (line: 1, column: 2). Names are metadata over the positional shape: same-shape tuples differing only in names are identity-convertible. GS0541 warns only when an explicit tuple-literal label is renamed by the target type (the C# CS8123 analog); converting a named-tuple-typed value to a differently-named same-shape target is silent. ItemN at the wrong position and Rest (used by the CLR ValueTuple encoding) are reserved; a name on a parenthesized single element is an error because (T) is grouping, not a 1-tuple.

ID Severity Message Example 
GS0540 Error Tuple element name '<name>' is used more than once. (line int32, line int32) 
GS0541 Warning Tuple element name '<name>' is ignored because the target type names this position '<target>'. let r (row int32, col int32) = (line: 1, column: 2) (literal labels only; a named-value conversion is silent) 
GS0542 Error Tuple element name '<name>' is reserved<detail>. (Item2 int32, x int32); (Rest: 1, x: 2) 
GS0543 Error An element name is only valid inside a tuple of two or more elements; a parenthesized single element is grouping. (line: 1); let x (line int32) = 1 

Variadic carrier construction (GS0544)​

A variadic COLLECTION carrier (...List[T], ...ReadOnlySpan[T]) packs its expanded call-site arguments via the carrier's CLR construction form (new List<T>(T[]), the span's T[] constructor). When the element type is a same-compilation type whose CLR shape is still erased at bind time, no closed construction exists; use the array carrier (...T) instead, or pass an existing collection directly.

ID Severity Message Example 
GS0544 Error Variadic carrier '<carrier>' cannot be constructed over element type '<element>' at this call site; use an array carrier ('...T') or pass the collection directly. func F(xs ...List[MyLocalClass]) called expanded 

Interpolated-string handler missing from the target framework (GS0545)​

Interpolated strings lower to the C# 10 handler pattern (System.Runtime.CompilerServices.DefaultInterpolatedStringHandler). The handler type and the AppendFormatted<T> overload each hole needs are resolved from the compilation's reference closure, so they describe the framework being compiled against rather than the SDK hosting gsc. When the referenced framework does not declare the required member — a netstandard2.x target, for example — the compile stops here instead of emitting a call the target's runtime cannot resolve.

ID Severity Message Example 
GS0545 Error Interpolated strings require '<member>', which the referenced target framework does not provide. Reference a framework that declares it, or build the string explicitly. let s = "v=$x" compiled with a netstandard2.1 reference closure 

Emit-time well-known member missing from the target framework (GS0546)​

The fixed / pointer lowering emits calls to two well-known members — System.Runtime.CompilerServices.Unsafe.AsPointer<T> for every pin, and System.String.GetPinnableReference() for the string-pin form. Both are resolved from the compilation's reference closure, so they describe the framework being compiled against rather than the SDK hosting gsc.

Neither is universally available. Unsafe is absent from netstandard2.x altogether (it ships there as a NuGet package), and String.GetPinnableReference() is absent from netstandard2.1 even though System.String is present. Earlier releases read the probes off the host, so a fixed statement compiled against such a target reported success and emitted either a TypeRef scoped to the host's System.Private.CoreLib or a MemberRef naming a method the target does not declare — a MissingMethodException at the target's runtime. The compile now stops here instead.

ID Severity Message Example 
GS0546 Error This construct lowers onto '<member>', which the referenced target framework does not provide. Reference a framework or package that declares it. fixed p *int32 = values { } compiled with a netstandard2.1 reference closure 

Ambiguous imported type reference (GS0547)​

A bare type name that two or more explicitly written imports each resolve to a different CLR type in referenced metadata. In earlier releases the first import that resolved the name won silently, so the reference bound a type chosen by the order of the import list rather than by anything the author wrote — and when the two homonyms had compatible members the program compiled and ran against the wrong type with no diagnostic at all. It is now an error, matching C#'s CS0104 and the two collisions gsc already rejected: GS0496 (the same collision between two same-named source types) and GS0471 (the typeof(Name[_]) open-generic form).

Two imports that resolve the same type are not a collision (the choice does not matter), and neither the compiler-synthesized System import nor an alias import can make a name ambiguous: the first applies to every file and cannot be removed by the author, and the second already names its target.

Silence it by saying which type you mean, using the spellings G# already has:

import Probe.Alpha
import Probe.Beta

// ambiguous — binds Probe.Alpha.Thing because that import comes first
Console.WriteLine(Thing.Name())

// either qualify the reference...
Console.WriteLine(Probe.Beta.Thing.Name())

// ...or alias it
import Thing = Probe.Beta.Thing

In construction position (Thing()) the alias import is the escape hatch: a package-qualified construction of an imported CLR type (Probe.Beta.Thing()) is not a spelling gsc accepts today (GS0157).

ID Severity Message Example 
GS0547 Error Type '<name>' is ambiguous between imported '<first>' and imported '<second>'; it would bind '<chosen>' only because that import comes first. Spell the name qualified, or add an 'import Alias = Namespace.Type', to say which one you mean (issue #3734). import Probe.Alpha + import Probe.Beta, both exporting Thing, then a bare Thing 
GS0548 Warning 'chan[<T>]()' constructs a rendezvous channel (capacity 0): a send completes only when a receiver takes the value. Pass a capacity for a buffered channel, or use 'Chan.Unbounded[<T>]()' if an unbounded buffer was intended (ADR-0174 D12). let ch = chan[int32]() 
GS0549 Error Cannot send on the receive-only channel type '<type>'; only a 'chan[T]' or 'out chan[T]' handle can send (ADR-0174 D2). func f(ch in chan[int32]) { ch <- 1 } 
GS0550 Error Cannot receive from the send-only channel type '<type>'; only a 'chan[T]' or 'in chan[T]' handle can receive (ADR-0174 D2). func f(ch out chan[int32]) { let v = <-ch } 
GS0554 Error '<form>' binds exactly <count>, not <actual>: a channel receive yields the element and an 'ok' flag (ADR-0174 D3). let (v, ok, extra) = <-ch; for k, v in ch 
GS0555 Error 'while let <name> = <expr>' binds the channel itself; receive from it with 'while let <name> = <-<expr>' to loop until the channel is closed (ADR-0174 D3). while let v = ch { } where ch is a chan[int32] 
GS0551 Error 'async let' starts a child of the enclosing 'scope', and there is none here; put it inside a 'scope' block (ADR-0174 D15). async let user = fetch(id) written outside any scope 
GS0559 Warning '<name>' is never awaited, so its work is started and then cancelled at the end of the scope (ADR-0174 D15). scope { async let user = fetch(id) } with no await user 
GS0562 Warning '<name>' is a rendezvous channel (capacity 0), so a batch operation on it degenerates to that many sequential transfers; give it a capacity to make batching pay (ADR-0174 D10). let ch = chan[int32]() then await ch.ReceiveBatch(buffer, 1) 
GS0569 Error '<name>' is an 'async let' binding; read it with 'await <name>' so the suspension is visible (ADR-0174 D15). async let user = fetch(id) then let copy = user 
GS0574 Error 'await' makes '<name>' suspending, but its signature is fixed — inference stops at an entry point, an 'open'/'override'/interface member, an accessor, a constructor, an operator, an iterator, a function literal, and an 'unsafe' or 'fixed' body (ADR-0174 D4). Move the awaited work into a 'suspend func' or an 'async func' and call that from here; where the form allows it, declaring this one that way works too. open func read() int32 { return await answer() } 
GS0575 Error Cannot 'await' in the body of a 'lock' statement: the monitor is thread-affine and reentrant, so a continuation that resumes on another thread would exit a lock it does not hold. Move the awaited work outside the 'lock' (ADR-0174 D4; C# spells the same rule CS1996). lock o { v = await answer() } 
GS0576 Error Cannot 'await' inside a 'go' operand: the spawn takes the call, and an await nested in its arguments has no place to suspend. Bind the awaited value to a local first, then 'go' the call that uses it (ADR-0174 D5). go consume(await fetch()) 
GS0577 Error Type '<type>' has no member '<member>' of its own. '<member>' is declared by the interface '<interface>', which '<type>' implements explicitly, so it is not part of the type's own surface. Reach it through an interface-typed receiver instead (issue #4013). map[string, int32]{}.Contains("k") — Contains on Dictionary<K, V> is an explicit ICollection<KeyValuePair<K, V>> / IDictionary implementation 
GS0580 Error Type parameter '<name>' does not carry the '<constraint>' constraint that type parameter '<parameter>' requires, so this instantiation is not valid for every '<name>'. Forward the constraint onto the declaration of '<name>' (issue #4037; C# spells the same rule CS0314). class Unforwarded[T] : Handler[T] where the imported Handler<TOptions> declares where TOptions : SchemeOptions 
GS0581 Error Circular constraint dependency involving '<type-parameter>' and '<type-parameter>'. A type parameter cannot, directly or through a chain of type-parameter constraints, be constrained by itself. class Cyc[A B, B A] — A is constrained by B, which is constrained by A (C# spells the same rule CS0454) 
GS0582 Error The <method-group-kind> '<name>' cannot be used as a value without a target delegate type. Invoke it with '(...)' or convert it to a delegate. The kind distinguishes user/imported and instance/static/extension method groups. items.Add.ToString() — Add is an imported instance method group, not a value 
GS0583 Error Attribute '<name>' has no constructor that accepts the argument list (<argument types>). Change the arguments to match one of its constructors (issue #4097; C# spells the same rule CS1729 and CS1503). @Many([]object{1}) where ManyAttribute declares only ManyAttribute(Type[] values) — before #4097 the whole attribute was dropped from the assembly with no diagnostic 
GS0584 Error Constructor parameter '<name>' of user-defined attribute '<attribute>' has type '<type>', which is not a valid attribute parameter type. An attribute constructor parameter must be a primitive, string, System.Type, object, an enum, or a 1-D array thereof (issue #4097; C# spells the same rule CS0181, and reports it on the attribute's declaration rather than on each use). class BadAttribute(Value Widget) : Attribute applied as @Bad(nil), where Widget is a class — csc reports CS0181 on the same shape. Unreachable for this shape as of #4143: GS0585 now rejects the declaration before any use exists 
GS0585 Error Attribute constructor parameter '<name>' has type '<type>', which is not a valid attribute parameter type. An attribute constructor parameter must be a primitive, string, System.Type, object, an enum, or a 1-D array thereof (issue #4143; C# spells the same rule CS0181). class BoxedAttribute(Value Holder) : Attribute where Holder is an ordinary class — reported on the class's own declaration, even if the attribute is never applied anywhere 
GS0558 Warning '<name>' is a suspending function; called from a function that neither suspends nor is 'async', it blocks the calling thread until it completes (ADR-0174 D4). Make the caller a 'suspend func' or an 'async func', or accept the block at a root such as the entry point. suspend func take(ch chan[int32]) int32 { return <-ch } then func f(ch chan[int32]) int32 { return take(ch) } 
GS0556 Error A select arm's 'when' guard must be a 'bool'; '<type>' is not (ADR-0174 D8). select { case <-ch when 1 { } } 
GS0557 Error 'case cancelled' observes the ambient context, and there is none here; put the select inside a 'scope', or take a 'ctx Context' parameter (ADR-0174 D8). select { case cancelled { } case <-ch { } } written outside any scope 
GS0564 Warning '<name>' is both sent to and received from by this select, so it can complete by talking to itself (ADR-0174 D8). select { case ch <- 1 { } case <-ch { } } 
GS0566 Error '<retired form>' has been retired (ADR-0174); <guidance naming the replacement> make(chan int32, 3) (use chan[int32](3)), close(ch) (use ch.Close()) 
GS0567 Error The 'chan T' type-clause spelling has been removed; use 'chan[<T>]' instead (ADR-0174 D2). var ch chan int32 

Pattern variable outside its definitely-assigned region (GS0532)​

A designation in a boolean is pattern (value is string text, value is { Length: > 0 } text, values is [..rest]) introduces a read-only pattern variable that is in scope exactly where C# would consider it definitely assigned — the right operand of && (or of || after a negated test), the branches selected by the condition, the loop body, the guarded switch arm, and the statements after an if whose other branch always exits. Reading it anywhere else is a definite-assignment error rather than an unknown name.

ID Severity Message Example 
GS0532 Error Pattern variable '<name>' is not definitely assigned here; it is only usable where its pattern is known to have matched — the right operand of '&&' (or of '||' after a negated test), the branches selected by the condition, and the statements after an 'if' whose other branch always exits (ADR-0166, issue #3409). if value is string s { } followed by s.Length; value is string s || s.Length > 0 

null identifier "did you mean nil?" diagnostic (GS0273)​

The contract for the C# spelling null used In a G# source where the canonical null literal is nil. null is not a keyword in G# — it parses as an ordinary identifier and resolves through normal symbol lookup. When the identifier null is used in a value-expression position and no symbol named null is in scope, the binder emits GS0273 and recovers by treating the identifier as nil so target-type contexts (e.g. let x string? = null, Foo(null) where Foo takes T?, or x == null) continue to typecheck without cascading errors.

ID Severity Message Example trigger 
GS0273 Error 'null' is not a literal in G#. Did you mean 'nil'? let x string? = null — replace null with nil. Also fires for Foo(null) where Foo takes T?, x == null, and inside lambda bodies. Does not fire when null resolves to a real symbol in scope. 

Cause/fix:

  • GS0273 — let x string? = null, Foo(null) where Foo takes T?, x == null. Replace null with nil (let x string? = nil, Foo(nil), x == nil). The diagnostic is anchored at the null token. GS0273 does not fire when a symbol named null is in scope — let null = "hi"; let s = null and func null() int32 { return 42 }; let v = null() both resolve normally with no diagnostic.

Channel operations and retired spellings​

These diagnostics explain channel direction, receive bindings, and migration from retired spellings. See Go-flavored concurrency for complete examples.

GS0548 warns that chan[T]() creates a rendezvous channel: a send waits for a receiver. Pass a capacity for buffering, or use Chan.Unbounded[T]() when an unbounded buffer is intended. GS0549 rejects sending through a receive-only in chan[T] handle; GS0550 rejects receiving through a send-only out chan[T] handle.

GS0554 reports the wrong number of receive variables: a two-value receive supplies the element and an ok flag, while channel iteration yields one element at a time. GS0555 explains that while let value = channel binds the channel itself; use while let value = <-channel to receive until closure.

GS0566 reports retired built-ins and channel construction. Follow its member replacement, such as xs.Length, m.Remove(key), ch.Close(), or chan[T](capacity). GS0567 replaces the old chan T type spelling with chan[T].

Go-flavored concurrency gate (GS0316, retired)​

Earlier releases gated the Go-shaped concurrency surface (go, chan, <-, select, close, make(chan …)) behind import Gsharp.Extensions.Go. That gate is retired: the syntax is part of the language, make/close are replaced by chan[T](…) and ch.Close() (GS0566), and the concurrency library lives in the implicitly imported Gsharp.Concurrency namespace. GS0316 is never reported again and its identifier is not reused.

ID Severity Message 
GS0316 Retired Retired: the concurrency syntax (go, chan[T], <-, select) is part of the language and no longer gated behind import Gsharp.Extensions.Go. 

Go-style built-ins gate (GS0317, retired)​

Earlier releases gated the Go-style built-in functions len, cap, append, and delete behind a per-file import Gsharp.Extensions.Go, and GS0317 fired when the import was missing. The built-ins themselves are retired: every receiver already carries the member (xs.Length, m.Count, m.Remove(k), List[T].Add, ch.Length(), ch.Capacity), so there is nothing left to gate. A call to a retired name reports GS0566 with a replacement computed for that site; a user-defined function of the same name is an ordinary call. The Gsharp.Extensions.Go namespace no longer exists, so the import itself is the ordinary unresolved-import error. GS0317 is never reported again and its identifier is not reused.

ID Severity Message 
GS0317 Retired Retired: len, cap, append, and delete are no longer built-ins, so there is no import gate to miss; a call to one reports GS0566 naming the member replacement. 

Default-interface-method diagnostics (GS0318–GS0321)​

Interfaces may now expose default-method bodies; classes that implement the interface inherit the default unless they declare their own override. The four diagnostics below cover the conflict, dropped-default, missing-implementer, and deferred-modifier cases.

ID Severity Description Example trigger 
GS0318 Error <Kind> '<C>' inherits conflicting default implementations of '<Name>' from interfaces '<IA>' and '<IB>'. Declare '<C>.<Name>' explicitly to disambiguate. Two unrelated interfaces both supply a default body for the same signature; the class or struct fails to override. 
GS0319 Error <Kind> '<C>' relied on a default implementation of '<I>.<Name>' that was removed. Declare an explicit override on '<C>'. Reserved for a class or struct that relied on a removed default-interface implementation. 
GS0320 Error <Kind> '<C>' does not implement interface method '<I>.<Name>' and the interface does not provide a default. Replaces the historical GS0187 path when a class or struct omits a method that has no default. 
GS0321 Error Modifier '<modifier>' on interface method '<Name>' is not yet supported; 'open', 'override', and 'sealed override' interface members are deferred. Fires when an interface method body carries a deferred modifier such as open, override, or sealed override — the parser accepts the shape so the binder can report a precise diagnostic. private is supported and no longer fires GS0321. static is not a modifier on interface methods; static-virtual members are declared inside the interface's shared { … } block. 
GS0368 Error Interface method '<Name>' has no body and must be terminated with ';'; a bodyless 'func' uses ';' as its no-body marker, mirroring P/Invoke. A body-less interface method (abstract instance method, or an abstract static slot inside the interface's shared { … } block) must end with ;. A method with a { … } body takes no ;. 

Note: as of the private modifier on an interface method is no longer deferred and no longer fires GS0321. See the "Private interface helper diagnostics" section below for the GS0334–GS0337 codes that govern private-helper visibility and override-clash detection. Interface static-virtual members no longer use a static modifier — they are declared inside a shared { … } block on the interface — so static is no longer recognised on interface methods at all (the old static func … shape now produces a generic parser error). GS0321 therefore only fires today for open, override, and sealed override on interface methods.

Default-interface methods (DIM) emit standard CLR DIM metadata: the interface's method table carries a .method virtual slot whose body lives on the interface TypeDef. Implementers inherit the default through normal virtual dispatch; an explicit override on the class replaces it. Cross-language consumers (C# / VB / F#) see the DIM as a regular C# 8+ default interface method.

The historical GS0186 diagnostic ("Interface method may not have a body.") is no longer emitted; default-interface methods. The slot is preserved for back-compat but the binder no longer fires it.

Cause/fix:

  • GS0318 — declare an explicit override on the class to pick which inherited default wins, or call the desired interface's default by qualifying the call site. The explicit-base call syntax (base<IFoo>.Method()) is deferred.
  • GS0319 — reserved for the version-skew scenario where a consumer's referenced library has been upgraded to drop a default. Restore the default or supply a class-level override.
  • GS0320 — provide a method body on the implementing class with the matching signature, or add a default body to the interface declaration.
  • GS0368 — terminate the body-less interface method (or abstract shared { … } static slot) with ;, the universal no-body marker for func declarations. A method with a { … } body takes no ;.
  • GS0321 — remove the deferred modifier. Static interface members, private helper methods, and sealed override are not supported in this release; instance-virtual default-interface methods are the only DIM shape supported in this release.

P/Invoke diagnostics (GS0322–GS0329)​

G# accepts a function whose body is a single ; token as a P/Invoke declaration when the function is annotated with @DllImport("libname", ...). The compiler emits CLR PinvokeImpl metadata (ImplMap + ModuleRef) for these declarations; the runtime resolves the call at first invocation. The historical blanket-rejection at GS0211 has been retired.

ID Severity Description Example trigger 
GS0322 Error @DllImport requires a non-empty library name as its first positional argument. @DllImport func F() int32; — missing the library name. 
GS0323 Error P/Invoke parameter or return type {type} is not in the supported marshalling table. @DllImport("libc") func F(o Object) int32; — Object is not marshallable in v1. 
GS0324 Error Function {name} is annotated @DllImport but has a managed body; P/Invoke declarations must use a ; body. @DllImport("libc") func F() int32 { return 0 }. 
GS0325 Error Function {name} has no body; only @DllImport- or @LibraryImport-annotated functions may use a ; body marker. func F() int32; with neither @DllImport nor @LibraryImport. 
GS0326 Error @DllImport or @LibraryImport (the attribute actually used) is not supported on this function shape ({reason}). @DllImport("libc") async func F() int32; — async functions, generic functions, instance/extension methods, members of generic types, and ref-returning functions are all disallowed. A static member in a class or struct shared { … } block is supported. 
GS0327 Error @DllImport CharSet value {value} is not recognised; valid values are CharSet.Ansi, CharSet.Unicode, CharSet.Auto, and CharSet.None. @DllImport("libc", CharSet: "Utf8"). 
GS0328 Error @DllImport CallingConvention value {value} is not recognised; valid values are CallingConvention.Winapi, Cdecl, StdCall, ThisCall, and FastCall. @DllImport("libc", CallingConvention: "MyCall"). 
GS0329 Error @DllImport EntryPoint must be a non-empty string. @DllImport("libc", EntryPoint: ""). 

The codes above also fire for the modern @LibraryImport attribute wherever they apply (@LibraryImport reuses the same library-name, body-shape, unsupported-type, and EntryPoint checks). CharSet (GS0327) and CallingConvention (GS0328) cannot fire under @LibraryImport because those knobs do not exist on the attribute — use StringMarshalling: (GS0343 / GS0344) and [UnmanagedCallConv] instead.

The supported v1 marshalling table is: every primitive integer (int8/16/32/64, uint8/16/32/64), nint/nuint, float32/float64, bool, char, string (governed by CharSet), single-element-typed *T byref-style pointers (*T where T is primitive), and slices of primitives. Anything else surfaces as GS0323.

Cause/fix:

  • GS0322 — supply the library name: @DllImport("libc").
  • GS0323 — change the parameter or return to a supported marshalling type; struct marshalling, function-pointer marshalling, and custom marshallers are not supported in this release.
  • GS0324 — drop the function body and replace it with ;, or remove the @DllImport annotation.
  • GS0325 — add @DllImport("libname") or @LibraryImport("libname") above the declaration, or replace the ; with a managed body { ... }.
  • GS0326 — make the function a plain top-level func or a static member of a non-generic class or struct (inside its shared { … } block): not async, not generic, no receiver, not an instance method, no ref return.
  • GS0327 / GS0328 — use one of the documented enum members (e.g. CharSet.Ansi, CallingConvention.Cdecl).
  • GS0329 — EntryPoint must be a non-empty literal string; omit the argument to default to the G# function's identifier.

See for the worked example, the attribute-knob table (EntryPoint, CharSet, SetLastError, CallingConvention, ExactSpelling, PreserveSig, BestFitMapping, ThrowOnUnmappableChar), and the deferred-features list.

Static-virtual interface-member diagnostics (GS0330–GS0333, GS0396–GS0397)​

See and its revision. The DIM family Lands in; interfaces with C# 11-style static-virtual members. Per, these members are declared inside a shared { … } block on the interface — the same shared { … } Block that hosts static members on classes and structs. A body-less func inside that block is an abstract static-virtual slot; a func carrying a body is a default static-virtual member. Implementers supply the static via their own shared { ... } block; generic methods can dispatch through T.M(...) and the call site resolves to the implementer's static method (constrained. !!T call <iface>::<method> at the CLR level — ECMA-335 II.15.4.2.4 and III.2.1).

ID Severity Description 
GS0330 Error An event is declared inside an interface shared block; interface static events are not supported. 
GS0331 Error <Kind> '<C>' does not implement static-virtual interface method '<I>.<Name>', and the interface provides no default body. 
GS0332 Error <Kind> '<C>' declares instance method '<Name>' but interface '<I>.<Name>' is static-virtual; declare it inside a 'shared { … }' block. 
GS0333 Error A constrained static access through a type parameter either is not a member name or names no static-virtual member on any interface constraint. 
GS0396 Error Retired. Default-bodied static-virtual interface properties (prop Name T { get { … } }) are now supported, so this diagnostic is no longer raised. 
GS0397 Error Type '<C>' does not implement static-virtual interface property '<I>.<Name>' (<detail>). Not raised for a fully default-bodied static property (the interface supplies the body). 

Static-virtual interface members emit the standard CLR shape: the interface's MethodDef carries Static | Virtual | Abstract | NewSlot (no body, RVA = 0) for the abstract case, or Static | Virtual | NewSlot (with a body) for the default case. The implementer declares the method as Static (no Virtual / NewSlot) and is paired to the interface slot via a MethodImpl row (ECMA-335 II.22.27).

Cause/fix:

  • GS0330 — func members, prop (static-virtual property) declarations, and var / let / const static state fields — on both non-generic and generic interfaces — may appear inside an interface's shared { … } block. The diagnostic now fires only for an event member. Move an event out of the shared block.
  • GS0331 — add the missing static override inside the implementer's shared { … } block: class Adder : IAdd { shared { func Add(a int32, b int32) int32 { return a + b } } }, or give the interface method a default body so implementers may omit it.
  • GS0332 — move the method into the implementer's shared { … } block. An instance method cannot satisfy a static-virtual slot because the CLR routes the call through the type, not through an instance receiver.
  • GS0333 — use a member name declared as a static-virtual slot by the receiver type parameter's constraint. For example, func Sum[T IAdd](xs sequence[T]) T { … T.Add(a, b) … } requires T to be constrained by IAdd — the interface that declares the static-virtual Add.
  • GS0396 — retired by. A static-virtual interface property may now carry an accessor body (prop Name T { get { … } }), declaring a non-abstract default static slot; no diagnostic is raised.
  • GS0397 — add the missing static property inside the implementer's shared { … } block with a compatible name, type, and accessor set. Static properties use the same nullable-erasure rule as instance interface properties: get-only reference or unconstrained/class- constrained type-parameter nullability may be covariant, concrete and struct-constrained nullable value types remain distinct, and setters are invariant: struct AppleData : IData { shared { prop Name string { get { return "apple" } } } }.

Private interface helper diagnostics (GS0334–GS0337)​

The DIM family lands in; It with C# 8-style private helper methods inside an interface body. A private helper is part of the interface's own implementation — only sibling members of the same interface may call it. Implementers cannot see the helper and cannot supply an override; the helper is non-virtual and not part of the interface's v-table.

ID Severity Description 
GS0334 Error Private interface member '<I>.<Name>' is not accessible from this context; private helpers are visible only to sibling members of the same interface. 
GS0335 Error Private interface method '<I>.<Name>' must declare a body; abstract private helpers are not allowed. 
GS0336 Error <Kind> '<C>' declares method '<Name>' that clashes with private interface helper '<I>.<Name>'; private interface helpers are interface-internal and cannot be overridden by implementers. 
GS0337 Error Modifier 'private' on interface member '<Name>' of kind '<Kind>' is not supported. The v1 surface accepts 'private' only on instance / static methods. 

Private interface helpers emit the standard CLR shape: MethodAttributes.Private | HideBySig (instance), plus MethodAttributes.Static when combined with's static form. The helper is not stamped Virtual / NewSlot / Abstract and carries an IL body on the interface TypeDef. Sibling default bodies dispatch to the helper via implicit this (instance) or implicit static-self (static).

Cause/fix:

  • GS0334 — remove the call site outside the interface, or expose the helper functionality by adding a public default method on the interface that wraps it. Implementers cannot invoke private helpers because they were never part of the contract; the helper is an implementation detail.
  • GS0335 — supply a body for the helper: private func Helper(x int32) int32 { return x + 1 }. Abstract private helpers do not make sense — implementers cannot satisfy them.
  • GS0336 — rename the implementer's method, or fold the logic into a public method on the interface. The CLR slot the implementer was trying to override is private to the interface and not part of the public contract.
  • GS0337 — restrict private to method members. The v1 surface supports private only on methods.

Explicit-base interface call diagnostics (GS0338–GS0341)​

The explicit-base call syntax base[IFoo].Method(args) for disambiguating default-interface-method (DIM) diamonds. The override may delegate to one — or both — of the inherited defaults rather than re-implement them. The emit shape is a non-virtual call instance R IFoo::Method(...) so the inherited body is invoked directly rather than re-dispatched through the v-table.

ID Severity Description 
GS0338 Error base[IFoo] names an interface not implemented by the enclosing type, or appears outside an instance member. 
GS0339 Error Interface '<I>' does not declare a member named '<Name>' reachable via 'base[<I>]'. 
GS0340 Error Interface member '<I>.<Name>' is abstract; there is no default implementation to delegate to via 'base[<I>]'. 
GS0341 Error Interface member '<I>.<Name>' is a private helper and is not reachable via 'base[<I>]'. 

base[IFoo] may be used inside any instance member (public, private, override, or non-conflicting) of a class that implements IFoo. It is not a statement and never appears outside an instance-member body. Private interface helpers are interface-internal and never exposed through base[IFoo]; that boundary is enforced by GS0341 rather than the helper visibility diagnostic GS0334.

Cause/fix:

  • GS0338 — either add the interface to the enclosing type's implementation set (class C : IFoo { ... }) or remove the base[IFoo] call. A top-level function has no enclosing type and cannot use the syntax.
  • GS0339 — check the spelling, arity, or visibility of the member. base[IFoo] reaches only members declared on IFoo itself (not inherited from another interface and not on a base class).
  • GS0340 — the interface declares the slot but did not supply a default body. There is nothing to delegate to. Either supply a default body on the interface, or implement the body inline in the class.
  • GS0341 — private interface helpers are an internal interface Detail. They are not part of the contract that implementers see and cannot be invoked across the implementer / interface boundary, even via base[IFoo]. Add a public default on the interface that wraps the helper if you need to expose the functionality.

Base-class call diagnostics (GS0383–GS0385, GS0413)​

G# can call the base class implementation of a virtual/overridable member non-virtually from within a derived type using base.Member(args) — the faithful mapping of C# base.M(...) — or the bracketed base[BaseClass].Member(args) form. Both emit ldarg.0 followed by a non-virtual call instance R BaseClass::Member(...), so the nearest base implementation runs without re-dispatching through the v-table (no infinite recursion when called from the override that shadows it). The bracketed selector names the immediate base class; the member is resolved by walking the base chain, so a grandparent's implementation is reached when the immediate base does not declare its own override.

The base class may also be an imported / BCL type. A G# class deriving from a CLR base (e.g. System.IO.Stream, System.IO.MemoryStream, or simply System.Object) can delegate to an inherited virtual member via base.Dispose(disposing), base.ToString(), base.Position, etc. The inherited member is resolved against the class's CLR base type (honoring protected/public accessibility and walking a user → user → BCL chain), and emits the same non-virtual call. A base call into an abstract BCL member that has no implementation to delegate to (e.g. base.Read(...) where System.IO.Stream.Read(byte[],int,int) is abstract) is rejected with GS0413, matching C#'s CS0205.

ID Severity Description 
GS0383 Error 'base' is not valid here: '<T>' must be an instance member of a class that has a base class to use 'base.Member(...)'. 
GS0384 Error Base class '<Base>' does not declare an accessible method named '<Name>' to call via 'base'. 
GS0385 Error 'base[<Type>]' is not valid: '<Type>' is not a base class of '<T>'. Use the immediate base class name, or the plain 'base.Member(...)' form. 
GS0413 Error Cannot call the abstract base member '<Base>.<Name>' via 'base'; it has no base implementation to delegate to. 

Cause/fix:

  • GS0383 — base.Member(...) is only valid inside an instance member of a class, including a function literal nested in one. It fires for top-level functions, shared statics, and structs (no base class), and for a function literal nested in any of those. A class deriving only from System.Object (or any imported/BCL base) does have a base, so base.ToString() and other inherited members are reachable — a missing member there reports GS0384. Move the call into an instance member of a class, or call the member directly.
  • GS0384 — the named member does not exist on any base class (user or BCL). Check the spelling, arity, or accessibility of the member. base reaches only members inherited from a base class.
  • GS0385 — the type named in the brackets is not a base class of the enclosing type. Use the immediate base class name, or prefer the plain base.Member(...) form, which resolves the base chain automatically.
  • GS0413 — the inherited BCL member named is abstract (it declares a virtual slot with no body), so there is no base implementation to call. As in C#, override the member with a concrete body instead of delegating to base.

Abstract member diagnostics (GS0386–GS0388)​

A no-body open func F() R; declared inside an open class is the canonical G# spelling of a C# abstract method: it declares a virtual slot with no implementation. A class that declares (or inherits without overriding) an abstract method is itself abstract — it is emitted with TypeAttributes.Abstract and cannot be instantiated. Concrete (non-open) subclasses must override every inherited abstract member; an open subclass may leave them abstract and remain abstract itself.

open class Shape {
open func Area() float64; // abstract member — no body, just ';'
}

class Circle(R float64) : Shape {
override func Area() float64 { return 3.14159 * R * R }
}

let s Shape = Circle(2.0) // OK — Circle is concrete
Console.WriteLine(s.Area().ToString()) // 12.566… via virtual dispatch
ID Severity Description 
GS0386 Error Cannot create an instance of the abstract type {typeName}. 
GS0387 Error {className} does not implement inherited abstract member {declaringType}.{member}. 
GS0388 Error Abstract method {methodName} must be declared open inside an open class; {className} is not open or the method omits open. 

Cause/fix:

  • GS0386 — an abstract class cannot be constructed (Shape() / new Shape()). Construct a concrete subclass that overrides every abstract member instead. Mirrors C# CS0144.
  • GS0387 — a concrete (non-open) class derives from an abstract base but does not override one of the inherited abstract members. Either provide an override func for the member, or declare the subclass open (it then stays abstract itself). Mirrors C# CS0534.
  • GS0388 — a no-body (abstract) method appeared where it is not permitted. An abstract member must be declared open and may only live inside an open class. Add the open modifier and/or make the enclosing class open, or give the method a { … } body. Mirrors C# CS0513/CS0500.

init() constraint construction diagnostic (GS0389)​

For class / struct / init() constraints and reified generics, a type parameter that carries an init() default-constructor constraint ([T init()]) may be constructed inside the generic body with the call-like spelling T(). The construction lowers to a reified System.Activator.CreateInstance<T>(), which yields a real instance for both reference types with a public parameterless constructor and value types.

ID Severity Description 
GS0389 Error Cannot construct '<T>()' because type parameter '<T>' has no 'init()' constraint; add an 'init()' constraint (e.g. '[<T> init()]') to allow construction. 

Cause/fix:

  • GS0389 — the body constructs a type parameter (T()) that does not declare an init() constraint, so the compiler cannot guarantee an accessible parameterless constructor exists for every instantiation. Add an init() constraint to the type parameter (e.g. class Factory[T init()] or func make[T init()]()). Mirrors C# CS0304. Note that a type argument that cannot satisfy the init() constraint (e.g. a class whose only constructor takes parameters) is reported separately as GS0152 at the instantiation site.

and/or/not pattern combinator diagnostic (GS0390)​

Switch patterns may be combined with the contextual keywords and, or, and not (precedence: not > and > or; parentheses override). A type pattern that introduces a binding variable (<ident> is T) is not allowed under or, nested not, or switch-pattern not, because the variable would not be definitely assigned when the arm runs (mirrors C# CS8780). The boolean is-expression form value is not T name is the exception: name is assigned on the false edge.

ID Severity Description 
GS0390 Error A pattern variable ('<name>') may not be declared under an 'or' or 'not' pattern; it would not be definitely assigned. Use '_' instead. 

Cause/fix:

  • GS0390 — a binding type pattern appears under or, nested not, or switch-pattern not. Replace the binding identifier with _ or restructure the pattern so the binding is definitely assigned.

Interface base-clause diagnostic (GS0391)​

An interface may extend one or more base interfaces via a : A, B clause (mirroring C# interface B : A). Every entry must resolve to an interface — a G# interface or an imported CLR interface.

ID Severity Message 
GS0391 Error Interface '<interfaceName>' cannot declare base type '<baseTypeName>'; an interface may only extend other interfaces. 

Cause/fix:

  • GS0391 — an interface's base clause names a class or struct. Remove the offending entry; an interface may only extend other interfaces.

User-defined conversion operator diagnostics (GS0393–GS0395)​

Conversion operators are declared with func operator implicit (x T) U or func operator explicit (x T) U and emit CLR op_Implicit/op_Explicit.

ID Severity Message 
GS0393 Error A user-defined '<implicit/explicit>' conversion operator must take exactly one by-value parameter (the source operand). 
GS0394 Error A user-defined conversion operator must convert to or from a user type declared in the same package, and its source and target types must differ. 
GS0395 Error Duplicate user-defined conversion operator: a conversion from '<source>' to '<target>' is already declared on this type. 

Cause/fix:

  • GS0393 — the operator declared more or fewer than one parameter. Declare exactly one by-value parameter (the source operand type).
  • GS0394 — neither the source nor the target type is a struct owned by the current package, or the source and target types are the same. Make at least one side an owned struct and ensure the two types differ.
  • GS0395 — a conversion with the same source/target pair already exists. Remove the duplicate (a source/target pair may have only one conversion, implicit or explicit).

@LibraryImport P/Invoke diagnostics (GS0342–GS0344)​

G# accepts the modern source-generator-shaped @LibraryImport(...) attribute on ;-bodied func declarations. The compiler emits an explicit managed marshalling stub (outer wrapper) that calls a hidden blittable inner P/Invoke, so the runtime never auto-marshals at the unmanaged boundary. The attribute reuses the same library-name, body-shape, unsupported-type, and EntryPoint checks as @DllImport (GS0322–GS0329); the codes below cover the surface that is unique to @LibraryImport.

ID Severity Description 
GS0342 Error Function {name} is annotated with both @DllImport and @LibraryImport; choose one. 
GS0343 Error StringMarshalling value {value} is not a valid StringMarshalling member; use Utf8 or Utf16. 
GS0344 Error @LibraryImport function {name} has a string surface (parameter or return) and must specify StringMarshalling: StringMarshalling.Utf8 or StringMarshalling.Utf16. 

Cause/fix:

  • GS0342 — pick exactly one P/Invoke attribute per declaration. @DllImport and @LibraryImport express the same intent through two different emit pipelines; mixing them is ambiguous.
  • GS0343 — only StringMarshalling.Utf8 and StringMarshalling.Utf16 are accepted in v1. Custom (and StringMarshallingCustomType) is reserved for future custom-marshaller support.
  • GS0344 — supply an explicit StringMarshalling argument whenever any string parameter or a string return is present. Unlike @DllImport, the modern attribute does not assume a default encoding.

string return types are supported: the inner P/Invoke returns the raw native pointer and the outer stub materializes the managed string via Marshal.PtrToStringUTF8/PtrToStringUni per StringMarshalling. The returned native buffer is treated as non-owning (e.g. getenv, whose result points into the process environ) and is never freed; a callee with caller-frees semantics should return nint and free explicitly. The retired GS0345 code (which used to reject a string return) is no longer emitted and is not reused.

Struct / class P/Invoke marshalling diagnostics (GS0346–GS0351)​

G# accepts @StructLayout(LayoutKind.…) on struct and class declarations, and @FieldOffset(N) on the fields of an Explicit-layout type. Both attributes are CLR pseudo-custom attributes — the runtime reconstructs them at reflection time from the ClassLayout and FieldLayout metadata-table rows, so the emitter writes those rows directly and skips the normal CustomAttribute round-trip. The diagnostics below cover the surface unique to struct / class marshalling; existing P/Invoke type-check codes (GS0322–GS0329 for @DllImport, GS0342–GS0344 for @LibraryImport) continue to apply for the surrounding signature.

ID Severity Description 
GS0346 Error @StructLayout(LayoutKind.{value}) is not supported; v1 accepts only LayoutKind.Sequential and LayoutKind.Explicit. LayoutKind.Auto is rejected because the CLR may reorder fields, breaking ABI. 
GS0347 Error Field {field} of explicit-layout struct {type} is missing a @FieldOffset(N) annotation; every field of an Explicit-layout type must carry one. 
GS0348 Error @FieldOffset on field {field} of {type} is only valid inside an Explicit-layout type; declare @StructLayout(LayoutKind.Explicit) on the enclosing struct or drop the annotation. 
GS0349 Error Type {type} is not blittable and cannot appear in a P/Invoke signature without per-field @MarshalAs (deferred); rewrite the type to use blittable fields only. 
GS0350 Error @FieldOffset({value}) value is not a valid non-negative int32. 
GS0351 Error Class {type} cannot be used as the return type of a P/Invoke function; return a struct or nint instead. 

Cause/fix:

  • GS0346 — LayoutKind.Auto is rejected because the CLR is free to reorder fields, which breaks the bit-for-bit ABI contract the native side relies on. Pick Sequential for "matches the C declaration order" or Explicit for "I'm describing a union or padded layout".
  • GS0347 — Explicit layout means every field's offset is your responsibility; an unannotated field would land at offset 0 by default and silently alias the first explicitly-placed field. Add the intended @FieldOffset(N).
  • GS0348 — @FieldOffset only has a defined meaning inside an Explicit-layout type. On a Sequential-layout type the CLR computes offsets from the declaration order and Pack setting; carrying the attribute would be misleading.
  • GS0349 — blittability is checked recursively: a type is blittable iff every field is a primitive integer / float, a pointer (*T), or a blittable nested struct. bool, char, string, decimal, slices, sequences, and unannotated classes are non-blittable in v1. Per-field [MarshalAs] is not supported in this release.
  • GS0350 — @FieldOffset accepts a non-negative int32 literal (typically 0, 4, 8, …); other forms (negative, non-integer, expression) are rejected.
  • GS0351 — classes can only be marshalled by reference across the P/Invoke boundary; returning a managed object reference from a native function requires a deallocator contract that v1 does not surface. Return a struct or pass an nint and reconstruct the object on the managed side.

P/Invoke ref / out / in parameter diagnostic (GS0352)​

G# now accepts ref T, out T, and in T parameters on a @DllImport or @LibraryImport declaration, provided the pointee type T is blittable. The runtime marshals the byref slot as T* to the unmanaged callee, which is the canonical shape for libc APIs like time(time_t *), clock_gettime(int, struct timespec *), and pipe(int [2]).

ID Severity Description 
GS0352 Error 'ref'/'out'/'in' parameter <name> requires a blittable pointee; <T> is not blittable. Use a blittable primitive (int8…int64, nint/nuint, float32/float64), or a struct annotated with @StructLayout(LayoutKind.Sequential). 

Cause/fix:

  • ref bool / ref char is rejected. The unmanaged width of BOOL is 4 bytes on Windows and 1 byte on POSIX; char is 1 byte natively but 2 in the CLR. There is no portable byref encoding without an explicit @MarshalAs. Declare the parameter as ref uint8 (POSIX) or ref int32 (Windows) and widen in user code.
  • ref string is rejected. Strings need an explicit CoTaskMem allocate-before / free-after round trip; the byref slot would carry ownership ambiguity. Use ref nint together with Marshal.StringToCoTaskMemUTF8 and Marshal.PtrToStringUTF8.
  • ref T? (nullable) is rejected. The Nullable<T> layout ({ T value; bool hasValue }) is not blittable; passing the address would expose the hasValue byte to the unmanaged side, which has no contract for it.
  • ref C for a class C is rejected. Classes already flow as Pointers when annotated with @StructLayout. Adding a ref-kind on top produces a double indirection (<TypeDef>**) that the runtime marshaller cannot handle. Drop the ref-kind on a class parameter.

When the pointee is a struct, blittability is checked by the same BlittableDetector used for the by-value struct path and the diagnostic falls through to GS0349 instead — the remediation is identical (add @StructLayout(LayoutKind.Sequential) and confirm every field is blittable).

The historical GS0326 ("ref/out/in parameter is not supported") path for ref-kind parameters is retired. GS0326 still fires for the remaining function-shape constraints (async / generic / instance / extension / shared / ref-return).

P/Invoke function-pointer marshalling diagnostics (GS0353 – GS0356)​

G# now supports passing managed callbacks and raw unmanaged function pointers across the P/Invoke boundary via two complementary shapes:

  • Shape A — delegate types annotated with @UnmanagedFunctionPointer(CallingConvention.Cdecl). Pass an instance of the delegate as a parameter; the runtime synthesizes a stable C-ABI thunk and keeps the delegate alive for the duration of Marshal.GetFunctionPointerForDelegate + the inner native call.
  • Shape B — raw function pointers spelled unmanaged[Cdecl] (T1, T2, ...) -> R. Encoded as ELEMENT_TYPE_FNPTR in the metadata blob; the runtime value is an address-sized integer (interconvertible with nint).
ID Severity Description 
GS0353 Error Delegate-typed P/Invoke parameter <name> of type <T> requires the delegate declaration to be annotated with @UnmanagedFunctionPointer(CallingConvention.Cdecl) (or a matching calling convention). 
GS0354 Error Unknown calling convention <name> on an unmanaged function-pointer type clause: no System.Runtime.CompilerServices.CallConv<name> type is available in the compilation's references. Use one of the legacy conventions (Cdecl, Stdcall, Thiscall, Fastcall) or a name with a matching CallConv type. 
GS0355 Error Returning a managed delegate <T> from a P/Invoke declaration is not supported. Declare the return as unmanaged[CC] (...) -> R (a raw function pointer) or nint and wrap manually with Marshal.GetDelegateForFunctionPointer. 
GS0356 Retired Previously: raw function-pointer type clause is missing its calling-convention slot. The slot is now optional — bare unmanaged (...) -> R is the platform-default unmanaged calling convention; this diagnostic is no longer emitted. 

Cause/fix:

  • GS0353 — missing @UnmanagedFunctionPointer. A G# delegate passed to a native callback parameter is marshalled through a runtime-synthesized thunk that needs an explicit calling convention. Add @UnmanagedFunctionPointer(CallingConvention.Cdecl) on the delegate Name(...) R declaration.;
  • GS0354 — unknown calling convention. A convention identifier must be one of the four legacy names or resolve to a System.Runtime.CompilerServices.CallConv<Name> type in the compilation's references. Cdecl is the right choice for almost all libc-style APIs; pick Stdcall only for the legacy Win32 ABI.
  • GS0355 — delegate-typed return. The runtime cannot conjure a managed wrapper for an arbitrary native function pointer because it has no contract for who owns the pointer's lifetime. Switch the return to unmanaged[CC] (...) -> R for a raw FNPTR, or to nint if the caller will wrap manually.
  • GS0356 — retired. The [CC] slot is now optional: bare unmanaged (...) -> R is the platform-default unmanaged calling convention, encoded exactly as C#'s bare delegate* unmanaged<...>.

GC lifetime contract (Shape A): the CLR keeps the delegate rooted for the duration of Marshal.GetFunctionPointerForDelegate + the inner native call. The caller is responsible for holding an explicit reference to the delegate for as long as the native side may call back. The canonical pattern is to assign the delegate to a local or field and call GC.KeepAlive(<delegate>) at the end of the scope.

P/Invoke @MarshalAs parameter override diagnostics (GS0357 – GS0360)​

G# now honours @MarshalAs(UnmanagedType.…) on a P/Invoke parameter (@DllImport or @LibraryImport), emitting a CLR FieldMarshal table row per ECMA-335 II.23.4 so the runtime marshaller picks up the explicit override at the unmanaged boundary. The v1 supported UnmanagedType set is: LPStr, LPWStr, LPUTF8Str, BStr, LPArray, SafeArray, I1, U1, I2, U2, I4, U4, I8, U8, Bool, VariantBool, SysInt, SysUInt, Struct, ByValTStr, ByValArray. Anything else (CustomMarshaler, IUnknown, IDispatch, FunctionPtr, Currency, LPStruct) is rejected.

ID Severity Description 
GS0357 Error @MarshalAs UnmanagedType {value} is not in the v1 supported set. Supported values: LPStr, LPWStr, LPUTF8Str, BStr, LPArray, SafeArray, I1, U1, I2, U2, I4, U4, I8, U8, Bool, VariantBool, SysInt, SysUInt, Struct, ByValTStr, ByValArray. 
GS0358 Error @MarshalAs(UnmanagedType.{X}) is not valid on parameter {name} of type {T}. The per-UnmanagedType type-compatibility table defines which G# types each marshaller accepts. 
GS0359 Error @MarshalAs(UnmanagedType.{X}) on parameter {name} requires the {arg} named argument. ByValTStr and ByValArray require SizeConst:; LPArray requires SizeConst: and/or SizeParamIndex:. 
GS0360 Error @MarshalAs on parameter {name} is not supported: {reason}. Two reasons fire today — the enclosing function is not a P/Invoke declaration, or the parameter is a string on a @LibraryImport (use the function-wide StringMarshalling: knob instead). 

Cause/fix:

  • GS0357 — unsupported UnmanagedType. Pick a value from the v1 supported set above. CustomMarshaler and IUnknown-style COM interop are deliberately deferred; raw function pointers already Have first-class syntax (unmanaged[CC] (...) -> R,).
  • GS0358 — type mismatch. Each UnmanagedType only accepts a narrow set of G# parameter types — strings for LPStr / LPWStr / LPUTF8Str / BStr / ByValTStr; integers (or bool / char) for I1…U8; slices for LPArray / SafeArray / ByValArray; struct values for Struct. Either change the parameter type to match the marshaller, or drop the @MarshalAs and let the default marshalling rule apply.
  • GS0359 — missing required knob. Inline / sized forms need a compile-time element count. ByValTStr(SizeConst: N), ByValArray(SizeConst: N), LPArray(SizeConst: N) or LPArray(SizeParamIndex: i).
  • GS0360 — rejected combination. @MarshalAs has no meaning on a managed (non-P/Invoke) function — the runtime never reads FieldMarshal rows for managed methods. On @LibraryImport string parameters, the function-wide StringMarshalling: knob is the only lever — @LibraryImport(StringMarshalling: StringMarshalling.Utf8) (or Utf16) replaces a per-parameter @MarshalAs(UnmanagedType.LPUTF8Str) / LPWStr.

Pseudo-custom attribute: @MarshalAs is encoded exclusively as a FieldMarshal table row + the HasFieldMarshal flag on the Param row. The emitter does not also write a CustomAttribute row for it — this matches C#'s [MarshalAs] treatment and keeps the metadata byte-for-byte interoperable with ildasm, ILSpy, and decompilers.

Type-parameter class / struct / init() constraint diagnostic (GS0361)​

(the default-constructor flag constraint was renamed from new() to init() by). The bracket-position flag-style constraints ([T class], [T struct], [T init()], plus combinations like [T class init()] and [T IFoo class]) compose freely with each other and with the legacy single-slot any / comparable / sealed-interface bound — except for two combinations that are rejected as mutually exclusive:

Code Severity Message 
GS0361 Error Type parameter <T> carries the mutually exclusive constraints <first> and <second>. The two combinations that fire today are class struct (a type cannot simultaneously be a reference type and a value type) and struct init() (the init() flag is redundant because the CLR's NotNullableValueTypeConstraint already implies DefaultConstructorConstraint per ECMA-335 II.10.1.7). 

Cause/fix:

  • class struct combo. Pick one. Reference-type-only callers want [T class]; value-type-only callers want [T struct]. If you really want "any type", drop both and use [T] (or [T any]).
  • struct init() combo. Drop the explicit init() — struct already requires every type argument to expose a public parameterless constructor at the CLR level. The emitter sets both flag bits whenever it sees struct, so the explicit init() adds nothing.

Target-typed bare default literal diagnostic (GS0362)​

The bare default literal (without an accompanying (T) type clause) takes its type from the surrounding target-typed position: the initializer of let/var with an explicit type clause, the value of return when the enclosing function has a known return type, an argument to a parameter of known type, and a conditional branch typed by its sibling. When no target type is available, GS0362 fires.

Code Severity Message 
GS0362 Error The bare default literal can only be used where its type is known from context. Use default(T) to spell the default value of an explicit type. 

Cause/fix:

  • var x = default with no type clause and no initializer-typed sibling. Either add a type clause (var x int32 = default) or use the typed form (var x = default(int32)).
  • Console.WriteLine(default) against an overloaded method. Pick the overload by writing default(T), where T matches the parameter type you want, or assign the value to a typed local first.
  • return default from a function whose return type cannot be inferred. Annotate the function's return type, or use return default(T) directly.

Variadic-parameter diagnostics (GS0363, GS0364, GS0365)​

(...T parameters) and (variadic slot in anonymous Function-type clauses). The canonical G# spelling for a variadic parameter is name ...T (Go-style: the ellipsis sits between the parameter identifier and the element type); inside the body the parameter has type []T. A signature may declare at most one variadic parameter and it must be the last parameter (see GS0145 above). Variadic declarations are accepted on top-level func declarations and on anonymous function-type clauses of the shape (T1, ...T2) -> R; other declaration sites report GS0146 (see above).

Code Severity Message 
GS0363 Error The C# params keyword is not supported in G#. Use the canonical variadic spelling name ...T (Go-style); inside the function body the parameter has type []T. 
GS0364 Error A function signature may declare at most one variadic parameter. 
GS0365 Error A variadic parameter slot in an anonymous function-type clause must use the slice form []T; got <typeName>. 

Cause/fix:

  • GS0363 — params keyword. Replace params values []T with values...T. The lowering and call-site behaviour are identical; this is purely a spelling decision ( §"Structural rules" explains why the alias was rejected).
  • GS0364 — multiple variadic parameters. Pick the one parameter that should accept the parameter pack and drop the ... from the others. The remaining variadic must be the last parameter (GS0145).
  • GS0365 — variadic slot in (...)-> R is not a slice. In an anonymous function-type clause the ... marker turns the parameter slot into a pack/passthrough call site, so the slot's element type must be a slice. Spell it (...[]T) -> R, not (...T) -> R. The body-side spelling on a real declaration (func f(values ...T)) is unchanged.

Caller-side semantics — the binder packs trailing positional arguments into a fresh []T array; if the caller supplies exactly one trailing []T argument (after generic substitution), it is forwarded unwrapped, preserving array identity. The emitted MethodDef carries [System.ParamArrayAttribute] on the variadic parameter so C# / F# / VB consumers see it as params T[].

Map type-clause spelling removal (GS0366)​

The legacy Go-flavored map type-clause spelling map[K]V (key inside the brackets, value outside) has been removed in v0.2. The canonical G# spelling is map[K,V] with both type arguments inside the brackets, separated by a comma — the same single-bracket / comma-separated shape every other multi-argument type clause already uses (Foo[T1, T2], Dictionary[K, V], func(P1, P2) R, (K, V) tuple). There is no deprecation window; the parser emits GS0366 and the program does not compile.

Code Severity Message 
GS0366 Error The map[K]V type-clause spelling has been removed; use map[{key},{value}] instead. 

Cause/fix:

  • Replace every type-clause occurrence of map[K]V with map[K,V]. The migration is purely syntactic — symbol identity, binding, lowering, and emit are unaffected, and the runtime backing type remains System.Collections.Generic.Dictionary<K, V>.
- var m = map[string]int32{"a": 1}
+ var m = map[string,int32]{"a": 1}

- func makeIndex() map[string]Person { … }
+ func makeIndex() map[string,Person] { … }

- func (self map[K]V) CountKeys() int32 { … }
+ func (self map[K,V]) CountKeys() int32 { … }

Map index/use sites are unchanged — only the type-clause spelling moves. m["a"], len(m), delete(m, k), and the map literal entry form {k: v, …} are all unaffected.

The parser still recognises the legacy shape long enough to emit a span-accurate diagnostic that quotes the exact replacement, so IDE quick-fixes can patch the whole construct in one edit. Mixed-form files produce one GS0366 per legacy occurrence with no cascade errors — the parser binds the recovered shape to the same MapTypeSymbol so downstream binding proceeds unchanged.

Interface property setter-kind mismatch (GS0502)​

ID Severity Description 
GS0502 Error A property implementation uses init where its interface requires set, or vice versa. 

An init accessor has a different CLR signature from set because its return type carries modreq(IsExternalInit). The accessor kinds must match in either direction. A positional data class or data struct member is init-only, so it can satisfy a get-only interface property but not a settable one. Declare the property explicitly with a set accessor. An init-only interface property must instead be implemented with a matching init accessor. Static interface properties cannot declare init accessors.

Nullable delegate invocation diagnostics (GS0503)​

ID Severity Description Example trigger 
GS0503 Error A nullable delegate receiver cannot be called directly without a valid non-null narrowing. func Run(d System.Action[int32]?) { d(1) } 

Use ?(...) for null-safe invocation of a name or member receiver. For an indexed or call-result receiver, use ?.Invoke(...). Alternatively, bind the delegate with if let, or assert non-null with !! before calling.

Interface property type mismatch (GS0504)​

ID Severity Description 
GS0504 Error An ordinary property has a different type from the interface property it would implement. 

The diagnostic names the implementing type and property, the interface property, and both the required and actual types. Get-only properties may erase reference nullability covariantly: a string implementation can satisfy a string? contract. A declared unconstrained T? slot erases to T, so I[int32] requires an int32 implementation, not int32?. Settable properties remain source-nullability invariant, and their emitted slot type must also match. The same erasure rule applies recursively inside slices, arrays, and generic constructions. Declared value-type nullability is never erased: int32 cannot implement a get-only int32? property because the CLR types are System.Int32 and System.Nullable<System.Int32>.

Suspension inside fixed statement (GS0506)​

ID Severity Description 
GS0506 Error An await, await for, await using, or yield suspension point appears inside a fixed statement. 

A pinned region cannot survive an async or iterator suspension because the generated state machine would have to resume by branching into the protected region. Move the suspension point outside the fixed statement. Suspension in a lambda declared inside fixed remains valid because the lambda runs in a different method.

Fixed statement over an already-fixed buffer (GS0507)​

ID Severity Description 
GS0507 Error A fixed statement pins a fixed-size buffer field reached through an already-fixed variable. 

A fixed statement may pin a fixed-size buffer field (fixed p *int8 = h.B.Name { … }) only when the buffer lives in movable storage: a field of a class instance, an array or slice element, a ref/out/in parameter, or the receiver this of a struct method. When the buffer is reached through storage that cannot move — a local variable, a by-value parameter, or a pointer dereference (p->Name), or a struct field of one of those — there is nothing to pin; use the buffer directly as a *T pointer instead (var q = local.Name). This mirrors C#'s CS0213.

Unconstrained nullable sequence element (GS0508)​

ID Severity Description 
GS0508 Error A nullable sequence element uses a type parameter that is not constrained to struct or a reference type. 

sequence[T?] needs one stable CLR element representation. Iterator return types are specialized into class and struct variants automatically. Other unconstrained sequence type positions still require an explicit struct, class, or base-class constraint.

A call from another unconstrained generic context cannot select either specialized iterator variant. Constrain the enclosing type parameter to struct, class, or a base class. Named or explicit arguments do not resolve that call: in this case it reports GS0266, and a nullable value-type argument may instead report GS0152. G# rejects source overloads differentiated only by constraints with GS0264, even though iterator specialization synthesizes equivalent variants.

P/Invoke interpreter boundary (GS0514, retired)​

GS0514 marked P/Invoke declarations as unrunnable under the tree-walking interpreter. The evaluator — and with it this diagnostic — was deleted; every driver executes emitted code, where P/Invoke runs natively.

Interpreter deinitializer boundary (GS0510, retired)​

GS0510 warned that a deinit finalizer would not run under interpreted execution. The evaluator — and with it this warning — was deleted; deinitializers run as real CLR finalizers on every driver.

Explicit-layout reference storage (GS0518)​

ID Severity Description 
GS0518 Error An explicit-layout type places a reference-typed field at a misaligned offset or overlaps it with non-reference storage. The CLR rejects both layouts; pointer-align the reference and keep non-reference fields outside its storage. 

ByRefLike interpolation on emitted paths (GS0519)​

ID Severity Description 
GS0519 Error A ByRefLike value without a usable parameterless ToString() method cannot be used as an interpolation hole on emitted execution paths. 

Emitted interpolation routes ByRefLike holes through their user-declared or CLR ToString() method because DefaultInterpolatedStringHandler.AppendFormatted<T> rejects ByRefLike generic arguments. GS0519 is the source-anchored fallback when no usable parameterless method is available, preventing a GS9998 reflection exception.

Channel declaration requires an initializer (GS0520)​

ID Severity Description 
GS0520 Error A chan[T] global or field is declared without an initializer. An auto-created channel has no sensible default (buffer size, ownership), so channels are carved out of the empty-instance zero values; initialize with chan[T]() (rendezvous) or chan[T](capacity), or declare the slot as chan[T]? if the channel is genuinely optional. A local channel declaration is legal without an initializer: locals are flow-checked instead, and only an unassigned use is an error (GS0522 below). 

The other magic collection types (map[K, V], []T, [N]T, sequence[T]) bind a sound empty instance when declared without an initializer; a channel cannot, because bounded-versus-unbounded and capacity are semantic decisions make exists to force. Globals and fields are readable from any function (they are emitted as static or instance fields), so they must initialize at the declaration. A genuinely optional channel is spelled with the parenthesized nullable form (chan T)?: the slot zero value is nil, nil comparison and ?-flow narrowing apply, and make(chan T) assigns into it. A trailing ? without parens binds to the element type — chan int32? is a channel of nullable int32 — consistent with []T? and (T) -> R?.

Channel local possibly used before assignment (GS0522)​

ID Severity Description 
GS0522 Error A use of a channel-typed local is reachable by a control-flow path with no preceding assignment. A bare chan T slot has no zero value, so every path from the declaration to a use must assign it first — e.g. c = make(chan T) or via an out argument position. 

Declaring an uninitialized chan T local is allowed, and the C# CS0165 model applies at use sites — an assignment in only one if arm, only inside a loop body (which may run zero times), or only in a try body (which an exception may skip) does not count; an assignment in every switch/select arm, in a finally, or before the use on every path does. A function literal checks captured channel locals against the assignment state at the capture point. Locals whose types have sound zero values (ints, strings, structs, and the magic collections) keep G#'s documented zero-value initialization and are never flow-checked — this analysis applies only to kinds with no usable zero value.

Pointer generic type arguments (GS0521)​

ID Severity Description 
GS0521 Error Pointer and function-pointer types cannot be used as generic type arguments because the CLR cannot instantiate generic types with them. The called cast[T](x) intrinsic is not a generic instantiation, so cast[*uint8](address) and cast[unmanaged[Cdecl] () -> int32](address) do not report it. 

Nil comparison against a bare collection type is statically constant (GS0523)​

ID Severity Description 
GS0523 Warning A == nil / != nil comparison whose non-nil operand's static type is a bare (non-?) map[K, V], []T, [N]T, [,]T, or chan[T]. With sound empty-instance zero values (and GS0520's mandatory channel initializer) such a value can never be nil, so the comparison is always false (==) or always true (!=) — typically a Go porting artifact. Remove the dead check, or declare the slot with the ? spelling (map[K, V]?, []?T, [,]?T, (chan T)?) if it is genuinely optional. 

The warning is static-type based and fires for both operand orders. It does NOT fire for ?-typed operands (including interop values surfaced as T?, which are the comparison's real use case), nor for a smart-cast-narrowed read of a ?-declared slot — v1 keys on the declared type, leaving a "redundant re-check" nuance as a possible future refinement. sequence[T] is excluded from v1 because bare sequence values commonly cross interop boundaries. Known accepted corners (warning severity, suppressible via /nowarn:GS0523): an explicit = default initializer can reintroduce nil into a bare slot. Recursive collection defaults close the other former corner — a bare struct-typed local's own magic-collection fields — so it no longer applies).

Additional current and reserved diagnostics​

These entries complete the current compiler catalogue. Older topic sections above retain their longer explanations and examples.

ID Severity Description Example trigger 
GS0268 Error Type does not contain a nested type of the requested name. Outer.Missing when Outer exists but declares no nested type named Missing. 
GS0269 Error Unrecognised escape sequence \X in string literal. "\q" — \q is not a valid escape. Use \\ for a literal backslash. 
GS0270 Error The as operator targets a non-nullable value type; use a reference type or nullable value type instead.  
GS0271 Error await using let outside an async function. func f() { await using let x = ... } — await using let requires async func. 
GS0272 Error Type is not async-disposable. await using let x = Foo() where Foo provides no public DisposeAsync() method returning ValueTask. 
GS0274 Error nil is supplied to a non-nullable parameter of an attribute constructor.  
GS0275 Warning .GetAwaiter().GetResult() is called directly on a ValueTask or ValueTask[T]; convert it to Task with .AsTask() first.  
GS0278 Error A convenience initializer does not delegate to another initializer with init(args) before any other statement.  
GS0279 Error A convenience initializer declares : base(args) instead of delegating to another initializer with init(args).  
GS0280 Error An init(args) constructor self-delegation appears outside a class constructor body.  
GS0281 Error A designated initializer delegates to a sibling init(args) overload instead of chaining to its base class.  
GS0282 Error A convenience initializer delegates to itself.  
GS0283 Error No sibling initializer overload matches an init(args) self-delegation call.  
GS0284 Error An explicit init(...) duplicates the constructor synthesized from the type's primary-constructor parameters.  
GS0367 Error A yield appears inside a try block that has a catch clause.  
GS0369 Error A collection initializer targets a type with no accessible Add method or settable indexer.  
GS0370 Error An indexer declaration has no index parameters.  
GS0371 Error An indexer declaration has no get or set accessor body.  
GS0372 Error An init-only property is assigned outside a constructor, object initializer, or init accessor for the same instance.  
GS0373 Error A property declares both set and init accessors.  
GS0374 Error A static property declares an init accessor.  
GS0378 Error Class {name} cannot inherit from itself (e.g. class A : A or the generic class A[T] : A[T]). Naming the enclosing type merely as a type argument of a base/interface type — class Shape : IEquatable[Shape] — is legal.  
GS0381 Error A class participates in a direct or transitive inheritance cycle.  
GS0382 Error Struct {structName} cannot declare base type {baseTypeName}; a struct may only implement interfaces.  
GS0392 Error A range expression slices a type that has no supported array, slice, string, span-like, or System.Range indexer shape.  
GS0410 Retired Previously: a standalone range could not start with a from-end ^ marker. Prefix ^x is now a first-class System.Index expression and one's-complement is ~x, so ^a..^b is valid; this diagnostic is no longer emitted. — 
GS0414 Error An unqualified reference to a shared member is ambiguous between two or more imported types (the G# form of C# using static). Qualify it with the owning type name.  
GS0415 Error The operand of sizeof(T) must be an unmanaged type — a blittable primitive, an enum, a value struct whose fields are all unmanaged, a pointer, or a generic type parameter constrained unmanaged.  
GS0416 Error A list pattern contains more than one slice (..) subpattern.  
GS0417 Error The source nests expressions, types, statements, patterns, or string-interpolation holes more deeply than the compiler's recursion limit. Simplify or flatten the nesting.  
GS0418 Error A using or await using statement uses tuple or named deconstruction instead of one variable declaration.  
GS0419 Reserved Former auto-property-in-data struct diagnostic; auto-properties are now supported in data aggregates. Reserved for compatibility. 
GS0420 Error The argument to nameof must be a name reference: an identifier, member access, or type. nameof(123) or nameof(Console.WriteLine("hi")). Previously misfiled under GS0190. 
GS0421 Error Member is marked open but the enclosing class is not open. class C { open func M() {} } where C is not declared open. Previously misfiled under GS0190. 
GS0422 Error A ref-kind parameter (ref/out/in) cannot appear on an async, sequence, or async sequence function. async func f(ref x int32) { } — the state-machine rewriter cannot hoist a managed pointer into a field. Previously misfiled under GS0226. 
GS0423 Error Type does not implement a usable GetEnumerator() method and cannot be iterated with for ... in. for x in 42 { } where 42's type has no usable GetEnumerator(). Previously misfiled under GS0268. 
GS0424 Error A ref-kind modifier (ref/out/in) is not legal on a primary-constructor parameter. class Vec(ref x int32) { } — primary-constructor parameters materialize fields, and the CLR cannot store a managed pointer in a field. Previously misfiled under GS0241. 
GS0460 Error The operand of a defer statement is a call with one or more ref, out, or in arguments.  
GS0461 Error A lock statement's operand is not a reference type.  
GS0462 Error A generic local function is not declared as a let-bound function literal.  
GS0463 Error A generic local function captures a variable from its enclosing scope.  
GS0465 Error @assembly:InternalsVisibleTo(...) does not contain exactly one string literal naming the friend assembly.  
GS0466 Error A named argument is used on an attribute type declared in the same compilation; use a constructor argument instead.  
GS0467 Error An enum member's explicit = expr value isn't a constant int32 expression.  
GS0468 Error A local function references a type parameter belonging to an enclosing method or class that its emitted method cannot close over.  
GS0469 Error A goto names no label in the enclosing function.  
GS0470 Error Two goto labels in the same function have the same name.  
GS0471 Error An explicit-arity open-generic typeof name resolves to different CLR types from multiple imported namespaces.  
GS0472 Error Code outside the declaring top-level type accesses one of its private members.  
GS0473 Error An expression-tree lambda contains a language construct that cannot be represented in an expression tree.  
GS0474 Error A lambda targets Expression[T] where T is not a delegate type.  
GS0475 Error One declaration in a partial-type group omits partial.  
GS0476 Error Partial declarations disagree on whether the type is a class, struct, or interface.  
GS0477 Error Partial declarations specify conflicting accessibility modifiers.  
GS0478 Error Partial declarations specify conflicting open or sealed modifiers.  
GS0479 Error A data, inline, or ref modifier appears on only some declarations of a partial type.  
GS0480 Error Partial declarations have different type-parameter names, arity, order, or constraints.  
GS0481 Error Partial declarations have conflicting base clauses or more than one base-constructor argument list.  
GS0482 Error More than one partial declaration supplies a primary constructor.  
GS0483 Error A partial type contains more than one deinit.  
GS0484 Error partial is applied to an aggregate kind other than class, struct, or interface.  
GS0485 Error An anonymous object declares an init or deinit member.  
GS0486 Error A field in an anonymous object with a base type, method, or event omits its explicit type.  
GS0487 Error A data class or struct declares ToString with a shape other than public, instance, non-generic, synchronous, parameterless, and returning string.  
GS0490 Error A requested structural projection is unsafe or incomplete; the diagnostic explains the incompatible member or shape.  
GS0492 Error An explicit-interface qualifier clause (func (X) M(...) / prop (X) P T / event (X) E T) references a type that is not an interface.  
GS0493 Error An explicit-interface qualifier clause references an interface the containing type does not implement.  
GS0494 Error An explicit-interface qualifier clause's interface is implemented, but no member on it matches the declared name, signature, or accessor shape.  
GS0495 Error Two members of the same containing type both carry an explicit-interface qualifier clause that resolves to the same interface member.  
GS0496 Error A bare source type name is ambiguous between same-named types declared by multiple imported packages.  
GS0497 Error A function literal is an async iterator; declare a named async iterator and reference it instead.  
GS0498 Error A goto enters a catch or finally handler from outside that handler.  
GS0499 Error A field assignment targets a temporary struct value rather than writable storage.  
GS0500 Error A user-defined compound-assignment operator is not an instance method with exactly one parameter and no return value.  
GS0501 Error Imported metadata exposes multiple public parameterless members with the same name, so reflection lookup is ambiguous.  
GS0505 Error A call cannot choose between compiler-generated reference-type and value-type variants of a nullable iterator because the caller's type parameter is unconstrained.  
GS9008 Error A pointer bound by fixed cannot be captured by a closure because the closure may outlive the pin. A lambda inside fixed p *int32 = xs captures p. 

Rethrow outside a catch handler (GS0570, GS0571)​

ID Severity Meaning Example 
GS0570 Error A rethrow appears where no exception is being handled — outside any catch, or inside a lambda / local function declared in one (the nested body is emitted as its own method, so at run time it is not inside the handler). Use throw <expr> to raise a new exception. func f() { rethrow } 
GS0571 Error A rethrow appears in a finally clause nested inside the enclosing catch handler. By the time that finally runs the CLR has left the handler, so ILOpCode.Rethrow there is unverifiable. Move the rethrow into the catch body, or throw a captured exception. catch (e Exception) { try { … } finally { rethrow } } 

rethrow re-raises the exception the lexically innermost enclosing catch is handling, emitting ILOpCode.Rethrow. Unlike throw <expr>, which emits ILOpCode.Throw and resets StackTrace to the throw site, a rethrow preserves the original throw site. G# spells it with a dedicated keyword rather than C#'s bare throw; because G# statements are not newline-terminated: a bare throw followed by a statement on the next line would parse as throw <that expression>.

Catch clause filters and reachability (GS0572, GS0573)​

ID Severity Meaning Example 
GS0572 Error An await appears in a catch clause's when filter. A filter runs during the CLR's first pass, on the throwing thread, before any unwinding — there is no suspension point available there, so the filter cannot be asynchronous. Move the await into the handler body, or compute the value before the try. catch (e Exception) when await IsTransient(e) { … } 
GS0573 Error A catch clause can never run because an earlier, unfiltered clause already catches its exception type. Reorder the clauses so the more specific type comes first, or delete the shadowed clause. catch (e Exception) { … } catch (e FormatException) { … } 

Catch clauses follow C#. A when filter is emitted as a real CLR filter region, so it is evaluated before any intervening finally and a false filter falls through to the next clause — the same ordering C# gives you. GS0573 only fires when the earlier clause is unfiltered: an earlier clause that carries a when may decline, so a later clause of the same type is genuinely reachable and is not reported.

Stack-only CLR values in the interpreter (GS0511, retired)​

GS0511 marked stack-only (ByRefLike) CLR values the boxed-storage interpreter could not represent. The evaluator — and with it this diagnostic — was deleted; every driver executes emitted code, where ByRefLike values work natively.