Skip to content

Commit 56e767f

Browse files
committed
Refactor structs test to more also test nested mutation, and test structs, tuples and arrays/slicies not just structs.
1 parent 005b362 commit 56e767f

File tree

6 files changed

+74
-46
lines changed

6 files changed

+74
-46
lines changed

Readme.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,11 @@ This backend currently supports a subset of Rust features:
3939
* ✅ Type casting (e.g., `as` operator).
4040
* ✅ Support for all primitive types.
4141
* ✅ Calling other functions (including recursion).
42+
* ✅ Loops such as `for`, `while`, and `loop`.
4243
* ✅ Variable assignment including subfield and array index assignment, including nesting.
43-
* ✅ Arrays and slices, including inserting, accessing and mutating at a given index.
44+
* ✅ Arrays and slices, including inserting, accessing and mutating at a given index (supporting nesting).
4445
* ✅ Floats (`f32`, `f64`).
45-
* ✅ Structs and Tuples (enums and unions coming soon!)
46+
* ✅ Structs and Tuples (enums and unions coming soon!) including nesting access/setting/mutation of fields.
4647
* ✅ Generating executable `.jar` files for binary crates.
4748

4849
### Next Milestone:

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,11 @@ public object Core {
7575
// In a real implementation, this would handle the panic appropriately.
7676
throw RuntimeException("Rust panic: " + (message ?: "<no message>"))
7777
}
78+
79+
@JvmStatic
80+
public fun core_panicking_assert_failed(message: String?) {
81+
// This is a placeholder for the assert failed function.
82+
// In a real implementation, this would handle the assertion failure appropriately.
83+
throw AssertionError("Rust assertion failed: " + (message ?: "<no message>"))
84+
}
7885
}

