A Rust compiler written in PHP that emits x86-64 Linux ELF binaries directly (no LLVM, no assembler, no linker). Implements ownership checking, borrow checking, type checking, move semantics, generics, traits, closures, and iterators. Useful if you need to compile Rust on a shared hosting server from 2008 where the only installed runtime is PHP.
In order to execute Rust code you of course first need to install PHP. You can do this easily on Windows 11 by running:
winget install PHP.PHP.8.4
This compiler outputs valid machine code for Linux, so the most practical approach if you're on Windows is to use WSL. Start by installing Ubuntu (if you haven't already):
wsl --install
After the install completes, reboot your machine and then open Ubuntu from the Start menu to finish the initial setup.
Compile a .rs file by running:
php rustc.php main.rs -o main
Then execute the compiled binary through WSL:
wsl ./main
To see the exit code of the program:
wsl ./main; echo $?
Types
i32,bool,u8,u16,u32,u64,u128,usizeString(heap string, move semantics)&strand string slice indexing (s[0])&T,&mut Treferences with borrow checking- Raw pointers
*const Tand*mut T - Structs (named fields, field access, method calls)
- Tuples and tuple destructuring
- Enums with optional tuple payloads and
match - Unit type
()in expressions, return types, and generic arguments - Generics on functions, structs, and
implblocks - Builtin
Option<T>andResult<T, E>withSome/None,Ok/Err(no source definitions required) - Builtin
Box<T>(Box::new, deref) - Generic
alloc::Vec<T>(monomorphized:Vec<i32>,Vec<u8>, etc.;Vec::new(),push, indexingv[i]andv[i] = x; usessize_of::<T>()in alloc crate). Legacyalloc::VecI32also supported.
Control flow
if/else(including as expressions)if letandwhile letwhile,loop,break,continue(including break level)for x in start..end(range iteration)matchwith enum arms, int literals, and wildcard_return
Heap and allocation
- Heap runtime (mmap + bump allocator, free-list for dealloc/realloc)
alloccrate:alloc(),dealloc(),realloc()(only callable from inside thealloccrate)- Generic
alloc::Vec<T>as above
Functions and closures
- Free functions with multiple parameters and explicit return types
const fn(accepted and treated as a regular function)implblocks withself,&self,&mut self- Trait definitions and
impl Trait for Type - Default trait method implementations
- Closures with capture-by-value (
|x: i32| x + captured_var)
Ownership and borrowing
- Move semantics for non-
Copytypes - Borrow and mutable borrow checking
Copyinference fori32,bool,&T, and all-copy structs/enums- Compound assignment (
+=,-=,*=,/=) for variables, derefs, and fields
Modules and syntax
mod name;declarations with file-based module resolutionpubvisibility on functions, structs, and fieldsusepaths for cross-module imports- Top-level
constandstaticitems - Attributes
#[...]and#
Output
println!("{}", expr)— print a single valueexit(code)— explicit exit with status code
Run the full test suite:
php tests/run.php
Test cases live in tests/cases/ organized into fundamentals/valid/, fundamentals/invalid/, modules/, and programs/. Each .rs file declares its expected output in comments at the top:
// exit: 42
// stdout: hello
// error: Use of moved valueRoughly in order of impact:
- User-callable
alloc()outside thealloccrate (heap andalloc::Vec<T>are supported) f32/f64floating point- The
?operator (Result is supported;?is not) - Closures as function arguments (
fn apply(f: impl Fn(i32) -> i32)) - Zero-parameter closures (
|| expr) - Pattern matching beyond single-level enum variants
- Multi-format
println!(only"{}"with one argument is supported) - Lifetimes (borrow checker is simplified — no lifetime annotations)
- Additional signed integer types (
i8,i16,i64,i128)