// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![crate_name = "rustc_errors"]
#![unstable(feature = "rustc_private", issue = "27812")]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
      html_root_url = "https://doc.rust-lang.org/nightly/")]
#![cfg_attr(not(stage0), deny(warnings))]

#![feature(custom_attribute)]
#![allow(unused_attributes)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(question_mark)]
#![feature(range_contains)]
#![feature(libc)]
#![feature(unicode)]

extern crate serialize;
extern crate term;
#[macro_use] extern crate log;
#[macro_use] extern crate libc;
extern crate rustc_unicode;
extern crate serialize as rustc_serialize; // used by deriving
extern crate syntax_pos;

pub use emitter::ColorConfig;

use self::Level::*;
use self::RenderSpan::*;

use emitter::{Emitter, EmitterWriter};

use std::cell::{RefCell, Cell};
use std::{error, fmt};
use std::rc::Rc;
use std::thread::panicking;

pub mod emitter;
pub mod snippet;
pub mod registry;
pub mod styled_buffer;

use syntax_pos::{BytePos, Loc, FileLinesResult, FileName, MultiSpan, Span, NO_EXPANSION };
use syntax_pos::{MacroBacktrace};

#[derive(Clone)]
pub enum RenderSpan {
    /// A FullSpan renders with both with an initial line for the
    /// message, prefixed by file:linenum, followed by a summary of
    /// the source code covered by the span.
    FullSpan(MultiSpan),

    /// A suggestion renders with both with an initial line for the
    /// message, prefixed by file:linenum, followed by a summary
    /// of hypothetical source code, where each `String` is spliced
    /// into the lines in place of the code covered by each span.
    Suggestion(CodeSuggestion),
}

#[derive(Clone)]
pub struct CodeSuggestion {
    pub msp: MultiSpan,
    pub substitutes: Vec<String>,
}

pub trait CodeMapper {
    fn lookup_char_pos(&self, pos: BytePos) -> Loc;
    fn span_to_lines(&self, sp: Span) -> FileLinesResult;
    fn span_to_string(&self, sp: Span) -> String;
    fn span_to_filename(&self, sp: Span) -> FileName;
    fn macro_backtrace(&self, span: Span) -> Vec<MacroBacktrace>;
}

impl CodeSuggestion {
    /// Returns the assembled code suggestion.
    pub fn splice_lines(&self, cm: &CodeMapper) -> String {
        use syntax_pos::{CharPos, Loc, Pos};

        fn push_trailing(buf: &mut String, line_opt: Option<&str>,
                         lo: &Loc, hi_opt: Option<&Loc>) {
            let (lo, hi_opt) = (lo.col.to_usize(), hi_opt.map(|hi|hi.col.to_usize()));
            if let Some(line) = line_opt {
                if line.len() > lo {
                    buf.push_str(match hi_opt {
                        Some(hi) => &line[lo..hi],
                        None => &line[lo..],
                    });
                }
                if let None = hi_opt {
                    buf.push('\n');
                }
            }
        }

        let mut primary_spans = self.msp.primary_spans().to_owned();

        assert_eq!(primary_spans.len(), self.substitutes.len());
        if primary_spans.is_empty() {
            return format!("");
        }

        // Assumption: all spans are in the same file, and all spans
        // are disjoint. Sort in ascending order.
        primary_spans.sort_by_key(|sp| sp.lo);

        // Find the bounding span.
        let lo = primary_spans.iter().map(|sp| sp.lo).min().unwrap();
        let hi = primary_spans.iter().map(|sp| sp.hi).min().unwrap();
        let bounding_span = Span { lo: lo, hi: hi, expn_id: NO_EXPANSION };
        let lines = cm.span_to_lines(bounding_span).unwrap();
        assert!(!lines.lines.is_empty());

        // To build up the result, we do this for each span:
        // - push the line segment trailing the previous span
        //   (at the beginning a "phantom" span pointing at the start of the line)
        // - push lines between the previous and current span (if any)
        // - if the previous and current span are not on the same line
        //   push the line segment leading up to the current span
        // - splice in the span substitution
        //
        // Finally push the trailing line segment of the last span
        let fm = &lines.file;
        let mut prev_hi = cm.lookup_char_pos(bounding_span.lo);
        prev_hi.col = CharPos::from_usize(0);

        let mut prev_line = fm.get_line(lines.lines[0].line_index);
        let mut buf = String::new();

        for (sp, substitute) in primary_spans.iter().zip(self.substitutes.iter()) {
            let cur_lo = cm.lookup_char_pos(sp.lo);
            if prev_hi.line == cur_lo.line {
                push_trailing(&mut buf, prev_line, &prev_hi, Some(&cur_lo));
            } else {
                push_trailing(&mut buf, prev_line, &prev_hi, None);
                // push lines between the previous and current span (if any)
                for idx in prev_hi.line..(cur_lo.line - 1) {
                    if let Some(line) = fm.get_line(idx) {
                        buf.push_str(line);
                        buf.push('\n');
                    }
                }
                if let Some(cur_line) = fm.get_line(cur_lo.line - 1) {
                    buf.push_str(&cur_line[.. cur_lo.col.to_usize()]);
                }
            }
            buf.push_str(substitute);
            prev_hi = cm.lookup_char_pos(sp.hi);
            prev_line = fm.get_line(prev_hi.line - 1);
        }
        push_trailing(&mut buf, prev_line, &prev_hi, None);
        // remove trailing newline
        buf.pop();
        buf
    }
}

