Skip to content

Commit c0ed2aa

Browse files
committed
Support for traits (+ new unit test verifying this!) :)
1 parent d131899 commit c0ed2aa

File tree

17 files changed

+412
-58
lines changed

17 files changed

+412
-58
lines changed

Cargo.lock

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

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ edition = "2024"
77
bigdecimal = "0.4.8"
88
half = "2.6.0"
99
libc = "0.2.172"
10+
md5 = "0.7.0"
1011
num-bigint = "0.4.6"
1112
num-traits = "0.2.19"
1213
regex = "1.11.1"

Readme.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +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)**
35+
* **[Implementation blocks](tests/binary/impl/src/main.rs)** and **[traits](tests/binary/traits/src/main.rs)**
3636
- …and more!
3737

3838
---
@@ -52,6 +52,7 @@ All examples live in `tests/binary` and are compiled to JVM bytecode & run/teste
5252
- Executable `.jar` generation for binary crates
5353
- Mutable borrowing, references, and dereferencing
5454
- Implementations for ADTs, including using and returning `self`, `&self`, `&mut self`
55+
- Traits!
5556
- **Integration tests** for all features, in debug and release modes
5657

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

Tester.py

-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ 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)
5048
return False
5149

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

library/src/main/kotlin/org/rustlang/core/Core.kt

+98-6
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public object Core {
7777
}
7878