shim-metadata-gen/core.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
"descriptor": "(I)Ljava/lang/String;",
2424
"is_static": true
2525
},
26+
"core_panicking_assert_failed": {
27+
"descriptor": "(Ljava/lang/String;)V",
28+
"is_static": true
29+
},
2630
"core_panicking_panic": {
2731
"descriptor": "(Ljava/lang/String;)V",
2832
"is_static": true

src/lower1/control_flow/rvalue.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,11 @@ pub fn convert_rvalue_to_operand<'a>(
551551
} else {
552552
// Enum, Union
553553
println!("Warning: Unhandled ADT Aggregate Kind -> Temp Placeholder");
554-
// No instructions needed for placeholder, result set below
554+
// make a placeholder (Class("java/lang/Object"))
555+
instructions.push(oomir::Instruction::ConstructObject {
556+
dest: temp_aggregate_var.clone(),
557+
class_name: "java/lang/Object".to_string(),
558+
});
555559
}
556560
}
557561
_ => {

src/lower2/translator.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,7 @@ impl<'a, 'cp> FunctionTranslator<'a, 'cp> {
13641364
// Currently hardcoded
13651365
if function_name == "panic_fmt"
13661366
|| function_name == "core_panicking_panic"
1367+
|| function_name == "core_panicking_assert_failed"
13671368
{
13681369
is_diverging_call = true;
13691370
}

tests/binary/structs/src/main.rs

Lines changed: 54 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,63 @@
1-
#[derive(Debug)]
2-
struct NestedStruct {
3-
// A nested struct that holds an array.
4-
values: [i32; 3],
1+
struct Inner {
2+
x: i32,
3+
y: (i32, i32),
54
}
65

7-
#[derive(Debug)]
8-
struct TestStruct {
9-
field1: i32,
10-
field2: String,
11-
// Nested struct inside the main struct.
12-
nested: NestedStruct,
6+
struct Outer {
7+
label: String,
8+
inner_struct: Inner,
9+
data: [i32; 3],
1310
}
1411

1512
fn main() {
16-
// Initialize the nested struct with an array.
17-
let nested = NestedStruct { values: [10, 20, 30] };
18-
19-
// Initialize the main structure with two simple fields and one nested struct.
20-
let test_struct = TestStruct {
21-
field1: 180,
22-
field2: "rust".to_string(),
23-
nested,
13+
// === Nested STRUCT + TUPLE + ARRAY ===
14+
let mut outer = Outer {
15+
label: "start".to_string(),
16+
inner_struct: Inner {
17+
x: 100,
18+
y: (5, 10),
19+
},
20+
data: [1, 2, 3],
2421
};
2522

26-
// Test simple field accesses.
27-
assert!(test_struct.field1 == 180, "Field1 should be 180");
28-
assert!(test_struct.field2 == "rust", "Field2 should be 'rust'");
29-
30-
// Test nested field access (accessing a field from the nested struct).
31-
assert!(test_struct.nested.values[0] == 10, "First element in nested.values should be 10");
32-
assert!(test_struct.nested.values[1] == 20, "Second element in nested.values should be 20");
33-
assert!(test_struct.nested.values[2] == 30, "Third element in nested.values should be 30");
34-
35-
// If you want to test even deeper nesting, for instance, an array containing nested structs:
36-
let more_nested: [TestStruct; 2] = [
37-
TestStruct {
38-
field1: 100,
39-
field2: "foo".to_string(),
40-
nested: NestedStruct { values: [1, 2, 3] },
41-
},
42-
TestStruct {
43-
field1: 200,
44-
field2: "bar".to_string(),
45-
nested: NestedStruct { values: [4, 5, 6] },
46-
},
47-
];
23+
// === Access nested values ===
24+
assert!(outer.label == "start");
25+
assert!(outer.inner_struct.x == 100, "Inner x should be 100");
26+
assert!(outer.inner_struct.y.0 == 5, "Inner tuple y.0 should be 5");
27+
assert!(outer.inner_struct.y.1 == 10, "Inner tuple y.1 should be 10");
28+
assert!(outer.data[0] == 1, "Array element at index 0 should be 1");
29+
30+
// === Mutate nested values ===
31+
outer.label = "updated".to_string();
32+
outer.inner_struct.x = 200;
33+
outer.inner_struct.y.1 = 999;
34+
outer.data[1] = 42;
35+
36+
// === Assert mutations ===
37+
assert!(outer.label == "updated", "Outer label should be updated");
38+
assert!(outer.inner_struct.x == 200, "Inner x should now be 200");
39+
assert!(outer.inner_struct.y.1 == 999, "Inner tuple y.1 should now be 999");
40+
assert!(outer.data[1] == 42, "Array element at index 1 should now be 42");
41+
42+
// === Tuple nesting test ===
43+
let mut big_tuple = (
44+
(10, 20),
45+
Inner { x: 50, y: (7, 8) },
46+
["a", "b", "c"],
47+
);
48+
49+
// Access nested tuple values
50+
assert!((big_tuple.0).1 == 20, "First tuple's second element should be 20");
51+
assert!(big_tuple.1.y.0 == 7, "Nested tuple inside struct should be 7");
52+
assert!(big_tuple.2[2] == "c", "Array inside tuple should contain 'c' at index 2");
53+
54+
// Mutate nested values
55+
(big_tuple.0).0 = 99;
56+
big_tuple.1.x = 123;
57+
big_tuple.2[1] = "z";
4858

49-
// Test access into the array and then the nested struct.
50-
assert!(more_nested[0].field1 == 100, "First element's field1 should be 100");
51-
assert!(more_nested[1].nested.values[2] == 6, "Second element's nested.values[2] should be 6");
59+
// Assert changes
60+
assert!((big_tuple.0).0 == 99, "Tuple value mutated to 99");
61+
assert!(big_tuple.1.x == 123, "Inner struct field x mutated to 123");
62+
assert!(big_tuple.2[1] == "z", "Tuple's array element at index 1 mutated to 'z'");
5263
}

0 commit comments

Comments
 (0)