/// Used as a return value to signify a fatal error occurred. (It is also
/// used as the argument to panic at the moment, but that will eventually
/// not be true.)
#[derive(Copy, Clone, Debug)]
#[must_use]
pub struct FatalError;

impl fmt::Display for FatalError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "parser fatal error")
    }
}

impl error::Error for FatalError {
    fn description(&self) -> &str {
        "The parser has encountered a fatal error"
    }
}

/// Signifies that the compiler died with an explicit call to `.bug`
/// or `.span_bug` rather than a failed assertion, etc.
#[derive(Copy, Clone, Debug)]
pub struct ExplicitBug;

impl fmt::Display for ExplicitBug {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "parser internal bug")
    }
}

impl error::Error for ExplicitBug {
    fn description(&self) -> &str {
        "The parser has encountered an internal bug"
    }
}

/// Used for emitting structured error messages and other diagnostic information.
#[must_use]
#[derive(Clone)]
pub struct DiagnosticBuilder<'a> {
    handler: &'a Handler,
    pub level: Level,
    pub message: String,
    pub code: Option<String>,
    pub span: MultiSpan,
    pub children: Vec<SubDiagnostic>,
}

/// For example a note attached to an error.
#[derive(Clone)]
pub struct SubDiagnostic {
    pub level: Level,
    pub message: String,
    pub span: MultiSpan,
    pub render_span: Option<RenderSpan>,
}

impl<'a> DiagnosticBuilder<'a> {
    /// Emit the diagnostic.
    pub fn emit(&mut self) {
        if self.cancelled() {
            return;
        }

        self.handler.emitter.borrow_mut().emit(&self);
        self.cancel();
        self.handler.panic_if_treat_err_as_bug();

        // if self.is_fatal() {
        //     panic!(FatalError);
        // }
    }

    /// Cancel the diagnostic (a structured diagnostic must either be emitted or
    /// cancelled or it will panic when dropped).
    /// BEWARE: if this DiagnosticBuilder is an error, then creating it will
    /// bump the error count on the Handler and cancelling it won't undo that.
    /// If you want to decrement the error count you should use `Handler::cancel`.
    pub fn cancel(&mut self) {
        self.level = Level::Cancelled;
    }

    pub fn cancelled(&self) -> bool {
        self.level == Level::Cancelled
    }

