1use crate::compilation_state::CompilationState;
7use crate::diagnostics::{Diagnostic, DiagnosticLevel};
8use crate::slice_options::SliceOptions;
9
10#[must_use]
12pub fn diagnostics_from_compilation_state(state: CompilationState, options: &SliceOptions) -> Vec<Diagnostic> {
13    let mut diagnostics = state.into_diagnostics(options);
14    diagnostics.retain(|diagnostic| diagnostic.level() != DiagnosticLevel::Allowed);
15    diagnostics
16}
17
18pub fn check_diagnostics<const L: usize>(diagnostics: Vec<Diagnostic>, expected: [impl Into<Diagnostic>; L]) {
31    if expected.len() != diagnostics.len() {
33        eprintln!(
34            "Expected {} diagnostics, but got {}.",
35            expected.len(),
36            diagnostics.len()
37        );
38        eprintln!("The emitted diagnostics were:");
39        for diagnostic in diagnostics {
40            eprintln!("\t{diagnostic:?}");
41        }
42        eprintln!();
43        panic!("test failure");
44    }
45
46    for (expect, diagnostic) in expected.into_iter().zip(diagnostics) {
48        let expect: Diagnostic = expect.into();
49        let mut failed = false;
50
51        if expect.code() != diagnostic.code() {
53            eprintln!("diagnostic codes didn't match:");
54            eprintln!("\texpected '{:?}', but got '{:?}'", expect.code(), diagnostic.code());
55            failed = true;
56        }
57
58        if expect.message() != diagnostic.message() {
60            eprintln!("diagnostic messages didn't match:");
61            eprintln!("\texpected: \"{}\"", expect.message());
62            eprintln!("\t but got: \"{}\"", diagnostic.message());
63            failed = true;
64        }
65
66        if expect.span().is_some() && expect.span() != diagnostic.span() {
68            eprintln!("diagnostic spans didn't match:");
69            eprintln!("\texpected: \"{:?}\"", expect.span());
70            eprintln!("\t but got: \"{:?}\"", diagnostic.span());
71            failed = true;
72        }
73
74        if !expect.notes().is_empty() {
76            let expected_notes = expect.notes();
77            let emitted_notes = diagnostic.notes();
78            if expected_notes.len() != emitted_notes.len() {
79                eprintln!(
80                    "Expected {} notes, but got {}.",
81                    expected_notes.len(),
82                    emitted_notes.len()
83                );
84                eprintln!("The emitted notes were:");
85                for note in emitted_notes {
86                    eprintln!("\t{note:?}");
87                }
88                failed = true;
89            } else {
90                for (expected_note, emitted_note) in expected_notes.iter().zip(emitted_notes) {
91                    if expected_note.message != emitted_note.message {
93                        eprintln!("note messages didn't match:");
94                        eprintln!("\texpected: \"{}\"", expected_note.message);
95                        eprintln!("\t but got: \"{}\"", emitted_note.message);
96                        failed = true;
97                    }
98
99                    if expected_note.span.is_some() && expected_note.span != emitted_note.span {
101                        eprintln!("note spans didn't match:");
102                        eprintln!("\texpected: \"{:?}\"", expected_note.span);
103                        eprintln!("\t but got: \"{:?}\"", emitted_note.span);
104                        failed = true;
105                    }
106                }
107            }
108        }
109
110        if failed {
112            eprintln!();
113            panic!("test failure");
114        }
115    }
116}