1ea88969fSopenharmony_ci//! This implementation uses [`proc_macro::Diagnostic`], nightly only. 2ea88969fSopenharmony_ci 3ea88969fSopenharmony_ciuse std::cell::Cell; 4ea88969fSopenharmony_ci 5ea88969fSopenharmony_ciuse proc_macro::{Diagnostic as PDiag, Level as PLevel}; 6ea88969fSopenharmony_ci 7ea88969fSopenharmony_ciuse crate::{ 8ea88969fSopenharmony_ci abort_now, check_correctness, 9ea88969fSopenharmony_ci diagnostic::{Diagnostic, Level, SuggestionKind}, 10ea88969fSopenharmony_ci}; 11ea88969fSopenharmony_ci 12ea88969fSopenharmony_cipub fn abort_if_dirty() { 13ea88969fSopenharmony_ci check_correctness(); 14ea88969fSopenharmony_ci if IS_DIRTY.with(|c| c.get()) { 15ea88969fSopenharmony_ci abort_now() 16ea88969fSopenharmony_ci } 17ea88969fSopenharmony_ci} 18ea88969fSopenharmony_ci 19ea88969fSopenharmony_cipub(crate) fn cleanup() -> Vec<Diagnostic> { 20ea88969fSopenharmony_ci IS_DIRTY.with(|c| c.set(false)); 21ea88969fSopenharmony_ci vec![] 22ea88969fSopenharmony_ci} 23ea88969fSopenharmony_ci 24ea88969fSopenharmony_cipub(crate) fn emit_diagnostic(diag: Diagnostic) { 25ea88969fSopenharmony_ci let Diagnostic { 26ea88969fSopenharmony_ci level, 27ea88969fSopenharmony_ci span_range, 28ea88969fSopenharmony_ci msg, 29ea88969fSopenharmony_ci suggestions, 30ea88969fSopenharmony_ci children, 31ea88969fSopenharmony_ci } = diag; 32ea88969fSopenharmony_ci 33ea88969fSopenharmony_ci let span = span_range.collapse().unwrap(); 34ea88969fSopenharmony_ci 35ea88969fSopenharmony_ci let level = match level { 36ea88969fSopenharmony_ci Level::Warning => PLevel::Warning, 37ea88969fSopenharmony_ci Level::Error => { 38ea88969fSopenharmony_ci IS_DIRTY.with(|c| c.set(true)); 39ea88969fSopenharmony_ci PLevel::Error 40ea88969fSopenharmony_ci } 41ea88969fSopenharmony_ci _ => unreachable!(), 42ea88969fSopenharmony_ci }; 43ea88969fSopenharmony_ci 44ea88969fSopenharmony_ci let mut res = PDiag::spanned(span, level, msg); 45ea88969fSopenharmony_ci 46ea88969fSopenharmony_ci for (kind, msg, span) in suggestions { 47ea88969fSopenharmony_ci res = match (kind, span) { 48ea88969fSopenharmony_ci (SuggestionKind::Note, Some(span_range)) => { 49ea88969fSopenharmony_ci res.span_note(span_range.collapse().unwrap(), msg) 50ea88969fSopenharmony_ci } 51ea88969fSopenharmony_ci (SuggestionKind::Help, Some(span_range)) => { 52ea88969fSopenharmony_ci res.span_help(span_range.collapse().unwrap(), msg) 53ea88969fSopenharmony_ci } 54ea88969fSopenharmony_ci (SuggestionKind::Note, None) => res.note(msg), 55ea88969fSopenharmony_ci (SuggestionKind::Help, None) => res.help(msg), 56ea88969fSopenharmony_ci } 57ea88969fSopenharmony_ci } 58ea88969fSopenharmony_ci 59ea88969fSopenharmony_ci for (span_range, msg) in children { 60ea88969fSopenharmony_ci let span = span_range.collapse().unwrap(); 61ea88969fSopenharmony_ci res = res.span_error(span, msg); 62ea88969fSopenharmony_ci } 63ea88969fSopenharmony_ci 64ea88969fSopenharmony_ci res.emit() 65ea88969fSopenharmony_ci} 66ea88969fSopenharmony_ci 67ea88969fSopenharmony_cithread_local! { 68ea88969fSopenharmony_ci static IS_DIRTY: Cell<bool> = Cell::new(false); 69ea88969fSopenharmony_ci} 70