Languages & compilers

Rustlyn

Build C# language intelligence in a native Rust server.

Recorded result

Explore the example
var x = missingName;Unresolved value at bytes 8..19
From the example below.

Why I’m interested

An editor needs more than syntax highlighting to understand C#. It has to resolve names, track types, load project inputs, and point diagnostics at the right source. Rustlyn brings those problems into a native Rust language server, with managed compatibility at the runtime boundary. The interesting part is how the language semantics become useful editor behavior.

Progress

The repository contains binder, project, and editor infrastructure. The binder example below records an unresolved name, its owning expression, and its exact source range. The next integration connects that semantic result to a live editor and a prepared project.

Trace a diagnostic back to its source

An unresolved name needs a useful location. Inspect the name, the bound expression, and the source range the Rustlyn binder attaches to it.

Choose an example

Keep the error attached to its source

The binder records missingName as an unresolved value and keeps its byte range, 8..19, with the error. The source line shows where that range points.

var x = missingName;Unresolved value at bytes 8..19
Lookup
Value
Source span
11 bytes

Input

var x = missingName;
        ^^^^^^^^^^^

Result

ResolveLookup::Value
ResolveFailureReason::NotFound
name: missingName
range: 8..19

One error, one owning source

The bound expression owns the resolution failure. The caller reads that error directly instead of repeating the name lookup.

Input

expression → owning body → source range

Result

bound_body.resolution_failure_for_expr(...)
  → NotFound { lookup: Value, name: missingName }

The native binder fixture constructs the unresolved expression and records its assigned range. The C# line illustrates that range. The next integration connects the result to a live editor.

What comes next

Load a prepared project in a live editor and trace its diagnostic back to the binder result.

Implementation and credits

How does a name-resolution failure become an editor diagnostic?

The example shows an unresolved-name result from the native Rustlyn binder and the source range attached to it.

Inspect the unresolved name, its byte range, and the bound expression that owns the error.

The native Rust binder supplies the result. Rust generates the page for inspection.

Independent work with Roslyn and other language servers as references.

Back to the collection