#![cfg(any(
not(any(
feature = "parser_tests",
feature = "analyzer_tests",
feature = "codegen_tests",
feature = "interpreter_tests",
feature = "conformance_tests",
feature = "integration_tests",
)),
feature = "analyzer_tests",
))]
#[path = "common/test_utils.rs"]
mod test_utils;
#[test]
fn test_two_ref_params_with_ref_return_gets_lifetime() {
let source = r#"
fn longest(a: string, b: string) -> string {
if a.len() >= b.len() {
a
} else {
b
}
}
fn main() {
let a = "Hello World".to_string()
let b = "Hi".to_string()
let result = longest(a, b)
println!("{}", result)
}
"#;
let generated = test_utils::compile_single(source);
assert!(
generated.contains("fn longest") && generated.contains("-> String"),
"Expected owned String return type.\nGenerated:\n{}",
generated
);
assert!(
!generated.contains("<\'a>"),
"Owned String return should not need explicit lifetime.\nGenerated:\n{}",
generated
);
}
#[test]
fn test_single_ref_param_no_lifetime_needed() {
let source = r#"
fn first_char(s: string) -> string {
s
}
fn main() {
let s = "Hello".to_string()
let c = first_char(s)
println!("{}", c)
}
"#;
let generated = test_utils::compile_single(source);
assert!(
generated.contains("fn first_char"),
"Function should exist in generated code"
);
}
#[test]
fn test_self_method_ref_return_no_lifetime_needed() {
let source = r#"
struct Container {
pub items: Vec<string>,
}
impl Container {
fn new() -> Container {
Container { items: Vec::new() }
}
fn first(self) -> Option<string> {
if self.items.is_empty() {
None
} else {
Some(self.items[0])
}
}
}
fn main() {
let c = Container::new()
println!("done")
}
"#;
let generated = test_utils::compile_single(source);
assert!(
generated.contains("fn first"),
"Method should exist in generated code"
);
}
#[test]
fn test_option_ref_return_with_multiple_params_gets_lifetime() {
let source = r#"
fn longer_option(a: string, b: string) -> Option<string> {
if a.len() > 0 {
Some(a)
} else {
Some(b)
}
}
fn main() {
let a = "Hello".to_string()
let b = "World".to_string()
match longer_option(a, b) {
Some(s) => println!("{}", s),
None => println!("none"),
}
}
"#;
let generated = test_utils::compile_single(source);
assert!(
generated.contains("-> Option<String>"),
"Expected owned Option<String> return.\nGenerated:\n{}",
generated
);
assert!(
!generated.contains("<\'a>"),
"Owned Option<String> return should not need explicit lifetime.\nGenerated:\n{}",
generated
);
}
#[test]
fn test_no_ref_return_no_lifetime_needed() {
let source = r#"
fn compare(a: string, b: string) -> bool {
a.len() > b.len()
}
fn main() {
let a = "Hello".to_string()
let b = "Hi".to_string()
println!("{}", compare(a, b))
}
"#;
let generated = test_utils::compile_single(source);
assert!(
!generated.contains("<'a>"),
"Should NOT have lifetime parameter when return type has no references.\nGenerated:\n{}",
generated
);
}