Got Rust to Segfault!

This commit is contained in:
Brooks J Rady 2024-04-23 19:43:35 -07:00
parent ea4296dace
commit e5ea3231e8
13 changed files with 165 additions and 281 deletions

2
.helix/languages.toml Normal file
View File

@ -0,0 +1,2 @@
[language-server.rust-analyzer]
config = { cargo = { features = "all" } }

View File

@ -1,4 +1,4 @@
use super::error::{ContextError, ErrorImpl};
use super::error::ContextError;
use super::{Report, WrapErr};
use core::fmt::{self, Debug, Display, Write};
@ -27,15 +27,6 @@ mod ext {
Report::from_msg(msg, self)
}
}
impl Diag for Report {
fn ext_report<D>(self, msg: D) -> Report
where
D: Display + Send + Sync + 'static,
{
self.wrap_err(msg)
}
}
}
impl<T, E> WrapErr<T, E> for Result<T, E>
@ -111,15 +102,6 @@ where
}
}
impl<D> StdError for ContextError<D, Report>
where
D: Display,
{
fn source(&self) -> Option<&(dyn StdError + 'static)> {
unsafe { Some(ErrorImpl::error(self.error.inner.by_ref())) }
}
}
impl<D, E> Diagnostic for ContextError<D, E>
where
D: Display,
@ -154,39 +136,6 @@ where
}
}
impl<D> Diagnostic for ContextError<D, Report>
where
D: Display,
{
fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
unsafe { ErrorImpl::diagnostic(self.error.inner.by_ref()).code() }
}
fn severity(&self) -> Option<crate::Severity> {
unsafe { ErrorImpl::diagnostic(self.error.inner.by_ref()).severity() }
}
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
unsafe { ErrorImpl::diagnostic(self.error.inner.by_ref()).help() }
}
fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
unsafe { ErrorImpl::diagnostic(self.error.inner.by_ref()).url() }
}
fn labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>> {
unsafe { ErrorImpl::diagnostic(self.error.inner.by_ref()).labels() }
}
fn source_code(&self) -> Option<&dyn crate::SourceCode> {
self.error.source_code()
}
fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
self.error.related()
}
}
struct Quoted<D>(D);
impl<D> Debug for Quoted<D>

View File

