Troubleshooting Guide
Common problems and solutions when working with Neuro.
Installation Issues
"No suitable version of LLVM was found"
Symptoms:
error: No suitable version of LLVM was found system-wide or pointed to by LLVM_SYS_231_PREFIX.Cause: LLVM_SYS_231_PREFIX not set or points to wrong location. Neuro requires LLVM 23.
Solution:
Windows:
# Set environment variable (adjust path to your LLVM 23 install)[System.Environment]::SetEnvironmentVariable('LLVM_SYS_231_PREFIX', 'C:\LLVM', 'Machine') # Restart terminal and verify$env:LLVM_SYS_231_PREFIXUnix:
# Add to ~/.bashrc or ~/.zshrc (path varies by distro)
export LLVM_SYS_231_PREFIX=/usr/lib/llvm-23 # Ubuntu/Debian
# export LLVM_SYS_231_PREFIX=/usr # Arch/CachyOS
# Reload shell config
source ~/.bashrc
# Verify
echo $LLVM_SYS_231_PREFIX"LLVMConfig.cmake not found"
Symptoms:
Could not find LLVMConfig.cmakeCause: Installed .exe installer instead of full development package.
Solution:
Download and extract the full development package:
- Windows: the LLVM 23
clang+llvm-23.*-x86_64-pc-windows-msvc.tar.xzarchive - URL: https://github.com/llvm/llvm-project/releases
Do not use the .exe installer: it lacks the development files.
"cannot open input file 'xml2s.lib'" (Windows)
Symptoms:
LINK : fatal error LNK1181: cannot open input file 'xml2s.lib'Cause: LLVM's llvm-config.exe --system-libs names xml2s.lib, because LLVM's
Windows manifest merger uses libxml2. Nothing Neuro calls reaches it, so no libxml2 code
is linked, but the linker still stops when a named library is missing.
Solution: copy any static libxml2 into the LLVM lib directory under that name:
vcpkg install "libxml2[core]:x64-windows-static"Get-ChildItem "<vcpkg-root>\installed\x64-windows-static\lib\*xml2*.lib" | Select-Object -First 1 | Copy-Item -Destination "$env:LLVM_SYS_231_PREFIX\lib\xml2s.lib"Build fails with linker errors (Unix)
Symptoms:
error: linker `cc` not foundCause: Missing C/C++ compiler toolchain.
Solution:
Ubuntu/Debian:
sudo apt-get update
sudo apt-get install build-essentialArch:
sudo pacman -S base-develmacOS:
xcode-select --installmlir-sys fails to build
Every build compiles the mlir-backend slice, which needs MLIR 23 on top of LLVM 23.
Symptoms:
failed to run `".../bin/llvm-config" ...`# orfatal error: 'mlir-c/IR.h' file not found# or, at link timeunable to find library -lMLIR-CCause: mlir-sys finds MLIR by running $MLIR_SYS_230_PREFIX/bin/llvm-config and
reading its lib/ and include/. MLIR has to live in the same prefix as that
llvm-config, and a prefix with no static LLVM libraries makes mlir-sys link the shared
MLIR-C library, which distro packages (Arch's aur/mlir included) do not build.
Solution: use a prefix that holds LLVM and MLIR together: apt.llvm.org's
/usr/lib/llvm-23 with libmlir-23-dev installed, Homebrew's llvm, or a source build of
LLVM 23 with -DLLVM_ENABLE_PROJECTS=mlir. Point all three variables at it. See
Installation → MLIR.
export LLVM_SYS_231_PREFIX=<prefix> # inkwell
export MLIR_SYS_230_PREFIX=<prefix> # melior
export TABLEGEN_230_PREFIX=<prefix> # melior's TableGen macros
cargo test -p mlir-backendIf bindgen reports opaque 1-byte structs (attempt to compute 0_usize - 8_usize), the
libclang it loaded is a different major version from the MLIR headers. Point
LIBCLANG_PATH at a libclang 23.
Compilation Errors
Type Mismatch Errors
Symptoms:
Type errors found in "program.nr":error: type mismatch: expected i32, found f64 --> program.nr:2:5 |2 | val x: i32 = 3.14 | ^^^^^^^^^^^^^^^^^ Error: 1 type error(s) foundCauses:
- Incorrect type in assignment or return
- Mixing integer and float types
- Using wrong type for function argument
Solutions:
Check variable types:
// Error: mixing types
val x: i32 = 10
val y: f64 = 3.14
// val z = x + y // Type mismatch
// Fix: use same types
val x: f64 = 10.0
val y: f64 = 3.14
val z: f64 = x + y // OKCheck function signatures:
func takes_i32(x: i32) -> i32 {
return x
}
// Error: passing wrong type
val y: f64 = 3.14
// takes_i32(y) // Type mismatch
// Fix: use correct type
val x: i32 = 42
takes_i32(x) // OKUndefined Variable Errors
Symptoms:
Type errors found in "program.nr":error: undefined variable 'z' --> program.nr:2:14 |2 | return z + 1 | ^ Error: 1 type error(s) foundCauses:
- Variable not declared before use
- Typo in variable name
- Variable out of scope
Solutions:
Declare before use:
// Error: undefined
// return x
// Fix: declare first
val x: i32 = 42
return xCheck scope:
func scoped() -> i32 {
if true {
val x: i32 = 10
}
// return x // Error: x out of scope
// Fix: declare in correct scope
val x: i32 = 10
if true {
// x is accessible here
}
return x // OK
}Cannot Assign to Immutable Variable
Symptoms:
Type errors found in "program.nr":error: cannot assign to immutable variable 'x' --> program.nr:3:5 |3 | x = 20 | ^^^^^^ Error: 1 type error(s) foundCause: Trying to reassign val variable.
Solution:
Use mut for variables that need to change:
// Error: immutable
val x: i32 = 10
// x = 20 // Error
// Fix: use mut
mut y: i32 = 10
y = 20 // OKMissing Return Statement
Symptoms:
Type errors found in "program.nr":error: missing return statement in function returning i32 --> program.nr:1:1 |1 | func compute(x: i32) -> i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: 1 type error(s) foundCause: Function doesn't return a value on all code paths.
Solutions:
Add missing return:
// Error: missing return for x <= 0
func bad(x: i32) -> i32 {
if x > 0 {
return x
}
// Missing return for else case
}
// Fix: add else branch
func good(x: i32) -> i32 {
if x > 0 {
return x
} else {
return 0
}
}Use implicit return:
func good_implicit(x: i32) -> i32 {
if x > 0 {
x
} else {
0
}
}Parse Errors
Symptoms:
error: unexpected token RightBrace, expected expression --> program.nr:3:1 |3 | } | ^ Error: Parsing failedParse errors stop the run at the first one; only the type checker reports a list.
Common causes:
- A stray semicolon (Neuro has none, see below)
- Unbalanced brackets/braces
- Syntax errors
Solutions:
Remove semicolons: Neuro statements are terminated by a newline, not ;.
A trailing semicolon is an unexpected token Semicolon parse error:
// Error: semicolons are not valid tokens
val x: i32 = 10;
val y: i32 = 20;
// Fix: one statement per line, no `;`
val x: i32 = 10
val y: i32 = 20Check brackets:
// Error: unbalanced braces
func bad() -> i32 {
if true {
return 1
// Missing closing brace
}
// Fix: add missing brace
func good() -> i32 {
if true {
return 1
} // Closing brace added
}Runtime Issues
Executable Doesn't Run (Windows)
Symptoms:
- Executable created but won't run
- "Cannot find DLL" errors
Causes:
- Missing MSVC runtime
- Antivirus blocking execution
Solutions:
Install Visual C++ Redistributable:
- Download from: https://aka.ms/vs/17/release/vc_redist.x64.exe
- Install and restart
Check antivirus:
- Add exception for Neuro executables
- Temporarily disable to test
Permission Denied (Unix)
Symptoms:
bash: ./program: Permission deniedCause: Executable permission not set.
Solution:
chmod +x ./program
./programRuntime Panic
Symptoms:
The program prints a panic: line naming a source position, then aborts (SIGABRT, which a
shell reports as status 134; neurc run reports it as status 1):
panic: division by zero at program.nr:1:33Causes:
- Integer division or remainder by zero. The divisor is checked at every optimization level.
- Integer overflow in a build at
-O0, reported aspanic: integer overflow. From-O1up, arithmetic wraps silently. - An explicit
panic(msg), a failedassert(cond), or a reachedunreachable().
Solutions:
Check the divisor:
func safe_divide(a: i32, b: i32) -> i32 {
if b == 0 {
return 0 // or report the failure through an Option or Result
}
return a / b
}For overflow, .checked_add, .checked_sub and .checked_mul return an Option instead
of panicking; see integer methods.
Runtime Crash (signal)
A program that dies on a signal (SIGSEGV, SIGILL) rather than a panic: line has hit
either unbounded recursion or a compiler bug. Report it with a minimal reproduction:
- GitHub Issues: https://github.com/PanzerPeter/Neuro/issues
Performance Issues
Slow Compilation
Symptoms: Compilation takes longer than expected.
Causes:
- Debug build of compiler
- Large program
- System resource constraints
Solutions:
Use release build:
# Build compiler in release mode
cargo build --release -p neurc
# Use release build
cargo run --release -p neurc -- compile program.nrDevelopment Environment Issues
VSCode Syntax Highlighting Not Working
Symptoms:
.nr files show no syntax highlighting.
Solution:
Install the extension from neuro-language-support/ as described in
Editor Support, then reload the window
(Developer: Reload Window). An editor that was already open does not pick up a new
grammar on its own.
Git Line Ending Issues (Windows)
Symptoms: Git shows all files as modified.
Solution:
# Configure Git for cross-platform development
git config --global core.autocrlf trueDebugging Techniques
Enable Debug Logging
Get detailed compilation information:
# Windows (PowerShell)
$env:RUST_LOG="debug"
neurc compile program.nr 2> debug.log
# Unix
RUST_LOG=debug neurc compile program.nr 2> debug.log
# Review log
cat debug.logIsolate the Problem
Create minimal reproduction:
// Start with simplest program
func main() -> i32 {
return 0
}
// Gradually add code until error appearsCheck Each Stage
Test compilation stages separately:
# 1. Check syntax only
neurc check program.nr
# 2. If check passes, try compile
neurc compile program.nr
# 3. If compile passes, try run
./programGetting Help
Before Asking for Help
- Check this troubleshooting guide
- Search GitHub issues
- Enable debug logging
- Create minimal reproduction
- Review CONTRIBUTING.md for development and reporting guidelines
Reporting Issues
Include in bug reports:
- Neuro compiler version
- Operating system and version
- LLVM version
- Rust version
- Complete error message
- Minimal reproduction case
- Steps to reproduce
Template:
## Environment- OS: Windows 11 / Ubuntu 22.04 / macOS 13- Neuro: version from `neurc --version` (and commit hash)- LLVM: 23.x- Rust: 1.98.1+ ## Issue[Description] ## Reproduction[Minimal .nr file that reproduces the issue] ## Expected[What should happen] ## Actual[What actually happens] ## Error Output```text[Complete error message with debug logging]```Resources
- GitHub Issues: https://github.com/PanzerPeter/Neuro/issues
- Documentation: README.md
- Development Guidelines: CONTRIBUTING.md
Known Limitations
Features that are planned but not built yet are on the
Quick Roadmap. Each language reference page states the
limits of the feature it covers. The one that surprises people most often: an interpolation
hole cannot contain a string literal. "{"lit"}" is a lexical error; bind the string to a name
first and interpolate the name.
Common Warnings
The compiler currently emits two warnings. Warnings never block compilation.
prefer-loop-over-while-true
Message:
warning[prefer-loop-over-while-true] at 24..28: `while true { ... }` should be written as `loop { ... }`; silence with `@allow(prefer_loop_over_while_true)` on the enclosing functionCause: A while loop whose condition is the literal true. loop { ... } says the same
thing and is the idiomatic form.
Solution:
// Triggers the lint
while true {
break
}
// Preferred
loop {
break
}Silence it with @allow(prefer_loop_over_while_true) on the enclosing function when the literal
form reads better.
float-cast-out-of-range
Message:
warning[float-cast-out-of-range] at 42..53: constant `1e20` does not fit `i32` and saturates to its maximum; use `.to_checked::<i32>()` for an `Option`, or silence with `@allow(float_cast_out_of_range)` on the enclosing function or `const`Cause: An as cast from a float to an integer type whose operand is a constant the target
cannot hold, or NaN. The cast clamps it to the type's minimum or maximum (NaN becomes 0),
which is rarely the value the author meant.
Solution: Fix the constant or widen the target type. Where the program computes the value
at run time, .to_checked::<T>() returns None for it instead of clamping. If the clamp is
what you want, add @allow(float_cast_out_of_range) to the enclosing function or method, or
to the const whose initializer holds the cast.
FAQ
Why does my program compile but do nothing?
Check that main returns the expected exit code and performs desired operations.
Why can't I mix i32 and i64?
Neuro uses strict typing with no implicit conversions. Convert explicitly with an as
cast: val wide: i64 = narrow as i64.
Why is compilation slow?
Use -O0 for fastest compile/debug loops and -O2/-O3 for faster runtime binaries.
How do I speed up development?
Use neurc check for rapid feedback without code generation.
Can I use Neuro for production?
Not yet. The language is alpha, and its syntax and semantics can still change between releases. The Quick Roadmap shows what is complete and what is ahead.
Still Stuck?
If this guide doesn't solve your problem:
- Check CLI Usage Guide
- Review Language Reference
- Search or create GitHub Issue
- Include all requested information in bug reports