mod test_helpers;
mod redefinition {
use crate::test_helpers::*;
use slicec::diagnostics::{Diagnostic, Error};
use slicec::slice_file::Span;
#[test]
fn redefinitions_of_the_same_type_are_disallowed() {
let slice = "
module Test
struct S {
i: int32
}
struct S {
i: int32
}
";
let diagnostics = parse_for_diagnostics(slice);
let expected = Diagnostic::from_error(Error::Redefinition {
identifier: "S".to_owned(),
})
.set_span(&Span::new((8, 20).into(), (8, 21).into(), "string-0"))
.add_note(
"'S' was previously defined here",
Some(&Span::new((4, 20).into(), (4, 21).into(), "string-0")),
);
check_diagnostics(diagnostics, [expected]);
}
#[test]
fn redefinitions_of_different_types_are_disallowed() {
let slice = "
module Test
enum A { i }
struct A {
i: int32
}
";
let diagnostics = parse_for_diagnostics(slice);
let expected = Diagnostic::from_error(Error::Redefinition {
identifier: "A".to_owned(),
})
.set_span(&Span::new((6, 20).into(), (6, 21).into(), "string-0"))
.add_note(
"'A' was previously defined here",
Some(&Span::new((4, 18).into(), (4, 19).into(), "string-0")),
);
check_diagnostics(diagnostics, [expected]);
}
#[test]
fn orthogonal_redefinitions_are_disallowed_separately() {
let slice = "
module Test
struct A {
i: int32
i: int64
}
interface A {
i(i: int32)
}
";
let diagnostics = parse_for_diagnostics(slice);
let i_error = Diagnostic::from_error(Error::Redefinition {
identifier: "i".to_owned(),
})
.set_span(&Span::new((6, 17).into(), (6, 18).into(), "string-0"))
.add_note(
"'i' was previously defined here",
Some(&Span::new((5, 17).into(), (5, 18).into(), "string-0")),
);
let s_error = Diagnostic::from_error(Error::Redefinition {
identifier: "A".to_owned(),
})
.set_span(&Span::new((9, 23).into(), (9, 24).into(), "string-0"))
.add_note(
"'A' was previously defined here",
Some(&Span::new((4, 20).into(), (4, 21).into(), "string-0")),
);
check_diagnostics(diagnostics, [i_error, s_error]);
}
#[test]
fn multiple_redefinitions_trigger_separate_errors() {
let slice = "
module Test
struct A {
i: int8
b: bool
b: bool
}
interface A {
i(b: bool, b: bool) -> (b: bool, b: bool)
b()
b()
}
enum A { i, b, b }
";
let diagnostics = parse_for_diagnostics(slice);
let expected = [
Diagnostic::from_error(Error::Redefinition {
identifier: "b".to_owned(),
})
.set_span(&Span::new((8, 17).into(), (8, 18).into(), "string-0")),
Diagnostic::from_error(Error::Redefinition {
identifier: "A".to_owned(),
})
.set_span(&Span::new((11, 23).into(), (11, 24).into(), "string-0")),
Diagnostic::from_error(Error::Redefinition {
identifier: "b".to_owned(),
})
.set_span(&Span::new((15, 17).into(), (15, 18).into(), "string-0")),
Diagnostic::from_error(Error::Redefinition {
identifier: "b".to_owned(),
})
.set_span(&Span::new((12, 28).into(), (12, 29).into(), "string-0")),
Diagnostic::from_error(Error::Redefinition {
identifier: "b".to_owned(),
})
.set_span(&Span::new((12, 50).into(), (12, 51).into(), "string-0")),
Diagnostic::from_error(Error::Redefinition {
identifier: "A".to_owned(),
})
.set_span(&Span::new((18, 18).into(), (18, 19).into(), "string-0")),
Diagnostic::from_error(Error::Redefinition {
identifier: "b".to_owned(),
})
.set_span(&Span::new((18, 28).into(), (18, 29).into(), "string-0")),
];
check_diagnostics(diagnostics, expected);
}
#[test]
fn cross_module_redefinitions_are_disallowed() {
let slice1 = "
module Foo
struct Bar {}
";
let slice2 = "
module Foo
custom Bar
";
let diagnostics = parse_multiple_for_diagnostics(&[slice1, slice2]);
let expected = Diagnostic::from_error(Error::Redefinition {
identifier: "Bar".to_owned(),
})
.set_span(&Span::new((3, 20).into(), (3, 23).into(), "string-1"))
.add_note(
"'Bar' was previously defined here",
Some(&Span::new((3, 20).into(), (3, 23).into(), "string-0")),
);
check_diagnostics(diagnostics, [expected]);
}
}