@ -2,6 +2,7 @@ use core::any::TypeId;
use core::fmt::{self, Debug, Display};
use core::mem::ManuallyDrop;
use core::ptr::{self, NonNull};
use std::any::type_name;
use std::error::Error as StdError;
use super::ptr::{Mut, Own, Ref};
@ -9,7 +10,7 @@ use super::Report;
use super::ReportHandler;
use crate::chain::Chain;
use crate::eyreish::wrapper::WithSourceCode;
use crate::{Diagnostic, SourceCode};
use crate::{Diagnostic, LabeledSpan, Severity, SourceCode};
use core::ops::{Deref, DerefMut};
impl Report {
@ -25,7 +26,8 @@ impl Report {
where
E: Diagnostic + Send + Sync + 'static,
{
Report::from_std(error)
dbg!("HEEEEEEEEEEEEEEEEEELLLLLLLLLLLLLLLOOOOOOOOOOOOOOOOOOOOOO>?");
dbg!(Report::from_std(error))
}
/// Create a new error object from a printable error message.
@ -94,8 +96,6 @@ impl Report {
object_drop: object_drop::<E>,
object_ref: object_ref::<E>,
object_ref_stderr: object_ref_stderr::<E>,
object_boxed: object_boxed::<E>,
object_boxed_stderr: object_boxed_stderr::<E>,
object_downcast: object_downcast::<E>,
object_drop_rest: object_drop_front::<E>,
};
@ -117,8 +117,6 @@ impl Report {
object_drop: object_drop::<MessageError<M>>,
object_ref: object_ref::<MessageError<M>>,
object_ref_stderr: object_ref_stderr::<MessageError<M>>,
object_boxed: object_boxed::<MessageError<M>>,
object_boxed_stderr: object_boxed_stderr::<MessageError<M>>,
object_downcast: object_downcast::<M>,
object_drop_rest: object_drop_front::<M>,
};
@ -142,8 +140,6 @@ impl Report {
object_drop: object_drop::<ContextError<D, E>>,
object_ref: object_ref::<ContextError<D, E>>,
object_ref_stderr: object_ref_stderr::<ContextError<D, E>>,
object_boxed: object_boxed::<ContextError<D, E>>,
object_boxed_stderr: object_boxed_stderr::<ContextError<D, E>>,
object_downcast: context_downcast::<D, E>,
object_drop_rest: context_drop_rest::<D, E>,
};
@ -164,8 +160,6 @@ impl Report {
object_drop: object_drop::<BoxedError>,
object_ref: object_ref::<BoxedError>,
object_ref_stderr: object_ref_stderr::<BoxedError>,
object_boxed: object_boxed::<BoxedError>,
object_boxed_stderr: object_boxed_stderr::<BoxedError>,
object_downcast: object_downcast::<Box<dyn Diagnostic + Send + Sync>>,
object_drop_rest: object_drop_front::<Box<dyn Diagnostic + Send + Sync>>,
};
@ -223,8 +217,6 @@ impl Report {
object_drop: object_drop::<ContextError<D, Report>>,
object_ref: object_ref::<ContextError<D, Report>>,
object_ref_stderr: object_ref_stderr::<ContextError<D, Report>>,
object_boxed: object_boxed::<ContextError<D, Report>>,
object_boxed_stderr: object_boxed_stderr::<ContextError<D, Report>>,
object_downcast: context_chain_downcast::<D>,
object_drop_rest: context_chain_drop_rest::<D>,
};
@ -363,7 +355,11 @@ impl Report {
unsafe {
// Use vtable to find NonNull<()> which points to a value of type E
// somewhere inside the data structure.
let addr = (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?;
dbg!(type_name::<E>());
let addr = dbg!((vtable(self.inner.ptr).object_downcast)(
self.inner.by_ref(),
target
))?;
Some(addr.cast::<E>().deref())
}
}
@ -411,21 +407,10 @@ impl Report {
/// Provide source code for this error
pub fn with_source_code(self, source_code: impl SourceCode + Send + Sync + 'static) -> Report {
WithSourceCode {
Self::new(WithSourceCode {
source_code,
error: self,
}
.into()
}
}
impl<E> From<E> for Report
where
E: Diagnostic + Send + Sync + 'static,
{
#[cfg_attr(track_caller, track_caller)]
fn from(error: E) -> Self {
Report::from_std(error)
})
}
}
@ -464,17 +449,52 @@ impl Drop for Report {
}
}
impl StdError for Report {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
(**self).source()
}
}
impl Diagnostic for Report {
fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
(**self).code()
}
fn severity(&self) -> Option<Severity> {
(**self).severity()
}
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
(**self).help()
}
fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
(**self).url()
}
fn source_code(&self) -> Option<&dyn SourceCode> {
(**self).source_code()
}
fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
(**self).labels()
}
fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
(**self).related()
}
fn diagnostic_source(&self) -> Option<&dyn Diagnostic> {
(**self).diagnostic_source()
}
}
struct ErrorVTable {
object_drop: unsafe fn(Own<ErasedErrorImpl>),
object_ref:
unsafe fn(Ref<'_, ErasedErrorImpl>) -> Ref<'_, dyn Diagnostic + Send + Sync + 'static>,
object_ref_stderr:
unsafe fn(Ref<'_, ErasedErrorImpl>) -> Ref<'_, dyn StdError + Send + Sync + 'static>,
#[allow(clippy::type_complexity)]
object_boxed: unsafe fn(Own<ErasedErrorImpl>) -> Box<dyn Diagnostic + Send + Sync + 'static>,
#[allow(clippy::type_complexity)]
object_boxed_stderr:
unsafe fn(Own<ErasedErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>,
object_downcast: unsafe fn(Ref<'_, ErasedErrorImpl>, TypeId) -> Option<Ref<'_, ()>>,
object_drop_rest: unsafe fn(Own<ErasedErrorImpl>, TypeId),
}
@ -527,31 +547,15 @@ where
))
}
// Safety: requires layout of *e to match ErrorImpl<E>.
unsafe fn object_boxed<E>(e: Own<ErasedErrorImpl>) -> Box<dyn Diagnostic + Send + Sync + 'static>
where
E: Diagnostic + Send + Sync + 'static,
{
// Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below.
e.cast::<ErrorImpl<E>>().boxed()
}
// Safety: requires layout of *e to match ErrorImpl<E>.
unsafe fn object_boxed_stderr<E>(
e: Own<ErasedErrorImpl>,
) -> Box<dyn StdError + Send + Sync + 'static>
where
E: StdError + Send + Sync + 'static,
{
// Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below.
e.cast::<ErrorImpl<E>>().boxed()
}
// Safety: requires layout of *e to match ErrorImpl<E>.
unsafe fn object_downcast<E>(e: Ref<'_, ErasedErrorImpl>, target: TypeId) -> Option<Ref<'_, ()>>
where
E: 'static,
{
dbg!(
"object_downcast????????????????????????????????????????????????????????????????",
type_name::<E>()
);
if TypeId::of::<E>() == target {
// Caller is looking for an E pointer and e is ErrorImpl<E>, take a
// pointer to its E field.
@ -745,40 +749,6 @@ where
}
}
impl From<Report> for Box<dyn Diagnostic + Send + Sync + 'static> {
fn from(error: Report) -> Self {
let outer = ManuallyDrop::new(error);
unsafe {
// Use vtable to attach ErrorImpl<E>'s native StdError vtable for
// the right original type E.
(vtable(outer.inner.ptr).object_boxed)(outer.inner)
}
}
}
impl From<Report> for Box<dyn StdError + Send + Sync + 'static> {
fn from(error: Report) -> Self {
let outer = ManuallyDrop::new(error);
unsafe {
// Use vtable to attach ErrorImpl<E>'s native StdError vtable for
// the right original type E.
(vtable(outer.inner.ptr).object_boxed_stderr)(outer.inner)
}
}
}
impl From<Report> for Box<dyn Diagnostic + 'static> {
fn from(error: Report) -> Self {
Box::<dyn Diagnostic + Send + Sync>::from(error)
}
}
impl From<Report> for Box<dyn StdError + 'static> {
fn from(error: Report) -> Self {
Box::<dyn StdError + Send + Sync>::from(error)
}
}
impl AsRef<dyn Diagnostic + Send + Sync> for Report {
fn as_ref(&self) -> &(dyn Diagnostic + Send + Sync + 'static) {
&**self

View File

@ -28,6 +28,6 @@ pub trait IntoDiagnostic<T, E> {
impl<T, E: std::error::Error + Send + Sync + 'static> IntoDiagnostic<T, E> for Result<T, E> {
fn into_diagnostic(self) -> Result<T, Report> {
self.map_err(|e| DiagnosticError(Box::new(e)).into())
self.map_err(|e| Report::new(DiagnosticError(Box::new(e))))
}
}

View File

@ -80,15 +80,15 @@ pub trait TraitKind: Sized {
}
}
impl<E> TraitKind for E where E: Into<Report> {}
impl<E> TraitKind for E where E: Diagnostic + Send + Sync + 'static {}
impl Trait {
#[cfg_attr(track_caller, track_caller)]
pub fn new<E>(self, error: E) -> Report
where
E: Into<Report>,
E: Diagnostic + Send + Sync + 'static,
{
error.into()
Report::new(error)
}
}

View File

@ -228,7 +228,7 @@ macro_rules! ensure {
#[macro_export]
macro_rules! miette {
($($key:ident = $value:expr,)* $fmt:literal $($arg:tt)*) => {
$crate::Report::from(
$crate::Report::new(
$crate::diagnostic!($($key = $value,)* $fmt $($arg)*)
)
};

View File

@ -58,6 +58,8 @@ where
}
}
// FIXME: Delete this derive!
#[derive(Debug)]
#[allow(explicit_outlives_requirements)]
#[repr(transparent)]
/// A raw pointer that represents a shared borrow of its pointee

View File

@ -2,7 +2,7 @@ use core::fmt::{self, Debug, Display};
use std::error::Error as StdError;
use crate::{Diagnostic, LabeledSpan, Report, SourceCode};
use crate::{Diagnostic, LabeledSpan, SourceCode};
use crate as miette;
@ -134,40 +134,6 @@ impl<E: Diagnostic, C: SourceCode> Diagnostic for WithSourceCode<E, C> {
}
}
impl<C: SourceCode> Diagnostic for WithSourceCode<Report, C> {
fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
self.error.code()
}
fn severity(&self) -> Option<miette::Severity> {
self.error.severity()
}
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
self.error.help()
}
fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
self.error.url()
}
fn labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>> {
self.error.labels()
}
fn source_code(&self) -> Option<&dyn miette::SourceCode> {
self.error.source_code().or(Some(&self.source_code))
}
fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
self.error.related()
}
fn diagnostic_source(&self) -> Option<&dyn Diagnostic> {
self.error.diagnostic_source()
}
}
impl<E: Debug, C> Debug for WithSourceCode<E, C> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Debug::fmt(&self.error, f)
@ -186,12 +152,6 @@ impl<E: StdError, C> StdError for WithSourceCode<E, C> {
}
}
impl<C> StdError for WithSourceCode<Report, C> {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
self.error.source()
}
}
#[cfg(test)]
mod tests {
use thiserror::Error;
@ -232,7 +192,7 @@ mod tests {
let inner_source = "hello world";
let outer_source = "abc";
let report = Report::from(Inner {
let report = Report::new(Inner {
at: (0..5).into(),
source_code: Some(inner_source.to_string()),
})
@ -257,7 +217,7 @@ mod tests {
let inner_source = "hello world";
let outer_source = "abc";
let report = Report::from(Outer {
let report = Report::new(Outer {
errors: vec![
Inner {
at: (0..5).into(),

View File

@ -1,7 +1,7 @@
use backtrace::Backtrace;
use thiserror::Error;
use crate::{self as miette, Context, Diagnostic, Result};
use crate::{self as miette, Context, Diagnostic, Report, Result};
/// Tells miette to render panics using its rendering engine.
pub fn set_panic_hook() {
@ -14,7 +14,7 @@ pub fn set_panic_hook() {
if let Some(msg) = payload.downcast_ref::<String>() {
message = msg.clone();
}
let mut report: Result<()> = Err(Panic(message).into());
let mut report: Result<()> = Err(Report::new(Panic(message)));
if let Some(loc) = info.location() {
report = report
.with_context(|| format!("at {}:{}:{}", loc.file(), loc.line(), loc.column()));

View File

@ -6,38 +6,38 @@ use miette::{
};
use thiserror::Error;
fn fmt_report(diag: Report) -> String {
fn fmt_report(diag: impl Diagnostic) -> String {
let mut out = String::new();
// Mostly for dev purposes.
if std::env::var("STYLE").is_ok() {
GraphicalReportHandler::new_themed(GraphicalTheme::unicode())
.with_width(80)
.with_footer("this is a footer".into())
.render_report(&mut out, diag.as_ref())
.render_report(&mut out, &diag)
.unwrap();
} else if std::env::var("NARRATED").is_ok() {
NarratableReportHandler::new()
.render_report(&mut out, diag.as_ref())
.render_report(&mut out, &diag)
.unwrap();
} else if let Ok(w) = std::env::var("REPLACE_TABS") {
GraphicalReportHandler::new_themed(GraphicalTheme::unicode_nocolor())
.without_syntax_highlighting()
.with_width(80)
.tab_width(w.parse().expect("Invalid tab width."))
.render_report(&mut out, diag.as_ref())
.render_report(&mut out, &diag)
.unwrap();
} else {
GraphicalReportHandler::new_themed(GraphicalTheme::unicode_nocolor())
.without_syntax_highlighting()
.with_width(80)
.render_report(&mut out, diag.as_ref())
.render_report(&mut out, &diag)
.unwrap();
};
out
}
fn fmt_report_with_settings(
diag: Report,
diag: impl Diagnostic,
with_settings: fn(GraphicalReportHandler) -> GraphicalReportHandler,
) -> String {
let mut out = String::new();
@ -46,7 +46,7 @@ fn fmt_report_with_settings(
GraphicalTheme::unicode_nocolor(),
));
handler.render_report(&mut out, diag.as_ref()).unwrap();
handler.render_report(&mut out, &diag).unwrap();
println!("Error:\n```\n{}\n```", out);
@ -299,7 +299,7 @@ fn wrapping_nested_errors() -> Result<(), MietteError> {
struct BabyError;
let err = MamaError { baby: BabyError };
let out = fmt_report_with_settings(err.into(), |handler| handler.with_width(50));
let out = fmt_report_with_settings(err, |handler| handler.with_width(50));
let expected = r#"mama::error
× This is the parent error, the error withhhhh
@ -368,7 +368,7 @@ fn wrapping_related_errors() -> Result<(), MietteError> {
brethren: vec![BabyError.into(), BabyWarning.into(), BabyAdvice.into()],
},
};
let out = fmt_report_with_settings(err.into(), |handler| handler.with_width(50));
let out = fmt_report_with_settings(err, |handler| handler.with_width(50));
let expected = r#"mama::error
× This is the parent error, the error withhhhh
@ -427,7 +427,7 @@ fn empty_source() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (0, 0).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
// For an empty string, the label cannot be rendered.
let expected = r#"oops::my::bad
@ -469,7 +469,7 @@ if true {
big: (0, 32).into(),
small: (14, 1).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"
@ -505,7 +505,7 @@ fn single_line_highlight_span_full_line() {
src: NamedSource::new("issue", "source\ntext"),
bad_bit: (7, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"
@ -539,7 +539,7 @@ fn single_line_with_wide_char() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (13, 8).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -578,7 +578,7 @@ fn single_line_with_two_tabs() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -617,7 +617,7 @@ fn single_line_with_tab_in_middle() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (14, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -654,7 +654,7 @@ fn single_line_highlight() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -685,7 +685,7 @@ fn external_source() -> Result<(), MietteError> {
}
let src = "source\n text\n here".to_string();
let err = Report::from(MyBad {
let err = Report::new(MyBad {
highlight: (9, 4).into(),
})
.with_source_code(NamedSource::new("bad_file.rs", src));
@ -726,7 +726,7 @@ fn single_line_highlight_offset_zero() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (0, 0).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -762,7 +762,7 @@ fn single_line_highlight_offset_end_of_line() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (6, 0).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -798,7 +798,7 @@ fn single_line_highlight_include_end_of_line() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 5).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -835,7 +835,7 @@ fn single_line_highlight_include_end_of_line_crlf() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (10, 6).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -872,7 +872,7 @@ fn single_line_highlight_with_empty_span() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 0).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -909,7 +909,7 @@ fn single_line_highlight_no_label() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -945,7 +945,7 @@ fn single_line_highlight_at_line_start() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (7, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -982,7 +982,7 @@ fn multiline_label() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (7, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -1028,7 +1028,7 @@ fn multiple_multi_line_labels() -> Result<(), MietteError> {
highlight2: (14, 4).into(),
highlight3: (24, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -1076,7 +1076,7 @@ fn multiple_same_line_highlights() -> Result<(), MietteError> {
highlight2: (14, 4).into(),
highlight3: (24, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -1123,7 +1123,7 @@ fn multiple_same_line_highlights_with_tabs_in_middle() -> Result<(), MietteError
highlight2: (14, 4).into(),
highlight3: (24, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -1162,7 +1162,7 @@ fn multiline_highlight_adjacent() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 11).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -1198,7 +1198,7 @@ fn multiline_highlight_multiline_label() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 11).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -1245,7 +1245,7 @@ line5
highlight1: (0, len).into(),
highlight2: (10, 9).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -1305,7 +1305,7 @@ line5
highlight1: (0, len).into(),
highlight2: (10, 9).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = "oops::my::bad
@ -1353,7 +1353,7 @@ fn multiple_multiline_highlights_adjacent() -> Result<(), MietteError> {
highlight1: (0, 10).into(),
highlight2: (20, 6).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = "oops::my::bad
@ -1399,7 +1399,7 @@ fn multiple_multiline_highlights_overlapping_lines() -> Result<(), MietteError>
highlight1: (0, 8).into(),
highlight2: (9, 10).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
assert_eq!("Error [oops::my::bad]: oops!\n\n[bad_file.rs] This is the part that broke:\n\n 1 │ source\n 2 │ text\n · ──┬─\n · ╰── this bit here\n 3 │ here\n\n﹦ try doing it better next time?\n".to_string(), out);
Ok(())
@ -1427,7 +1427,7 @@ fn multiple_multiline_highlights_overlapping_offsets() -> Result<(), MietteError
highlight1: (0, 8).into(),
highlight2: (10, 10).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
assert_eq!("Error [oops::my::bad]: oops!\n\n[bad_file.rs] This is the part that broke:\n\n 1 │ source\n 2 │ text\n · ──┬─\n · ╰── this bit here\n 3 │ here\n\n﹦ try doing it better next time?\n".to_string(), out);
Ok(())
@ -1444,7 +1444,7 @@ fn url_links() -> Result<(), MietteError> {
)]
struct MyBad;
let err = MyBad;
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
assert!(out.contains("https://example.com"));
assert!(out.contains("(link)"));
@ -1459,7 +1459,7 @@ fn url_links_no_code() -> Result<(), MietteError> {
#[diagnostic(help("try doing it better next time?"), url("https://example.com"))]
struct MyBad;
let err = MyBad;
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
assert!(out.contains("https://example.com"));
assert!(out.contains("(link)"));
@ -1500,7 +1500,7 @@ fn url_links_with_display_text() -> Result<(), MietteError> {
)]
struct MyBad;
let err = MyBad;
let out = fmt_report_with_settings(err.into(), |handler| {
let out = fmt_report_with_settings(err, |handler| {
handler.with_link_display_text("Read the documentation")
});
@ -1535,7 +1535,7 @@ fn related() -> Result<(), MietteError> {
related: vec![],
}],
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -1596,7 +1596,7 @@ fn related_source_code_propagation() -> Result<(), MietteError> {
highlight: (0, 6).into(),
}],
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -1701,7 +1701,7 @@ fn related_severity() -> Result<(), MietteError> {
},
],
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -1769,7 +1769,7 @@ fn zero_length_eol_span() {
src: NamedSource::new("issue", "this is the first line\nthis is the second line"),
bad_bit: (23, 0).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"
@ -1803,7 +1803,7 @@ fn primary_label() {
first_label: (2, 4).into(),
second_label: (24, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
// line 2 should be the primary, not line 1
@ -1839,7 +1839,7 @@ fn single_line_with_wide_char_unaligned_span_start() -> Result<(), MietteError>
src: NamedSource::new("bad_file.rs", src),
highlight: (10, 5).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -1876,7 +1876,7 @@ fn single_line_with_wide_char_unaligned_span_end() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 6).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -1913,7 +1913,7 @@ fn single_line_with_wide_char_unaligned_span_empty() -> Result<(), MietteError>
src: NamedSource::new("bad_file.rs", src),
highlight: (10, 0).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops::my::bad
@ -2055,7 +2055,7 @@ fn triple_adjacent_highlight() -> Result<(), MietteError> {
highlight2: (11, 4).into(),
highlight3: (22, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = "oops::my::bad
@ -2101,7 +2101,7 @@ fn non_adjacent_highlight() -> Result<(), MietteError> {
highlight1: (0, 6).into(),
highlight2: (12, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = "oops::my::bad
@ -2141,7 +2141,7 @@ fn invalid_span_bad_offset() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight1: (50, 6).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = "oops::my::bad
@ -2170,7 +2170,7 @@ fn invalid_span_bad_length() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight1: (0, 50).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = "oops::my::bad
@ -2199,7 +2199,7 @@ fn invalid_span_no_label() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight1: (50, 6).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = "oops::my::bad
@ -2231,7 +2231,7 @@ fn invalid_span_2nd_label() -> Result<(), MietteError> {
highlight1: (0, 6).into(),
highlight2: (50, 6).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = "oops::my::bad
@ -2277,7 +2277,7 @@ fn invalid_span_inner() -> Result<(), MietteError> {
inner_label: (60, 6).into(),
},
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = "oops::my::outer
@ -2328,7 +2328,7 @@ fn invalid_span_related() -> Result<(), MietteError> {
inner_label: (60, 6).into(),
}],
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = "oops::my::outer

View File

@ -1,22 +1,22 @@
#![cfg(feature = "fancy-no-backtrace")]
use miette::{Diagnostic, MietteError, NamedSource, NarratableReportHandler, Report, SourceSpan};
use miette::{Diagnostic, MietteError, NamedSource, NarratableReportHandler, SourceSpan};
use miette::{GraphicalReportHandler, GraphicalTheme};
use thiserror::Error;
fn fmt_report(diag: Report) -> String {
fn fmt_report(diag: impl Diagnostic) -> String {
let mut out = String::new();
// Mostly for dev purposes.
if cfg!(feature = "fancy-no-backtrace") && std::env::var("STYLE").is_ok() {
#[cfg(feature = "fancy-no-backtrace")]
GraphicalReportHandler::new_themed(GraphicalTheme::unicode())
.render_report(&mut out, diag.as_ref())
.render_report(&mut out, &diag)
.unwrap();
} else {
NarratableReportHandler::new()
.render_report(&mut out, diag.as_ref())
.render_report(&mut out, &diag)
.unwrap();
};
out
@ -39,7 +39,7 @@ fn single_line_with_wide_char() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 6).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops!
Diagnostic severity: error
@ -75,7 +75,7 @@ fn single_line_highlight() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops!
Diagnostic severity: error
@ -111,7 +111,7 @@ fn single_line_highlight_offset_zero() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (0, 0).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops!
Diagnostic severity: error
@ -146,7 +146,7 @@ fn single_line_highlight_with_empty_span() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 0).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops!
Diagnostic severity: error
@ -182,7 +182,7 @@ fn single_line_highlight_no_label() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops!
Diagnostic severity: error
@ -218,7 +218,7 @@ fn single_line_highlight_at_line_start() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (7, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops!
Diagnostic severity: error
@ -260,7 +260,7 @@ fn multiple_same_line_highlights() -> Result<(), MietteError> {
highlight2: (14, 4).into(),
highlight3: (24, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops!
Diagnostic severity: error
@ -298,7 +298,7 @@ fn multiline_highlight_adjacent() -> Result<(), MietteError> {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 11).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops!
Diagnostic severity: error
@ -345,7 +345,7 @@ line5
highlight1: (0, len).into(),
highlight2: (10, 9).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops!
Diagnostic severity: error
@ -407,7 +407,7 @@ line5
highlight1: (0, len).into(),
highlight2: (10, 9).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = "wtf?!
it broke :(
@ -457,7 +457,7 @@ fn multiple_multiline_highlights_adjacent() -> Result<(), MietteError> {
highlight1: (0, 10).into(),
highlight2: (20, 6).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = "oops!
Diagnostic severity: error
@ -505,7 +505,7 @@ fn multiple_multiline_highlights_overlapping_lines() -> Result<(), MietteError>
highlight1: (0, 8).into(),
highlight2: (9, 10).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
assert_eq!("Error [oops::my::bad]: oops!\n\n[bad_file.rs] This is the part that broke:\n\n 1 │ source\n 2 │ text\n · ──┬─\n · ╰── this bit here\n 3 │ here\n\n﹦ try doing it better next time?\n".to_string(), out);
Ok(())
@ -533,7 +533,7 @@ fn multiple_multiline_highlights_overlapping_offsets() -> Result<(), MietteError
highlight1: (0, 8).into(),
highlight2: (10, 10).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
assert_eq!("Error [oops::my::bad]: oops!\n\n[bad_file.rs] This is the part that broke:\n\n 1 │ source\n 2 │ text\n · ──┬─\n · ╰── this bit here\n 3 │ here\n\n﹦ try doing it better next time?\n".to_string(), out);
Ok(())
@ -546,7 +546,7 @@ fn url() -> Result<(), MietteError> {
#[diagnostic(help("try doing it better next time?"), url("https://example.com"))]
struct MyBad;
let err = MyBad;
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
assert!(out.contains("https://example.com"));
Ok(())
@ -576,7 +576,7 @@ fn related() -> Result<(), MietteError> {
related: vec![],
}],
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops!
Diagnostic severity: error
@ -637,7 +637,7 @@ fn related_source_code_propagation() -> Result<(), MietteError> {
highlight: (0, 6).into(),
}],
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected = r#"oops!
Diagnostic severity: error

View File

@ -43,7 +43,9 @@ fn test_boxed_thiserror() {
let error = MyError {
source: io::Error::new(io::ErrorKind::Other, "oh no!"),
};
dbg!(&error, error.source());
let report: Report = miette!(error);
dbg!(&report, report.source());
assert_eq!("oh no!", report.source().unwrap().to_string());
let error = MyError {
@ -218,7 +220,6 @@ fn test_boxed_custom_diagnostic() {
}
#[test]
#[ignore = "I don't know why this isn't working but it needs fixing."]
fn test_boxed_sources() {
let error = MyError {
source: io::Error::new(io::ErrorKind::Other, "oh no!"),

View File

@ -1,14 +1,14 @@
mod json_report_handler {
use miette::{Diagnostic, MietteError, NamedSource, Report, SourceSpan};
use miette::{Diagnostic, MietteError, NamedSource, SourceSpan};
use miette::JSONReportHandler;
use thiserror::Error;
fn fmt_report(diag: Report) -> String {
fn fmt_report(diag: impl Diagnostic) -> String {
let mut out = String::new();
JSONReportHandler::new()
.render_report(&mut out, diag.as_ref())
.render_report(&mut out, &diag)
.unwrap();
out
}
@ -30,7 +30,7 @@ mod json_report_handler {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 6).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{
@ -75,7 +75,7 @@ mod json_report_handler {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{
@ -120,7 +120,7 @@ mod json_report_handler {
src: NamedSource::new("bad_file.rs", src),
highlight: (0, 0).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{
@ -165,7 +165,7 @@ mod json_report_handler {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 0).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{
@ -210,7 +210,7 @@ mod json_report_handler {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{
@ -254,7 +254,7 @@ mod json_report_handler {
src: NamedSource::new("bad_file.rs", src),
highlight: (7, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{
@ -305,7 +305,7 @@ mod json_report_handler {
highlight2: (14, 4).into(),
highlight3: (24, 4).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{
@ -364,7 +364,7 @@ mod json_report_handler {
src: NamedSource::new("bad_file.rs", src),
highlight: (9, 11).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{
@ -419,7 +419,7 @@ mod json_report_handler {
highlight1: (0, len).into(),
highlight2: (10, 9).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{
@ -492,7 +492,7 @@ mod json_report_handler {
highlight1: (0, len).into(),
highlight2: (10, 9).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{
@ -549,7 +549,7 @@ mod json_report_handler {
highlight1: (0, 10).into(),
highlight2: (20, 6).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{
@ -604,7 +604,7 @@ mod json_report_handler {
highlight1: (0, 8).into(),
highlight2: (9, 10).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{
@ -659,7 +659,7 @@ mod json_report_handler {
highlight1: (0, 8).into(),
highlight2: (10, 10).into(),
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{
@ -702,7 +702,7 @@ mod json_report_handler {
struct MyBad;
let err = MyBad;
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{
@ -752,7 +752,7 @@ mod json_report_handler {
},
],
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{
@ -849,7 +849,7 @@ mod json_report_handler {
},
],
};
let out = fmt_report(err.into());
let out = fmt_report(err);
println!("Error: {}", out);
let expected: String = r#"
{