Skip to content

Commit 1527744

Browse files
committed
Support for impl blocks, and new test confirming this.
1 parent baa89e5 commit 1527744

File tree

12 files changed

+369
-3
lines changed

12 files changed

+369
-3
lines changed

Readme.md

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ All examples live in `tests/binary` and are compiled to JVM bytecode & run/teste
3232
- **[Collatz conjecture](tests/binary/collatz/src/main.rs)** verifier
3333
- **[Large prime](tests/binary/primes/src/main.rs)** generator
3434
- Use of nested data structures: enums, structs, tuples, arrays, slices (**[enums](tests/binary/enums/src/main.rs)**, **[structs](tests/binary/structs/src/main.rs)** - both tests use arrays and tuples)
35+
* **[Implementation blocks](tests/binary/impl/src/main.rs)**
3536
- …and more!
3637

3738
---
@@ -50,6 +51,7 @@ All examples live in `tests/binary` and are compiled to JVM bytecode & run/teste
5051
- Structs, tuples, enums (both C‑like and Rust‑style)
5152
- Executable `.jar` generation for binary crates
5253
- Mutable borrowing, references, and dereferencing
54+
- Implementations for ADTs, including using and returning `self`, `&self`, `&mut self`
5355
- **Integration tests** for all features, in debug and release modes
5456

5557
🚧 **Next Milestone:** Full support for the Rust `core` crate.

Tester.py

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ def process_test(test_dir: str, release_mode: bool):
4545
output = f"STDOUT:\n{proc.stdout}\n\nSTDERR:\n{proc.stderr}"
4646
write_to_file(fail_path, output)
4747
print(f"|---- ❌ cargo build exited with code {proc.returncode}")
48+
print(f"|---- STDERR:")
49+
print(proc.stderr)
4850
return False
4951

5052
print("|--- 🤖 Running with Java...")

src/lib.rs

+50
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use rustc_data_structures::fx::FxIndexMap;
3131
use rustc_metadata::EncodedMetadata;
3232
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
3333
use rustc_middle::ty::TyCtxt;
34+
use rustc_hir::{TyKind as HirTyKind, QPath};
3435
use rustc_session::{Session, config::OutputFilenames};
3536
use std::{any::Any, io::Write, path::Path};
3637

@@ -96,6 +97,55 @@ impl CodegenBackend for MyBackend {
9697
.insert(oomir_function.name.clone(), oomir_function);
9798

9899
oomir_module.merge_data_types(&oomir_result.1);
100+
} else if let rustc_hir::ItemKind::Impl(impl_a) = item.kind {
101+
let ident = match impl_a.self_ty.kind {
102+
HirTyKind::Path(qpath) => {
103+
match qpath {
104+
QPath::Resolved(_, p) => {
105+
format!("{}", p.segments[0].ident)
106+
}
107+
QPath::TypeRelative(_, ps) => {
108+
format!("{}", ps.ident)
109+
}
110+
_ => {
111+
println!("Warning: {:?} is an unknown qpath", qpath);
112+
"unknown_qpath_kind".into()
113+
}
114+
}
115+
}
116+
_ => {
117+
println!("Warning: {:?} has unknown kind", impl_a.self_ty);
118+
"unknown_type_kind".into()
119+
}
120+
};
121+
for item in impl_a.items {
122+
let i = item.ident;
123+
let def_id = item.id.owner_id.to_def_id();
124+
125+
if tcx.generics_of(def_id).count() != 0 {
126+
println!("Skipping generic impl: {i}");
127+
continue; // Skip generic functions for now
128+
}
129+
let instance = rustc_middle::ty::Instance::mono(tcx, def_id);
130+
let mut mir = tcx.optimized_mir(instance.def_id()).clone(); // Clone the MIR
131+
132+
let i = format!("{}_{}", ident, i).to_lowercase();
133+
134+
println!("MIR for function {i}: {:?}", mir);
135+
136+
println!("--- Starting MIR to OOMIR Lowering for function: {i} ---");
137+
let oomir_result = lower1::mir_to_oomir(tcx, instance, &mut mir);
138+
println!("--- Finished MIR to OOMIR Lowering for function: {i} ---");
139+
140+
let mut oomir_function = oomir_result.0;
141+
oomir_function.name = i.clone();
142+
143+
oomir_module
144+
.functions
145+
.insert(i, oomir_function);
146+
147+
oomir_module.merge_data_types(&oomir_result.1);
148+
}
99149
}
100150
}
101151

src/lower1/control_flow.rs

+5
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,9 @@ pub fn convert_basic_block<'tcx>(
440440
rustc_middle::mir::AssertKind::NullPointerDereference => {
441441
"NullPointerDereference".to_string()
442442
}
443+
rustc_middle::mir::AssertKind::ResumedAfterDrop(_) => {
444+
"ResumedAfterDrop".to_string()
445+
}
443446
};
444447

445448
let fail_instructions = vec![oomir::Instruction::ThrowNewWithMessage {
@@ -465,6 +468,8 @@ pub fn convert_basic_block<'tcx>(
465468
target,
466469
unwind: _,
467470
replace: _,
471+
drop: _,
472+
async_fut: _
468473
} => {
469474
// In simple cases (no custom Drop trait), a MIR drop often just signifies
470475
// the end of a scope before control flow continues.

tests/binary/enums/src/main.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
#[derive(PartialEq, Clone, Debug)]
1+
#[derive(PartialEq)]
22
struct ConfigData {
33
id: u32,
44
enabled: bool,
55
params: (f32, f32), // Nested tuple
66
}
77

8-
#[derive(PartialEq, Clone, Debug)]
8+
#[derive(PartialEq)]
99
enum ComplexEnum<'a> {
1010
SimpleVariant, // No data
1111
Count(i64), // Single primitive data

tests/binary/impl/.cargo/config.toml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[build]
2+
rustflags = [
3+
"-Z", "codegen-backend=/Users/mreeve27/rustc_codegen_jvm/target/debug/librustc_codegen_jvm.dylib",
4+
"-C", "linker=/Users/mreeve27/rustc_codegen_jvm/java-linker/target/debug/java-linker",
5+
"-C", "link-args=/Users/mreeve27/rustc_codegen_jvm/library/build/distributions/library-0.1.0/lib/library-0.1.0.jar /Users/mreeve27/rustc_codegen_jvm/library/build/distributions/library-0.1.0/lib/kotlin-stdlib-2.1.20.jar /Users/mreeve27/rustc_codegen_jvm/library/build/distributions/library-0.1.0/lib/annotations-13.0.jar --r8-jar /Users/mreeve27/rustc_codegen_jvm/vendor/r8.jar --proguard-config /Users/mreeve27/rustc_codegen_jvm/proguard/default.pro"
6+
]
7+
8+
# Throwing a JVM exception will unwind and give a stack trace, no need for rust to handle unwinding.
9+
[profile.debug]
10+
panic = "abort"
11+
12+
[profile.release]
13+
panic = "abort"
14+
rustflags = [
15+
"-C", "link-args=--release"
16+
]

tests/binary/impl/Cargo.lock

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/binary/impl/Cargo.toml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
cargo-features = ["profile-rustflags"]
2+
3+
[package]
4+
name = "impl"
5+
version = "0.1.0"
6+
edition = "2024"
7+
8+
[dependencies]

tests/binary/impl/java-output.expected

Whitespace-only changes.

tests/binary/impl/no_jvm_target.flag

Whitespace-only changes.

0 commit comments

Comments
 (0)