7979
@JvmStatic
80-
public fun arguments_new_const(pieces: Array<String>): String {
80+
public fun arguments_new_const_1(pieces: Array<String>): String {
8181
// Concatenate all the string pieces together.
8282
// This mimics the simplest formatting scenario where pieces are just joined.
8383
// If the array is empty, it correctly returns an empty string.
@@ -219,10 +219,82 @@ public object Core {
219219
return false
220220
}
221221

222+
223+
// variants of eq that just call the main one. need A LOT of these since we are now properly resolving generics
224+
// will no longer be needed once we compile the real `core` library which will generate all of these - support is almost there
225+
// placeholders just for now
226+
227+
@JvmStatic
228+
public fun str_eq(value1: String?, value2: String?): Boolean {
229+
return eq(value1, value2)
230+
}
231+
232+
@JvmStatic
233+
public fun f16_eq(value1: Any?, value2: Any?): Boolean {
234+
return eq(value1, value2)
235+
}
236+
237+
@JvmStatic
238+
public fun f32_eq(value1: Any?, value2: Any?): Boolean {
239+
return eq(value1, value2)
240+
}
241+
242+
@JvmStatic
243+
// (f32, f32) tuple
244+
public fun f32_f32_eq(value1: Any?, value2: Any?): Boolean {
245+
return eq(value1, value2)
246+
}
247+
248+
@JvmStatic
249+
public fun f64_eq(value1: Any?, value2: Any?): Boolean {
250+
return eq(value1, value2)
251+
}
252+
253+
@JvmStatic
254+
public fun f128_eq(value1: Any?, value2: Any?): Boolean {
255+
return eq(value1, value2)
256+
}
257+
258+
@JvmStatic
259+
public fun i64_eq(value1: Any?, value2: Any?): Boolean {
260+
return eq(value1, value2)
261+
}
262+
263+
@JvmStatic
264+
// tuple (i32, i32, i32)
265+
public fun i32_i32_i32_eq(value1: Any?, value2: Any?): Boolean {
266+
return eq(value1, value2)
267+
}
268+
222269
@JvmStatic
223-
public fun core_panic(message: String?) {
224-
// This is a placeholder for the panic function.
225-
// In a real implementation, this would handle the panic appropriately.
270+
// tuple (i32, u8, bool)
271+
public fun i32_u8_bool_eq(value1: Any?, value2: Any?): Boolean {
272+
return eq(value1, value2)
273+
}
274+
275+
@JvmStatic
276+
// [u8; 8]
277+
public fun u8_8_eq(value1: Any?, value2: Any?): Boolean {
278+
return eq(value1, value2)
279+
}
280+
281+
@JvmStatic
282+
public fun raw_eq_u8_8(slice1: Any?, slice2: Any?): Boolean {
283+
return eq(slice1, slice2)
284+
}
285+
286+
@JvmStatic
287+
public fun u8_eq(value1: Any?, value2: Any?): Boolean {
288+
return eq(value1, value2)
289+
}
290+
291+
@JvmStatic
292+
public fun option_usize_eq(value1: Any?, value2: Any?): Boolean {
293+
return eq(value1, value2)
294+
}
295+
296+
@JvmStatic
297+
public fun core_panicking_panic(message: String?) {
226298
throw RuntimeException("Rust panic: " + (message ?: "<no message>"))
227299
}
228300

@@ -240,7 +312,7 @@ public object Core {
240312
}
241313

242314
@JvmStatic
243-
fun core_starts_with(value: Any, prefix: Any): Boolean {
315+
fun core_str_str_starts_with_char(value: Any, prefix: Any): Boolean {
244316
// Runtime type check needed here!
245317
return when {
246318
value is String && prefix is String -> { // Both are strings
@@ -270,6 +342,12 @@ fun core_starts_with(value: Any, prefix: Any): Boolean {
270342
}
271343
}
272344
}
345+
346+
// wrapper that just calls the above
347+
@JvmStatic
348+
public fun core_slice_u8_starts_with(value: Any, prefix: Any): Boolean {
349+
return core_str_str_starts_with_char(value, prefix)
350+
}
273351
@JvmStatic
274352
public fun option_unwrap(optionObj: Any?): Any? {
275353
if (optionObj == null) {
@@ -332,7 +410,13 @@ fun core_starts_with(value: Any, prefix: Any): Boolean {
332410
}
333411
}
334412

335-
/**
413+
// redirectors for monomorphised versions of the above, to just call the above
414+
@JvmStatic
415+
public fun option_usize_is_none(optionObj: Any?): Boolean {
416+
return option_is_none(optionObj)
417+
}
418+
419+
/**
336420
* Shim for `<[T] as SlicePartialEq<T>>::equal`.
337421
* Handles comparison of primitive arrays based on OOMIR types.
338422
* Primarily expects ByteArray (for u8) or ShortArray (due to I16 OOMIR type from String casts).
@@ -362,6 +446,14 @@ fun core_starts_with(value: Any, prefix: Any): Boolean {
362446
}
363447
}
364448

449+
// monomorphised versions of the above
450+
@JvmStatic
451+
// a slice of u8
452+
public fun u8_equal(slice1: Any?, slice2: Any?): Boolean {
453+
return equal(slice1, slice2)
454+
}
455+
456+
365457
/**
366458
* Convert a Java String into a ShortArray, by casting each char to a short.
367459
*/

shim-metadata-gen/core.json

+67-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"arguments_new_const": {
2+
"arguments_new_const_1": {
33
"descriptor": "([Ljava/lang/String;)Ljava/lang/String;",
44
"is_static": true
55
},
@@ -27,11 +27,15 @@
2727
"descriptor": "(I)Ljava/lang/String;",
2828
"is_static": true
2929
},
30-
"core_panic": {
30+
"core_panicking_panic": {
3131
"descriptor": "(Ljava/lang/String;)V",
3232
"is_static": true
3333
},
34-
"core_starts_with": {
34+
"core_slice_u8_starts_with": {
35+
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
36+
"is_static": true
37+
},
38+
"core_str_str_starts_with_char": {
3539
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
3640
"is_static": true
3741
},
@@ -51,10 +55,42 @@
5155
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
5256
"is_static": true
5357
},
58+
"f128_eq": {
59+
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
60+
"is_static": true
61+
},
62+
"f16_eq": {
63+
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
64+
"is_static": true
65+
},
66+
"f32_eq": {
67+
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
68+
"is_static": true
69+
},
70+
"f32_f32_eq": {
71+
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
72+
"is_static": true
73+
},
74+
"f64_eq": {
75+
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
76+
"is_static": true
77+
},
5478
"fromShortArray": {
5579
"descriptor": "([S)Ljava/lang/String;",
5680
"is_static": true
5781
},
82+
"i32_i32_i32_eq": {
83+
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
84+
"is_static": true
85+
},
86+
"i32_u8_bool_eq": {
87+
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
88+
"is_static": true
89+
},
90+
"i64_eq": {
91+
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
92+
"is_static": true
93+
},
5894
"option_is_none": {
5995
"descriptor": "(Ljava/lang/Object;)Z",
6096
"is_static": true
@@ -63,16 +99,44 @@
6399
"descriptor": "(Ljava/lang/Object;)Ljava/lang/Object;",
64100
"is_static": true
65101
},
102+
"option_usize_eq": {
103+
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
104+
"is_static": true
105+
},
106+
"option_usize_is_none": {
107+
"descriptor": "(Ljava/lang/Object;)Z",
108+
"is_static": true
109+
},
66110
"panic_fmt": {
67111
"descriptor": "(Ljava/lang/Object;)V",
68112
"is_static": true
69113
},
114+
"raw_eq_u8_8": {
115+
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
116+
"is_static": true
117+
},
118+
"str_eq": {
119+
"descriptor": "(Ljava/lang/String;Ljava/lang/String;)Z",
120+
"is_static": true
121+
},
70122
"toShortArray": {
71123
"descriptor": "(Ljava/lang/String;)[S",
72124
"is_static": true
73125
},
74126
"to_string": {
75127
"descriptor": "(Ljava/lang/Object;)Ljava/lang/String;",
76128
"is_static": true
129+
},
130+
"u8_8_eq": {
131+
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
132+
"is_static": true
133+
},
134+
"u8_eq": {
135+
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
136+
"is_static": true
137+
},
138+
"u8_equal": {
139+
"descriptor": "(Ljava/lang/Object;Ljava/lang/Object;)Z",
140+
"is_static": true
77141
}
78142
}

src/lib.rs

-8
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,6 @@ impl CodegenBackend for MyBackend {
7777
} = item.kind
7878
{
7979
let def_id = item_id.owner_id.to_def_id();
80-
if tcx.generics_of(def_id).count() != 0 {
81-
println!("Skipping generic function: {i}");
82-
continue; // Skip generic functions for now
83-
}
8480
let instance = rustc_middle::ty::Instance::mono(tcx, def_id);
8581
let mut mir = tcx.optimized_mir(instance.def_id()).clone(); // Clone the MIR
8682

@@ -122,10 +118,6 @@ impl CodegenBackend for MyBackend {
122118
let i = item.ident;
123119
let def_id = item.id.owner_id.to_def_id();
124120

125-
if tcx.generics_of(def_id).count() != 0 {
126-
println!("Skipping generic impl: {i}");
127-
continue; // Skip generic functions for now
128-
}
129121
let instance = rustc_middle::ty::Instance::mono(tcx, def_id);
130122
let mut mir = tcx.optimized_mir(instance.def_id()).clone(); // Clone the MIR
131123

src/lower1/control_flow/rvalue.rs

+10
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,16 @@ pub fn convert_rvalue_to_operand<'a>(
905905
ty: method_return_type, // Should be I32
906906
};
907907
}
908+
Rvalue::CopyForDeref(place) => {
909+
// Need to get the value from the source place first
910+
let (temp_var_name, get_instructions, temp_var_type) =
911+
emit_instructions_to_get_on_own(place, tcx, mir, data_types);
912+
instructions.extend(get_instructions);
913+
result_operand = oomir::Operand::Variable {
914+
name: temp_var_name,
915+
ty: temp_var_type,
916+
};
917+
}
908918
// Handle other Rvalue variants by generating a placeholder
909919
_ => {
910920
println!(

0 commit comments

Comments
 (0)