aboutsummaryrefslogtreecommitdiff
path: root/proc-macro-error/proc-macro-error/src/nightly.rs
blob: d053c2f06dcdf655cf55e5f80bc12f3b4032ae74 (plain)
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
use std::sync::atomic::{AtomicBool, Ordering};

use proc_macro::{Diagnostic as PDiag, Level as PLevel};

use crate::{abort_now, check_correctness, Diagnostic, Level, SuggestionKind};

pub fn abort_if_dirty() {
    check_correctness();
    if IS_DIRTY.load(Ordering::SeqCst) {
        abort_now()
    }
}

pub(crate) fn cleanup() -> Vec<Diagnostic> {
    vec![]
}

pub(crate) fn emit_diagnostic(diag: Diagnostic) {
    let Diagnostic {
        level,
        span,
        msg,
        suggestions,
    } = diag;

    let level = match level {
        Level::Warning => PLevel::Warning,
        Level::Error => {
            IS_DIRTY.store(true, Ordering::SeqCst);
            PLevel::Error
        }
        _ => unreachable!(),
    };

    let mut res = PDiag::spanned(span.unwrap(), level, msg);

    for (kind, msg, span) in suggestions {
        res = match (kind, span) {
            (SuggestionKind::Note, Some(span)) => res.span_note(span.unwrap(), msg),
            (SuggestionKind::Help, Some(span)) => res.span_help(span.unwrap(), msg),
            (SuggestionKind::Note, None) => res.note(msg),
            (SuggestionKind::Help, None) => res.help(msg),
        }
    }

    res.emit()
}

static IS_DIRTY: AtomicBool = AtomicBool::new(false);