Release notes
G# is pre-1.0. The repository's version base is currently 0.3, and product versions are derived by Nerdbank.GitVersioning from that base and the Git commit. Until the project reaches a stable compatibility promise, release notes should be read as implementation status notes rather than a long-term compatibility contract.
0.3
The third pre-1.0 line is a breadth-and-interop release. The language gains a large batch of C#-parity expression and declaration constructs, an unsafe pointer surface, partial types, and anonymous-object literals. Tooling adds the cs2gs C#→G# migration tool and the gsgen Roslyn source-generator host for native G# projects. The language server gains incremental binding, an incremental semantic-model pipeline, and a cross-session cold-start cache. This release also cuts a fresh 0.3 docs snapshot from the live docs and retires the 0.2 snapshot.
Highlights
- Unsafe pointer surface. An
unsafecontext now supports unmanaged raw pointers*T,stackalloc [n]Tproducing either safeSpan[T]or unsafe*Tstorage, thefixedpinning statement, theunmanagedtype-parameter constraint,sizeof(T), and pointer compound-assignment and cast lowering. - New expression and statement forms. Throw expressions, value-producing increment and decrement expressions
++/--, from-end indexes^n, standaloneSystem.Rangevalues such as1..3, expression-bodied members via->, generalgoto/ labels, collection initializersList[T]{…}/HashSet[T]{…}/Dictionary[K,V]{…}, and inferred-type arrow lambdas with statement-block bodies. - New declaration forms.
partialclasses, structs, and interfaces; anonymous-object literalsobject { … }; nested type declarations; user-defined conversion operatorsoperator implicit/operator explicit; user indexer membersprop this[i int32] T { get; set }; theshared { init { … } }static-initializer block; static imports throughimport Ns.Type; and top-levelprivatemapping to ILassembly/ internal. cs2gsC#→G# migration. The new translator lowers C# source to canonical G#, with construct coverage, gap triage, and a build-time strategy that reproduces generated code rather than freezing it. See the new cs2gs tooling page.- Source generators for native G#. The
gsgenhost runs Roslyn analyzers and generators against native G# projects.gsc /analyzer:<asm>spawnsgsgenas a sibling before compiling. A shared resx codebehind generator emitsResources.Designer.gs. - Language-server performance. Incremental binding, instance-keyed semantic-model memoization, a cross-session cold-start cache, completion-as-you-type triggering, and unified member resolution reduce repeated work across binder and LSP flows.
- Diagnostics catalogue extended. v0.3 adds diagnostics through the
GS04xxrange. The Diagnostics reference is reconciled against the compiler source and lists the current per-ID cause and fix detail.
Added
- Null-coalescing operator respelled
??. The null-coalescing operator isa ?? b. The earlier?:spelling is retired in that role;cond ? a : bremains the ternary expression. - Runtime array allocation
[n]T. A length-bearing[n]Tallocates a zero-initialised array at runtime, complementing array literals. - Nullable array-element spelling.
[]T?is an array of nullable elements;[]?Tis a nullable array. - Nullable function-type spelling. Nullable function types are spelled and displayed with the appropriate parenthesisation.
- Expression-tree lambda conversions. A lambda converts to
Expression[TDelegate]where the target demands an expression tree. - Delegate return-type covariance. Delegate return types can be covariant, including lambda target-typing on CLR method calls.
- Predefined type aliases as static-member receivers. Friendly numeric aliases can be used as receivers for static member access.
- Assembly-attribute parity with C#. Assembly-level attributes are accepted with C#-equivalent behavior.
Changed
- C#-compatible numeric conversions. Numeric literal narrowing and widening, plus implicit numeric promotion at call sites, now align with C# behavior.
- Unannotated imported reference types are nullable by default. Imported reference types without nullable annotations bind as nullable.
charbitwise and shift operators promote toint32. Enum==/!=comparisons against the integer literal0are also permitted.- The website spec, feature matrix, diagnostics reference, CLR-interop reference, guides, tour, tutorials, and tooling docs were refreshed to match compiler ground truth for the 0.3 surface; a new
cs2gstooling page was added. - The Docusaurus site cuts a new
0.3snapshot from the live docs and retires the0.2snapshot. The version dropdown lists0.3andNext.
Fixed
- Extensive
cs2gstranslator hardening across nullability promotion, extension-call lowering, deconstruction and indexer targets, pattern binding, named-argument lowering, and source-generator-shaped constructs. - Numerous
gscbinder, emitter, and interpreter correctness fixes across imported generic interface methods, nullable value-tuple boxing,data classequality andwith, overload resolution, async lambda inference, and smart-cast narrowing.
Known limitations
gsc --helpadvertises/implicitimports[+|-]; the+/-suffix form is not currently accepted by the Release parser. Use/noimplicitimports.- Migration coverage in
cs2gsis still expanding. C# source generators are reproduced at build time rather than translated, and some constructs remain on the gap-triage backlog.
0.2
The second pre-1.0 line is a syntax-and-ergonomics release. The parser, binder, and emitter absorb substantial additions; several legacy Go-flavored spellings are retired in favour of canonical G# forms; and the native-interop and default-interface-method surfaces ship end-to-end. This release also formally introduces docs versioning: the 0.1 snapshot is removed and a fresh 0.2 snapshot is cut from the live docs.
Highlights
- New language surface.
while/do…whileloops with labeledbreak/continue;if let/guard letsmart-cast bindings; null-coalescing compound assignment??=; null-conditional indexinga?[i]; arrow lambdasx => body; canonical(T1, T2) -> Rfunction-type clauses; lambda binding-type inference; Kotlin/Swift-style type-declaration grammar; if-as-expression completion; smart-cast extensions; discriminated-union enum payloads;default(T)and target-typed baredefault; variadic...Tparameters in function and anonymous function-type clauses;class/struct/init()constraint flag spellings; default-interface methods; reified generics;Gsharp.Extensions.OptionalandGsharp.Extensions.Sequences; friendly numeric type aliases; and the canonical map type clausemap[K,V]. - Removals and migrations. Legacy spellings now produce focused, span-accurate diagnostics with canonical replacements so IDE quick-fixes can patch most migrations in one edit.
typekeyword for type declarations (type Foo struct { … }→struct Foo { … }).recordkeyword, replaced bydata classordata struct.:=short variable declaration, replaced bylet/var, with diagnosticGS0305.name = valuenamed-argument separator, replaced byname: value, with diagnosticGS0315.func(T) Rlegacy function-type clause, replaced by(T) -> R, with diagnosticGS0303.- Go-flavored
map[K]Vtype clause, replaced bymap[K,V], with diagnosticGS0366. static funcon interface methods is removed. Static-virtual interface members now live inside the interfaceshared { … }block. A body-lessfuncinside that block is an abstract static-virtual slot; afuncwith a body is the default. Static private helpers also move into theshared { … }block asprivate func, while instance private helpers stay directly in the interface body. The oldstatic func …shape now produces a parser error, andGS0330fires when a non-funcmember appears inside an interfaceshared { … }block.
- Body-less
funcnow requires;. Afuncdeclaration without a{ … }block is terminated by the universal no-body marker;. This already held for P/Invoke (func getpid() int32;) and now also applies to abstract interface methods and abstract static-virtual slots inside an interfaceshared { … }block. A body-less interfacefuncmissing its;reportsGS0368; afunccarrying a body still takes no;. - Native interop end-to-end. P/Invoke via
@DllImport, source-generator-shaped@LibraryImport, struct and class marshalling,ref/out/inparameter marshalling, function-pointer marshalling, and@MarshalAsparameter overrides are supported. - Go-flavored concurrency moved behind an opt-in import.
go,chan,select, channel send and receive,make(chan T), and the built-inslen,cap,append,make, anddeletenow requireimport Gsharp.Extensions.Go. DiagnosticsGS0316/GS0317point at the missing import. - Tooling polish. LSP completion understands async-shaped types such as
async (T) -> Randasync sequence[T];textDocument/codeActionoffers nil-related quick fixes; andnullnow produces anil"did you mean" diagnosticGS0273. - Diagnostics catalogue extended. v0.2 introduces
GS0273andGS0288–GS0366. The Diagnostics reference has the per-ID cause and fix detail.
Added
- Friendly numeric type aliases.
int,uint,long,ulong,short,ushort,byte,sbyte,float, anddoubleare accepted everywhere a type name is accepted, as a strict superset on top of the canonical width-bearing names (int32,uint32, …). The alias resolves to the canonicalTypeSymbolat the binder, so diagnostics,typeof,nameof, hover, and emitted IL always print the canonical spelling. Canonical names remain preferred in documentation and public library APIs; aliases are appropriate inside function bodies and local code. Aliases are reserved type names, sotype int = stringand equivalents are rejected withGS0102. - Null-conditional indexing
a?[i].a?[i]evaluates receiveraexactly once. If it isnil, the whole expression yieldsnil; otherwise the result is the indexed value lifted to the nullable form of the indexer's return type. It works on arrays, slices, maps, and CLR indexers on both emit and interpreter paths. Chained forms (h?.Data?[i]?.c) short-circuit on the first nil. The new token?[is recognized only when[immediately follows?, preservingcond ? [arr] : [arr]ternary parses. DiagnosticsGS0300andGS0301cover non-nullable receivers and assignment left-hand sides. - Documentation comments. Markdown-authored
///documentation comments round-trip losslessly to CLR XML doc. Hover renders merged documentation for both G# declarations and imported CLR APIs. New warnings includeGS0227,GS0228,GS0229,GS0230, andGS0231. - Named delegate types.
type Name = delegate func(...)declares a real CLRMulticastDelegate-derived type so C# consumers see a conventional handler type and G# events can carry first-class custom delegate types. DiagnosticsGS0233–GS0234cover invalid forms. ref/out/inparameters. Declaration-site and call-site ref-kind modifiers are supported, including inlineout var/out let/out _declarations. DiagnosticsGS0235–GS0243cover the rules. Passing a value to aninparameter without writinginat the call site is warningGS0242rather than a silent spill.- Ref-aliasing locals.
let ref m = arr[i]andvar ref v = c.Fieldproduce locals whose IL slots areT&and alias another lvalue. DiagnosticsGS0256–GS0258cover invalid aliases. - Ref returns.
func f(...) ref T { return ref <expr> }is supported. DiagnosticsGS0248–GS0255cover escape rules, async and iterator bans, and override matching. - Conditional ref-arguments. The narrow
ref cond ? a : bform is supported inside ref-kind argument payloads. DiagnosticsGS0260–GS0262cover invalid forms. - Generalized ternary expression.
cond ? a : bis now a normal expression.GS0259is retired in value contexts;GS0263covers "no common type" failures. - Method overloading and optional parameters. User G# functions can carry overload sets that differ by parameter types or ref-kinds, and optional parameters can use compile-time-constant defaults. Diagnostics
GS0264–GS0267cover invalid overloads and defaults. - Named arguments at call sites.
Foo(timeout: 30, retries: 3)works for free functions, user methods, user constructors, extension functions, inherited CLR methods, and delegateInvoke. DiagnosticsGS0244–GS0247cover invalid usage. The legacyname = valueform is deprecated this release with diagnosticGS0315; migrate.copy(...)and attribute argument lists alongside ordinary call sites. scopedparameter modifier.scopedconstrains aref structor managed-pointer parameter from escaping, enforced byGS9004/GS9006.data structsynthesis completed. Everydata structsynthesizesEquals(object),Equals(T),GetHashCode(),ToString(),op_Equality,op_Inequality, andDeconstruct(...). Hand-written versions are rejected withGS0232.- Editor features. Hover for CLR XML docs, live pull-based diagnostics, CodeLens reference counts on members of structs, interfaces, and enums, implicit
thisfor properties, methods, and events, hover forthis, bare static-member access from instance methods, chained-member hover, and six VS Code color themes inspired by the G# logo: Ember, Magma, and Synthwave in dark and light variants. :=short variable declaration removed. Every binding site now requiresletfor immutable bindings orvarfor mutable bindings. The lexer still recognizes:=so the parser can emitGS0305with context-sensitive migration suggestions such asx := 1→let x = 1,for i := 0 ... 10→for i in 0 ... 10, andcase v := <-ch→case let v = <-ch.
Changed
- The website spec, feature matrix, FAQ, bridges page, guide pages, and design-decisions index were refreshed to match compiler ground truth. Outdated statements such as "Parameters do not have default-value syntax" and "Named arguments — Partial" were rewritten.
- The repo
docs/lexical.mdblock-comment paragraph is corrected, and a documentation-comments subsection was added. - The VS Code TextMate grammar adds contextual keywords (
data,inline,record,delegate,event,prop,init,shared,scoped, accessor namesget/set/add/remove/raise, and ref-kindsref/out), operators (:=,?.,??,?/:,!!,...,=>), an@Annotationscope, and a///documentation-comment scope with@taghighlighting. The VS Code snippet set was rewritten to match current grammar. - The Docusaurus site cuts a new
0.2snapshot from the live docs and retires the0.1snapshot. The version dropdown lists0.2andNext; the0.1URL space is no longer served.
Fixed
- Numerous IL-emit, determinism, language-server, and editor hardening rounds improve CLR verification, byte-for-byte reproducibility, property access, CodeLens accuracy, and stale-tree handling.
Known limitations
- Full ref-safe-to-escape analysis is partial;
GS0257is reserved for a future pass. - Unsupported async state-machine emit shapes continue to report
GS0190.
0.1
The 0.1 version base identifies the first pre-1.0 line. This is not a dated stable release announcement; it summarizes the major capabilities implemented in the repository at that point.
Language and libraries
- Packages, imports, import aliases, top-level declarations, and multi-file or multi-package compilation.
- Width-bearing primitive names such as
int32,uint64,float32, andfloat64, plusbool,char,string,object,decimal,nint,nuint, andvoid. - Nullable
T?types withnil,?.,??, and!!. - Structs, classes, interfaces, enums,
data struct,recordas adata structalias, andinline structvalue wrappers. - Generic functions and types with square-bracket type parameters and arguments, constraints, method inference, and CLR variance support where applicable.
- Fixed arrays, slices, maps, tuples, function values, delegates,
sequence[T],async sequence[T], and iteratoryieldsupport. - Control flow including
if,for,for inorrangeforms, switches, switch expressions,try,catch,finally,throw,using, anddefer. - Go-shaped concurrency with
go,scope, channels, channel send and receive,make(chan T),close, andselect. async func,await, async lambdas, awaitable-shape support, andawait forover async sequences.- CLR interop for imported constructors, methods, overload resolution, fields, properties, indexers, events, delegates, extension methods, optional CLR arguments, operators, conversions, attributes, and generic types.
Tooling
gsccompiler driver with an interpreter path when no/out:is supplied and an emit path for managed executables or libraries.- Managed PE and metadata emission without Roslyn, optional reference assemblies, target-framework-aware reference resolution, runtime configuration output, and Portable PDB support.
- MSBuild SDK support through
Gsharp.NET.Sdk,.gsprojprojects,dotnet build,dotnet run, templates, and SDK-side response-file invocation. - VS Code extension and language server support for diagnostics, hover, definitions, references, symbols, formatting, completions, signature help, rename, code actions, CodeLens, semantic tokens, inlay hints, and debugging integration.
- Stable diagnostic IDs in the
GS####form, with warning suppression and warning-as-error controls.
Pre-1.0 notes
- The language is still evolving; source compatibility may change before a stable release.
- Some surfaces are intentionally documented as current implementation behavior rather than final specification guarantees.
- The Playground page exists, but browser-hosted execution is deferred.
Future release-note format
Use reverse chronological order. Each version entry should identify the version and, when a real release process exists, its date. Do not invent dates or version numbers; derive versions from the repository's release process. Write for end users: describe what changed, what it means, and any migration steps they should take.
## X.Y.Z
Short summary of the release.
### Added
- New language, tooling, documentation, or interop capabilities users can try.
### Changed
- Behavior changes, breaking changes, renamed features, or migration notes.
### Fixed
- Short grouped quality notes for user-visible correctness, diagnostics, emit, interpreter, or tooling improvements.
### Known limitations
- Important limitations users should know before upgrading.