    pub fn is_fatal(&self) -> bool {
        self.level == Level::Fatal
    }

    /// Add a span/label to be included in the resulting snippet.
    /// This is pushed onto the `MultiSpan` that was created when the
    /// diagnostic was first built. If you don't call this function at
    /// all, and you just supplied a `Span` to create the diagnostic,
    /// then the snippet will just include that `Span`, which is
    /// called the primary span.
    pub fn span_label(&mut self, span: Span, label: &fmt::Display)
                      -> &mut DiagnosticBuilder<'a> {
        self.span.push_span_label(span, format!("{}", label));
        self
    }

    pub fn note_expected_found(&mut self,
                               label: &fmt::Display,
                               expected: &fmt::Display,
                               found: &fmt::Display)
                               -> &mut DiagnosticBuilder<'a>
    {
        // For now, just attach these as notes
        self.note(&format!("expected {} `{}`", label, expected));
        self.note(&format!("   found {} `{}`", label, found));
        self
    }

    pub fn note(&mut self, msg: &str) -> &mut DiagnosticBuilder<'a> {
        self.sub(Level::Note, msg, MultiSpan::new(), None);
        self
    }
    pub fn span_note<S: Into<MultiSpan>>(&mut self,
                                         sp: S,
                                         msg: &str)
                                         -> &mut DiagnosticBuilder<'a> {
        self.sub(Level::Note, msg, sp.into(), None);
        self
    }
    pub fn warn(&mut self, msg: &str) -> &mut DiagnosticBuilder<'a> {
        self.sub(Level::Warning, msg, MultiSpan::new(), None);
        self
    }
    pub fn span_warn<S: Into<MultiSpan>>(&mut self,
                                         sp: S,
                                         msg: &str)
                                         -> &mut DiagnosticBuilder<'a> {
        self.sub(Level::Warning, msg, sp.into(), None);
        self
    }
    pub fn help(&mut self , msg: &str) -> &mut DiagnosticBuilder<'a> {
        self.sub(Level::Help, msg, MultiSpan::new(), None);
        self
    }
    pub fn span_help<S: Into<MultiSpan>>(&mut self,
                                         sp: S,
                                         msg: &str)
                                         -> &mut DiagnosticBuilder<'a> {
        self.sub(Level::Help, msg, sp.into(), None);
        self
    }
    /// Prints out a message with a suggested edit of the code.
    ///
    /// See `diagnostic::RenderSpan::Suggestion` for more information.
    pub fn span_suggestion<S: Into<MultiSpan>>(&mut self,
                                               sp: S,
                                               msg: &str,
                                               suggestion: String)
                                               -> &mut DiagnosticBuilder<'a> {
        self.sub(Level::Help, msg, MultiSpan::new(), Some(Suggestion(CodeSuggestion {
            msp: sp.into(),
            substitutes: vec![suggestion],
        })));
        self
    }

    pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self {
        self.span = sp.into();
        self
    }

    pub fn code(&mut self, s: String) -> &mut Self {
        self.code = Some(s);
        self
    }

    pub fn message(&self) -> &str {
        &self.message
    }

    pub fn level(&self) -> Level {
        self.level
    }

    /// Convenience function for internal use, clients should use one of the
    /// struct_* methods on Handler.
    fn new(handler: &'a Handler,
           level: Level,
           message: &str) -> DiagnosticBuilder<'a> {
        DiagnosticBuilder::new_with_code(handler, level, None, message)
    }

    /// Convenience function for internal use, clients should use one of the
    /// struct_* methods on Handler.
    fn new_with_code(handler: &'a Handler,
           level: Level,
           code: Option<String>,
           message: &str) -> DiagnosticBuilder<'a> {
        DiagnosticBuilder {
            handler: handler,
            level: level,
            message: message.to_owned(),
            code: code,
            span: MultiSpan::new(),
            children: vec![],
        }
    }

    /// Convenience function for internal use, clients should use one of the
    /// public methods above.
    fn sub(&mut self,
           level: Level,
           message: &str,
           span: MultiSpan,
           render_span: Option<RenderSpan>) {
        let sub = SubDiagnostic {
            level: level,
            message: message.to_owned(),
            span: span,
            render_span: render_span,
        };
        self.children.push(sub);
    }
}

