1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#![cfg(any(
not(any(
feature = "parser_tests",
feature = "analyzer_tests",
feature = "codegen_tests",
feature = "interpreter_tests",
feature = "conformance_tests",
feature = "integration_tests",
)),
feature = "integration_tests",
))]
// Integration test for generic owned parameter inference
// Verifies that `mut game: G` generates as `mut game: G` not `game: &G`
// NOTE: Full rustc compilation is disabled due to known issues:
// 1. extern fn generates without body
// 2. Call site adds & when it shouldn't
use std::path::PathBuf;
// Skip in coverage runs - subprocess spawning is very slow under tarpaulin instrumentation
// The tarpaulin cfg is declared in Cargo.toml [lints.rust] section
#[cfg_attr(tarpaulin, ignore)]
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_generic_owned_param_inference() {
let out_tmp = tempfile::tempdir().expect("tempdir");
let wj_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests")
.join("generic_owned_param_test.wj");
windjammer::build_project(
&wj_path,
out_tmp.path(),
windjammer::CompilationTarget::Rust,
false,
)
.expect("Windjammer compilation failed");
// Read the generated Rust code
// The compiler outputs relative to source_root (tests/ directory),
// so the file is directly in output_dir
// Read the generated Rust code
// The file location depends on whether path stripping succeeded:
// - Success: <output_dir>/generic_owned_param_test.rs
// - Failure: <output_dir>/wj/windjammer/tests/generic_owned_param_test.rs
let generated_code =
std::fs::read_to_string(out_tmp.path().join("generic_owned_param_test.rs"))
.or_else(|_| {
std::fs::read_to_string(
out_tmp
.path()
.join("wj")
.join("windjammer")
.join("tests")
.join("generic_owned_param_test.rs"),
)
})
.expect("Failed to read generated code (tried both possible paths)");
// Print for debugging
println!("Generated code:\n{}", generated_code);
// THE BUG (FIXED): Should generate `mut game: G` not `game: &G`
assert!(
generated_code.contains("pub fn run_game<G: GameState>(mut game: G)") ||
generated_code.contains("pub fn run_game<G>(mut game: G)\nwhere"),
"run_game should have owned parameter `mut game: G`, not borrowed `game: &G`.\nGenerated: {}",
generated_code
);
// KNOWN ISSUE: Call site still generates `run_game(&game)` instead of `run_game(game)`
// This is tracked separately and will be fixed in a future PR
// For now, we just verify the function signature is correct
}