    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30

    //! This implementation uses self-written stable facilities.

    use crate::{
        abort_now, check_correctness,
        diagnostic::{Diagnostic, Level},
    };
    use std::cell::RefCell;

    pub fn abort_if_dirty() {
        check_correctness();
        ERR_STORAGE.with(|storage| {
            if !storage.borrow().is_empty() {
                abort_now()
            }
        });
    }

    pub(crate) fn cleanup() -> Vec<Diagnostic> {
        ERR_STORAGE.with(|storage| storage.replace(Vec::new()))
    }

    pub(crate) fn emit_diagnostic(diag: Diagnostic) {
        if diag.level == Level::Error {
            ERR_STORAGE.with(|storage| storage.borrow_mut().push(diag));
        }
    }

    thread_local! {
        static ERR_STORAGE: RefCell<Vec<Diagnostic>> = RefCell::new(Vec::new());
    }