impl<'a> fmt::Debug for DiagnosticBuilder<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.message.fmt(f)
    }
}

/// Destructor bomb - a DiagnosticBuilder must be either emitted or cancelled or
/// we emit a bug.
impl<'a> Drop for DiagnosticBuilder<'a> {
    fn drop(&mut self) {
        if !panicking() && !self.cancelled() {
            let mut db = DiagnosticBuilder::new(self.handler,
                                                Bug,
                                                "Error constructed but not emitted");
            db.emit();
            panic!();
        }
    }
}

/// A handler deals with errors; certain errors
/// (fatal, bug, unimpl) may cause immediate exit,
/// others log errors for later reporting.
pub struct Handler {
    err_count: Cell<usize>,
    emitter: RefCell<Box<Emitter>>,
    pub can_emit_warnings: bool,
    treat_err_as_bug: bool,
    continue_after_error: Cell<bool>,
    delayed_span_bug: RefCell<Option<(MultiSpan, String)>>,
}

impl Handler {
    pub fn with_tty_emitter(color_config: ColorConfig,
                            registry: Option<registry::Registry>,
                            can_emit_warnings: bool,
                            treat_err_as_bug: bool,
                            cm: Option<Rc<CodeMapper>>)
                            -> Handler {
        let emitter = Box::new(EmitterWriter::stderr(color_config, registry, cm,
                               snippet::FormatMode::EnvironmentSelected));
        Handler::with_emitter(can_emit_warnings, treat_err_as_bug, emitter)
    }

    pub fn with_emitter(can_emit_warnings: bool,
                        treat_err_as_bug: bool,
                        e: Box<Emitter>) -> Handler {
        Handler {
            err_count: Cell::new(0),
            emitter: RefCell::new(e),
            can_emit_warnings: can_emit_warnings,
            treat_err_as_bug: treat_err_as_bug,
            continue_after_error: Cell::new(true),
            delayed_span_bug: RefCell::new(None),
        }
    }

    pub fn set_continue_after_error(&self, continue_after_error: bool) {
        self.continue_after_error.set(continue_after_error);
    }

