add some regression tests for the new unused fields warning.

This commit is contained in:
KtorZ 2025-01-22 19:29:12 +01:00 committed by Lucas
parent 05264bc423
commit be770acb54
2 changed files with 212 additions and 2 deletions

View File

@ -1,7 +1,10 @@
use crate::{ use crate::{
ast::{Definition, ModuleKind, Pattern, TraceLevel, Tracing, TypedModule, UntypedModule}, ast::{
Definition, ModuleKind, Pattern, TraceLevel, Tracing, TypedModule, UntypedModule,
UntypedPattern,
},
builtins, builtins,
expr::TypedExpr, expr::{CallArg, Span, TypedExpr},
parser, parser,
tipo::error::{Error, UnifyErrorSituation, Warning}, tipo::error::{Error, UnifyErrorSituation, Warning},
IdGenerator, IdGenerator,
@ -3445,3 +3448,207 @@ fn constant_generic_empty() {
let source_code = r#"const foo: List<a> = []"#; let source_code = r#"const foo: List<a> = []"#;
assert!(check_validator(parse(source_code)).is_ok()); assert!(check_validator(parse(source_code)).is_ok());
} }
#[test]
fn unused_record_fields_1() {
let source_code = r#"
pub type Foo {
Foo { field0: Bool, field1: Bool }
Bar
}
test confusing() {
let foo = Foo(True, True)
when foo is {
Foo(field1, field0) -> field0 || field1
_ -> False
}
}
"#;
let result = check_validator(parse(source_code));
assert!(result.is_ok());
let (warnings, _) = result.unwrap();
assert_eq!(
warnings[0],
Warning::UnusedRecordFields {
location: Span::create(193, 19),
suggestion: UntypedPattern::Constructor {
is_record: true,
location: Span::create(193, 19),
name: "Foo".to_string(),
arguments: vec![
CallArg {
label: Some("field0".to_string()),
location: Span::create(197, 6),
value: Pattern::Var {
location: Span::create(197, 6),
name: "field1".to_string()
}
},
CallArg {
label: Some("field1".to_string()),
location: Span::create(205, 6),
value: Pattern::Var {
location: Span::create(205, 6),
name: "field0".to_string()
}
}
],
module: None,
constructor: (),
spread_location: None,
tipo: ()
}
}
);
}
#[test]
fn unused_record_fields_2() {
let source_code = r#"
pub type Foo {
Foo { field0: Bool, field1: Bool }
Bar
}
test confusing() {
let foo = Foo(True, True)
when foo is {
Foo(field0, field1) -> field0 || field1
_ -> False
}
}
"#;
let result = check_validator(parse(source_code));
assert!(result.is_ok());
let (warnings, _) = result.unwrap();
assert_eq!(
warnings[0],
Warning::UnusedRecordFields {
location: Span::create(193, 19),
suggestion: UntypedPattern::Constructor {
is_record: true,
location: Span::create(193, 19),
name: "Foo".to_string(),
arguments: vec![
CallArg {
label: Some("field0".to_string()),
location: Span::create(197, 6),
value: Pattern::Var {
location: Span::create(197, 6),
name: "field0".to_string()
}
},
CallArg {
label: Some("field1".to_string()),
location: Span::create(205, 6),
value: Pattern::Var {
location: Span::create(205, 6),
name: "field1".to_string()
}
}
],
module: None,
constructor: (),
spread_location: None,
tipo: ()
}
}
);
}
#[test]
fn unused_record_fields_3() {
let source_code = r#"
pub type Foo {
Foo { field0: Bool, field1: Bool }
Bar
}
test confusing() {
let foo = Foo(True, True)
when foo is {
Foo(a, _) -> a
_ -> False
}
}
"#;
let result = check_validator(parse(source_code));
assert!(result.is_ok());
let (warnings, _) = result.unwrap();
assert_eq!(
warnings[0],
Warning::UnusedRecordFields {
location: Span::create(193, 9),
suggestion: UntypedPattern::Constructor {
is_record: true,
location: Span::create(193, 9),
name: "Foo".to_string(),
arguments: vec![CallArg {
label: Some("field0".to_string()),
location: Span::create(197, 6),
value: Pattern::Var {
location: Span::create(197, 1),
name: "a".to_string()
}
},],
module: None,
constructor: (),
spread_location: Some(Span::create(199, 2)),
tipo: ()
}
}
);
}
#[test]
fn unused_record_fields_4() {
let source_code = r#"
pub type Foo {
Foo { field0: Bool, field1: Bool }
Bar
}
test confusing() {
let foo = Foo(True, True)
when foo is {
Foo(a, ..) -> a
_ -> False
}
}
"#;
let result = check_validator(parse(source_code));
assert!(result.is_ok());
let (warnings, _) = result.unwrap();
assert_eq!(
warnings[0],
Warning::UnusedRecordFields {
location: Span::create(193, 10),
suggestion: UntypedPattern::Constructor {
is_record: true,
location: Span::create(193, 10),
name: "Foo".to_string(),
arguments: vec![CallArg {
label: Some("field0".to_string()),
location: Span::create(197, 6),
value: Pattern::Var {
location: Span::create(197, 1),
name: "a".to_string()
}
},],
module: None,
constructor: (),
spread_location: Some(Span::create(200, 2)),
tipo: ()
}
}
);
}

View File

@ -475,6 +475,9 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
} else { } else {
Some(CallArg { Some(CallArg {
label: Some(field.clone()), label: Some(field.clone()),
location: arg
.location
.map(|start, _| (start, start + field.len())),
..arg.clone() ..arg.clone()
}) })
} }