#![cfg(not(any(
feature = "parser_tests",
feature = "analyzer_tests",
feature = "codegen_tests",
feature = "interpreter_tests",
feature = "conformance_tests",
feature = "integration_tests",
)))]
#[path = "common/test_utils.rs"]
mod test_utils;
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_struct_field_in_loop_no_auto_clone() {
let source = r#"
pub struct Item {
pub id: string,
pub quantity: i32,
}
pub struct Inventory {
items: Vec<Item>,
}
impl Inventory {
pub fn has_item(self, item_id: string, quantity: i32) -> bool {
for item in self.items {
if item.id == item_id && item.quantity >= quantity {
return true
}
}
false
}
}
fn main() {
let inv = Inventory { items: Vec::new() }
let result = inv.has_item("sword", 1)
}
"#;
let (rust_code, success) = test_utils::compile_single_check(source);
let stderr = if !success { &rust_code } else { "" };
if !success {
panic!(
"Compilation failed:\n{}\n\nGenerated code:\n{}",
stderr, rust_code
);
}
assert!(
!rust_code.contains("item.id.clone()"),
"Should not auto-clone struct field in comparison:\n{}",
rust_code
);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_struct_field_passed_to_borrowed_param() {
let source = r#"
pub struct Ingredient {
pub item_id: string,
pub quantity: i32,
}
pub struct Recipe {
ingredients: Vec<Ingredient>,
}
impl Recipe {
pub fn check_inventory(self, has_item: fn(string, i32) -> bool) -> bool {
for ingredient in self.ingredients {
if !has_item(ingredient.item_id, ingredient.quantity) {
return false
}
}
true
}
}
fn dummy_has_item(item_id: string, quantity: i32) -> bool {
true
}
fn main() {
let recipe = Recipe { ingredients: Vec::new() }
let result = recipe.check_inventory(dummy_has_item)
}
"#;
let (rust_code, success) = test_utils::compile_single_check(source);
let stderr = if !success { &rust_code } else { "" };
if !success {
panic!(
"Compilation failed:\n{}\n\nGenerated code:\n{}",
stderr, rust_code
);
}
assert!(
!rust_code.contains("ingredient.item_id.clone()"),
"Should not auto-clone struct field when passing to borrowed param:\n{}",
rust_code
);
}