    pub fn struct_dummy<'a>(&'a self) -> DiagnosticBuilder<'a> {
        DiagnosticBuilder::new(self, Level::Cancelled, "")
    }

    pub fn struct_span_warn<'a, S: Into<MultiSpan>>(&'a self,
                                                    sp: S,
                                                    msg: &str)
                                                    -> DiagnosticBuilder<'a> {
        let mut result = DiagnosticBuilder::new(self, Level::Warning, msg);
        result.set_span(sp);
        if !self.can_emit_warnings {
            result.cancel();
        }
        result
    }
    pub fn struct_span_warn_with_code<'a, S: Into<MultiSpan>>(&'a self,
                                                              sp: S,
                                                              msg: &str,
                                                              code: &str)
                                                              -> DiagnosticBuilder<'a> {
        let mut result = DiagnosticBuilder::new(self, Level::Warning, msg);
        result.set_span(sp);
        result.code(code.to_owned());
        if !self.can_emit_warnings {
            result.cancel();
        }
        result
    }
    pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
        let mut result = DiagnosticBuilder::new(self, Level::Warning, msg);
        if !self.can_emit_warnings {
            result.cancel();
        }
        result
    }
    pub fn struct_span_err<'a, S: Into<MultiSpan>>(&'a self,
                                                   sp: S,
                                                   msg: &str)
                                                   -> DiagnosticBuilder<'a> {
        self.bump_err_count();
        let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
        result.set_span(sp);
        result
    }
    pub fn struct_span_err_with_code<'a, S: Into<MultiSpan>>(&'a self,
                                                             sp: S,
                                                             msg: &str,
                                                             code: &str)
                                                             -> DiagnosticBuilder<'a> {
        self.bump_err_count();
        let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
        result.set_span(sp);
        result.code(code.to_owned());
        result
    }
    pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
        self.bump_err_count();
        DiagnosticBuilder::new(self, Level::Error, msg)
    }
    pub fn struct_span_fatal<'a, S: Into<MultiSpan>>(&'a self,
                                                     sp: S,
                                                     msg: &str)
                                                     -> DiagnosticBuilder<'a> {
        self.bump_err_count();
        let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg);
        result.set_span(sp);
        result
    }
    pub fn struct_span_fatal_with_code<'a, S: Into<MultiSpan>>(&'a self,
                                                               sp: S,
                                                               msg: &str,
                                                               code: &str)
                                                               -> DiagnosticBuilder<'a> {
        self.bump_err_count();
        let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg);
        result.set_span(sp);
        result.code(code.to_owned());
        result
    }
    pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
        self.bump_err_count();
        DiagnosticBuilder::new(self, Level::Fatal, msg)
    }

    pub fn cancel(&self, err: &mut DiagnosticBuilder) {
        if err.level == Level::Error || err.level == Level::Fatal {
            self.err_count.set(
                self.err_count.get().checked_sub(1)
                    .expect("cancelled an error but err_count is 0")
            );
        }
        err.cancel();
    }

    fn panic_if_treat_err_as_bug(&self) {
        if self.treat_err_as_bug {
            panic!("encountered error with `-Z treat_err_as_bug");
        }
    }

    pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str)
                                          -> FatalError {
        self.emit(&sp.into(), msg, Fatal);
        self.bump_err_count();
        self.panic_if_treat_err_as_bug();
        return FatalError;
    }
    pub fn span_fatal_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: &str)
                                                    -> FatalError {
        self.emit_with_code(&sp.into(), msg, code, Fatal);
        self.bump_err_count();
        self.panic_if_treat_err_as_bug();
        return FatalError;
    }
    pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
        self.emit(&sp.into(), msg, Error);
        self.bump_err_count();
        self.panic_if_treat_err_as_bug();
    }
    pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: &str) {
        self.emit_with_code(&sp.into(), msg, code, Error);
        self.bump_err_count();
        self.panic_if_treat_err_as_bug();
    }
    pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
        self.emit(&sp.into(), msg, Warning);
    }
    pub fn span_warn_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: &str) {
        self.emit_with_code(&sp.into(), msg, code, Warning);
    }
    pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
        self.emit(&sp.into(), msg, Bug);
        panic!(ExplicitBug);
    }
    pub fn delay_span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
        let mut delayed = self.delayed_span_bug.borrow_mut();
        *delayed = Some((sp.into(), msg.to_string()));
    }
    pub fn span_bug_no_panic<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
        self.emit(&sp.into(), msg, Bug);
        self.bump_err_count();
    }
    pub fn span_note_without_error<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
        self.emit(&sp.into(), msg, Note);
    }
    pub fn span_unimpl<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
        self.span_bug(sp, &format!("unimplemented {}", msg));
    }
    pub fn fatal(&self, msg: &str) -> FatalError {
        if self.treat_err_as_bug {
            self.bug(msg);
        }
        let mut db = DiagnosticBuilder::new(self,
                                            Fatal,
                                            msg);
        db.emit();
        self.bump_err_count();
        FatalError
    }
    pub fn err(&self, msg: &str) {
        if self.treat_err_as_bug {
            self.bug(msg);
        }
        let mut db = DiagnosticBuilder::new(self,
                                            Error,
                                            msg);
        db.emit();
        self.bump_err_count();
    }
    pub fn warn(&self, msg: &str) {
        let mut db = DiagnosticBuilder::new(self,
                                            Warning,
                                            msg);
        db.emit();
    }
    pub fn note_without_error(&self, msg: &str) {
        let mut db = DiagnosticBuilder::new(self,
                                            Note,
                                            msg);
        db.emit();
    }
    pub fn bug(&self, msg: &str) -> ! {
        let mut db = DiagnosticBuilder::new(self,
                                            Bug,
                                            msg);
        db.emit();
        panic!(ExplicitBug);
    }
    pub fn unimpl(&self, msg: &str) -> ! {
        self.bug(&format!("unimplemented {}", msg));
    }

    pub fn bump_err_count(&self) {
        self.err_count.set(self.err_count.get() + 1);
    }

    pub fn err_count(&self) -> usize {
        self.err_count.get()
    }

    pub fn has_errors(&self) -> bool {
        self.err_count.get() > 0
    }
    pub fn abort_if_errors(&self) {
        let s;
        match self.err_count.get() {
            0 => {
                let delayed_bug = self.delayed_span_bug.borrow();
                match *delayed_bug {
                    Some((ref span, ref errmsg)) => {
                        self.span_bug(span.clone(), errmsg);
                    },
                    _ => {}
                }

                return;
            }
            1 => s = "aborting due to previous error".to_string(),
            _  => {
                s = format!("aborting due to {} previous errors",
                            self.err_count.get());
            }
        }

        panic!(self.fatal(&s));
    }
    pub fn emit(&self,
                msp: &MultiSpan,
                msg: &str,
                lvl: Level) {
        if lvl == Warning && !self.can_emit_warnings { return }
        let mut db = DiagnosticBuilder::new(self, lvl, msg);
        db.set_span(msp.clone());
        db.emit();
        if !self.continue_after_error.get() { self.abort_if_errors(); }
    }
    pub fn emit_with_code(&self,
                          msp: &MultiSpan,
                          msg: &str,
                          code: &str,
                          lvl: Level) {
        if lvl == Warning && !self.can_emit_warnings { return }
        let mut db = DiagnosticBuilder::new_with_code(self,
                                                      lvl,
                                                      Some(code.to_owned()),
                                                      msg);
        db.set_span(msp.clone());
        db.emit();
        if !self.continue_after_error.get() { self.abort_if_errors(); }
    }
}


#[derive(Copy, PartialEq, Clone, Debug)]
pub enum Level {
    Bug,
    Fatal,
    // An error which while not immediately fatal, should stop the compiler
    // progressing beyond the current phase.
    PhaseFatal,
    Error,
    Warning,
    Note,
    Help,
    Cancelled,
}

impl fmt::Display for Level {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.to_str().fmt(f)
    }
}

impl Level {
    pub fn color(self) -> term::color::Color {
        match self {
            Bug | Fatal | PhaseFatal | Error => term::color::BRIGHT_RED,
            Warning => term::color::YELLOW,
            Note => term::color::BRIGHT_GREEN,
            Help => term::color::BRIGHT_CYAN,
            Cancelled => unreachable!(),
        }
    }

    pub fn to_str(self) -> &'static str {
        match self {
            Bug => "error: internal compiler error",
            Fatal | PhaseFatal | Error => "error",
            Warning => "warning",
            Note => "note",
            Help => "help",
            Cancelled => panic!("Shouldn't call on cancelled error"),
        }
    }
}

pub fn expect<T, M>(diag: &Handler, opt: Option<T>, msg: M) -> T where
    M: FnOnce() -> String,
{
    match opt {
        Some(t) => t,
        None => diag.bug(&msg()),
    }
}

/// True if we should use the old-skool error format style. This is
/// the default setting until the new errors are deemed stable enough
/// for general use.
///
/// FIXME(#33240)
#[cfg(not(test))]
pub fn check_old_school() -> bool {
    use std::env;
    env::var("RUST_NEW_ERROR_FORMAT").is_err()
}

/// For unit tests, use the new format.
#[cfg(test)]
pub fn check_old_school() -> bool {
    false
}
