From 79fbd0a07d7277556e2aaa9a97e10a3d73219b8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Garillot?= Date: Sat, 18 Oct 2025 07:44:18 -0400 Subject: [PATCH] feat(no_std): Implement comprehensive no_std support This commit finishes full no_std support to miette. --- Cargo.toml | 9 +++------ build.rs | 19 +++++++++++++++++++ examples/serde_json.rs | 2 ++ miette-derive/src/severity.rs | 4 +--- src/chain.rs | 3 --- src/diagnostic_chain.rs | 3 --- src/diagnostic_impls.rs | 6 ++---- src/error.rs | 24 ++++++++++++------------ src/eyreish/context.rs | 17 ++++++++++++----- src/eyreish/error.rs | 11 +++-------- src/eyreish/into_diagnostic.rs | 13 +++++++------ src/eyreish/kind.rs | 3 +++ src/eyreish/mod.rs | 23 +++++++++++++++++------ src/eyreish/ptr.rs | 2 +- src/eyreish/wrapper.rs | 12 ++++++------ src/handler.rs | 16 +++++++++++++--- src/handlers/debug.rs | 2 +- src/handlers/graphical.rs | 8 +++++++- src/handlers/json.rs | 2 +- src/handlers/narratable.rs | 2 +- src/handlers/theme.rs | 6 ++++-- src/highlighters/blank.rs | 5 +++++ src/highlighters/mod.rs | 5 +++++ src/highlighters/syntect.rs | 5 +++++ src/lib.rs | 18 +++++++++++++++++- src/macro_helpers.rs | 1 - src/miette_diagnostic.rs | 11 +++++------ src/named_source.rs | 2 +- src/panic.rs | 11 +++++++++-- src/protocol.rs | 13 +++++-------- src/source_impls.rs | 10 +++++----- tests/color_format.rs | 6 +++++- tests/common/mod.rs | 2 +- tests/derive.rs | 2 ++ tests/graphical.rs | 2 ++ tests/narrated.rs | 2 ++ tests/test_boxed.rs | 10 +++++----- tests/test_derive_attr.rs | 2 ++ tests/test_derive_collection.rs | 2 ++ tests/test_diagnostic_source_macro.rs | 2 ++ tests/test_json.rs | 2 ++ tests/test_source.rs | 2 +- 42 files changed, 198 insertions(+), 104 deletions(-) create mode 100644 build.rs diff --git a/Cargo.toml b/Cargo.toml index cbabc78..bc3ead4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,22 +32,19 @@ syntect = { version = "5.1.0", optional = true } [dev-dependencies] semver = "1.0.21" - -[build-dependencies] -rustc_version = "0.2" - -# Eyre devdeps futures = { version = "0.3", default-features = false } indenter = "0.3.3" rustversion = "1.0" trybuild = { version = "1.0.89", features = ["diff"] } syn = { version = "2.0.87", features = ["full"] } regex = "1.10" - serde = { version = "1.0.196", features = ["derive"] } serde_json = "1.0.113" strip-ansi-escapes = "0.2.0" +[build-dependencies] +rustc_version = "0.2" + [features] default = ["derive", "std"] std = ["thiserror/std", "fancy-no-syscall"] diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..20e6ce0 --- /dev/null +++ b/build.rs @@ -0,0 +1,19 @@ +use rustc_version::{version_meta, Channel}; + +fn main() { + if let Channel::Nightly = version_meta().unwrap().channel { + println!("cargo:rustc-cfg=nightly") + } + + // Configure track_caller based on Rust version + if let Ok(version) = rustc_version::version() { + if version >= rustc_version::Version::new(1, 46, 0) { + println!("cargo:rustc-cfg=track_caller"); + } + } + + // Add check-cfg for conditional configurations + println!("cargo:rustc-check-cfg=cfg(doc_cfg)"); + println!("cargo:rustc-check-cfg=cfg(track_caller)"); + println!("cargo:rustc-check-cfg=cfg(nightly)"); +} diff --git a/examples/serde_json.rs b/examples/serde_json.rs index d57a76a..be3fbe1 100644 --- a/examples/serde_json.rs +++ b/examples/serde_json.rs @@ -2,6 +2,8 @@ //! so the decoding source will be annotated with the decoding error, //! providing contextual information about the error. +extern crate alloc; + use miette::{IntoDiagnostic, SourceOffset}; use serde_json::{self, json}; diff --git a/miette-derive/src/severity.rs b/miette-derive/src/severity.rs index 40f1bd7..a6f664a 100644 --- a/miette-derive/src/severity.rs +++ b/miette-derive/src/severity.rs @@ -71,9 +71,7 @@ impl Severity { syn::Fields::Unnamed(_) => quote! { (..) }, syn::Fields::Unit => quote! {}, }; - Some( - quote! { Self::#ident #fields => Option::Some(miette::Severity::#severity), }, - ) + Some(quote! { Self::#ident #fields => Option::Some(miette::Severity::#severity), }) }, ) } diff --git a/src/chain.rs b/src/chain.rs index e21d82a..6880678 100644 --- a/src/chain.rs +++ b/src/chain.rs @@ -5,9 +5,6 @@ NOTE: This module is taken wholesale from . */ extern crate alloc; -#[cfg(feature = "std")] -use std::error::Error as StdError; -#[cfg(not(feature = "std"))] use crate::StdError; use alloc::vec::{self, Vec}; diff --git a/src/diagnostic_chain.rs b/src/diagnostic_chain.rs index e9dcccd..7fcfa20 100644 --- a/src/diagnostic_chain.rs +++ b/src/diagnostic_chain.rs @@ -2,10 +2,7 @@ Iterate over error `.diagnostic_source()` chains. */ -extern crate alloc; - use crate::protocol::Diagnostic; -use alloc::string::ToString; /// Iterator of a chain of cause errors. #[derive(Clone, Default)] diff --git a/src/diagnostic_impls.rs b/src/diagnostic_impls.rs index 4bb7345..07391a4 100644 --- a/src/diagnostic_impls.rs +++ b/src/diagnostic_impls.rs @@ -3,12 +3,10 @@ Default trait implementations for [`Diagnostic`]. */ extern crate alloc; -use core::{convert::Infallible, fmt::Display}; use alloc::boxed::Box; +use core::{convert::Infallible, fmt::Display}; -use crate::{Diagnostic, LabeledSpan, Severity, SourceCode, StdError}; - -impl StdError for Infallible {} +use crate::{Diagnostic, LabeledSpan, Severity, SourceCode}; impl Diagnostic for Infallible { fn code<'a>(&'a self) -> Option> { diff --git a/src/error.rs b/src/error.rs index 5fab5b8..9e2faad 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,13 +1,13 @@ extern crate alloc; -#[cfg(feature = "std")] -use std::io; -#[cfg(feature = "std")] -use std::error::Error; #[cfg(not(feature = "std"))] use crate::StdError as Error; -use core::fmt::{self, Display}; use alloc::boxed::Box; +use core::fmt::{self, Display}; +#[cfg(feature = "std")] +use std::error::Error; +#[cfg(feature = "std")] +use std::io; use crate::Diagnostic; @@ -83,17 +83,17 @@ impl Diagnostic for MietteError { }; Some(Box::new(alloc::format!( "https://docs.rs/miette/{}/miette/enum.MietteError.html{}", - crate_version, variant, + crate_version, + variant, ))) } } #[cfg(test)] pub(crate) mod tests { - #[cfg(feature = "std")] - use std::io::ErrorKind; - #[cfg(not(feature = "std"))] - use crate::StdError as Error; + #[cfg(not(feature = "std"))] + use crate::StdError as Error; + use std::string::ToString; use super::*; @@ -126,9 +126,9 @@ pub(crate) mod tests { #[cfg(feature = "std")] #[test] fn io_error() { - let inner_error = io::Error::new(ErrorKind::Other, "halt and catch fire"); + let inner_error = io::Error::other("halt and catch fire"); let outer_error = TestError(inner_error); - let io_error = io::Error::new(ErrorKind::Other, outer_error); + let io_error = io::Error::other(outer_error); let miette_error = MietteError::from(io_error); diff --git a/src/eyreish/context.rs b/src/eyreish/context.rs index 1dbb543..86db506 100644 --- a/src/eyreish/context.rs +++ b/src/eyreish/context.rs @@ -2,13 +2,10 @@ extern crate alloc; use super::error::{ContextError, ErrorImpl}; use super::{Report, WrapErr}; -use core::fmt::{self, Debug, Display, Write}; use core::convert::Infallible; +use core::fmt::{self, Debug, Display, Write}; -#[cfg(feature = "std")] -use std::error::Error as StdError; -#[cfg(not(feature = "std"))] -use crate::StdError as StdError; +use crate::StdError; use alloc::boxed::Box; use crate::{Diagnostic, LabeledSpan}; @@ -27,6 +24,7 @@ mod ext { where E: Diagnostic + Send + Sync + 'static, { + #[cfg_attr(track_caller, track_caller)] fn ext_report(self, msg: D) -> Report where D: Display + Send + Sync + 'static, @@ -36,6 +34,7 @@ mod ext { } impl Diag for Report { + #[cfg_attr(track_caller, track_caller)] fn ext_report(self, msg: D) -> Report where D: Display + Send + Sync + 'static, @@ -46,6 +45,7 @@ mod ext { } impl WrapErr for Option { + #[cfg_attr(track_caller, track_caller)] fn wrap_err(self, msg: D) -> Result where D: Display + Send + Sync + 'static, @@ -56,6 +56,7 @@ impl WrapErr for Option { } } + #[cfg_attr(track_caller, track_caller)] fn wrap_err_with(self, msg: F) -> Result where D: Display + Send + Sync + 'static, @@ -67,6 +68,7 @@ impl WrapErr for Option { } } + #[cfg_attr(track_caller, track_caller)] fn context(self, msg: D) -> Result where D: Display + Send + Sync + 'static, @@ -74,6 +76,7 @@ impl WrapErr for Option { self.wrap_err(msg) } + #[cfg_attr(track_caller, track_caller)] fn with_context(self, msg: F) -> Result where D: Display + Send + Sync + 'static, @@ -87,6 +90,7 @@ impl WrapErr for Result where E: ext::Diag + Send + Sync + 'static, { + #[cfg_attr(track_caller, track_caller)] fn wrap_err(self, msg: D) -> Result where D: Display + Send + Sync + 'static, @@ -97,6 +101,7 @@ where } } + #[cfg_attr(track_caller, track_caller)] fn wrap_err_with(self, msg: F) -> Result where D: Display + Send + Sync + 'static, @@ -108,6 +113,7 @@ where } } + #[cfg_attr(track_caller, track_caller)] fn context(self, msg: D) -> Result where D: Display + Send + Sync + 'static, @@ -115,6 +121,7 @@ where self.wrap_err(msg) } + #[cfg_attr(track_caller, track_caller)] fn with_context(self, msg: F) -> Result where D: Display + Send + Sync + 'static, diff --git a/src/eyreish/error.rs b/src/eyreish/error.rs index 238e46c..0add102 100644 --- a/src/eyreish/error.rs +++ b/src/eyreish/error.rs @@ -1,14 +1,11 @@ extern crate alloc; +use crate::StdError; +use alloc::boxed::Box; use core::any::TypeId; use core::fmt::{self, Debug, Display}; use core::mem::ManuallyDrop; use core::ptr::{self, NonNull}; -#[cfg(feature = "std")] -use std::error::Error as StdError; -#[cfg(not(feature = "std"))] -use crate::StdError as StdError; -use alloc::boxed::Box; use super::ptr::{Mut, Own, Ref}; use super::Report; @@ -93,7 +90,6 @@ impl Report { Report::from_boxed(error) } - #[cfg_attr(track_caller, track_caller)] #[cold] pub(crate) fn from_std(error: E) -> Self where @@ -160,7 +156,7 @@ impl Report { }; // Safety: passing vtable that operates on the right type. - let handler = Some(super::capture_handler(&error)); + let handler = Some(super::capture_handler_with_location(&error)); unsafe { Report::construct(error, vtable, handler) } } @@ -445,7 +441,6 @@ impl From for Report where E: Diagnostic + Send + Sync + 'static, { - #[cfg_attr(track_caller, track_caller)] #[cold] fn from(error: E) -> Self { Report::from_std(error) diff --git a/src/eyreish/into_diagnostic.rs b/src/eyreish/into_diagnostic.rs index b739b24..2ed2aae 100644 --- a/src/eyreish/into_diagnostic.rs +++ b/src/eyreish/into_diagnostic.rs @@ -1,10 +1,6 @@ extern crate alloc; -#[cfg(feature = "std")] -use std::error::Error; -#[cfg(not(feature = "std"))] use crate::StdError as Error; -use core::fmt::Display; use alloc::boxed::Box; use crate::{Diagnostic, Report}; @@ -42,11 +38,13 @@ inaccessible. If you have a type implementing [`Diagnostic`] consider simply ret pub trait IntoDiagnostic { /// Converts [`Result`] types that return regular [`std::error::Error`]s /// into a [`Result`] that returns a [`Diagnostic`]. + #[cfg_attr(track_caller, track_caller)] fn into_diagnostic(self) -> Result; } #[cfg(feature = "std")] impl IntoDiagnostic for Result { + #[cfg_attr(track_caller, track_caller)] fn into_diagnostic(self) -> Result { self.map_err(|e| DiagnosticError(Box::new(e)).into()) } @@ -54,6 +52,7 @@ impl IntoDiagnostic for R #[cfg(not(feature = "std"))] impl IntoDiagnostic for Result { + #[cfg_attr(track_caller, track_caller)] fn into_diagnostic(self) -> Result { self.map_err(|e| DiagnosticError(Box::new(e)).into()) } @@ -62,7 +61,9 @@ impl IntoDiagnostic for Result #[cfg(test)] mod tests { #[cfg(feature = "std")] - use std::io::{self, ErrorKind}; + use std::io::{self}; + #[cfg(feature = "std")] + use std::string::ToString; use super::*; @@ -72,7 +73,7 @@ mod tests { #[cfg(feature = "std")] #[test] fn diagnostic_error() { - let inner_error = io::Error::new(ErrorKind::Other, "halt and catch fire"); + let inner_error = io::Error::other("halt and catch fire"); let outer_error: Result<(), _> = Err(TestError(inner_error)); let diagnostic_error = outer_error.into_diagnostic().unwrap_err(); diff --git a/src/eyreish/kind.rs b/src/eyreish/kind.rs index e6dd978..2c1f49a 100644 --- a/src/eyreish/kind.rs +++ b/src/eyreish/kind.rs @@ -56,6 +56,9 @@ use crate::Diagnostic; #[cfg(not(feature = "std"))] use alloc::boxed::Box; +#[cfg(feature = "std")] +use std::boxed::Box; + pub struct Adhoc; pub trait AdhocKind: Sized { diff --git a/src/eyreish/mod.rs b/src/eyreish/mod.rs index 8a4598c..bf0076d 100644 --- a/src/eyreish/mod.rs +++ b/src/eyreish/mod.rs @@ -6,14 +6,14 @@ )] extern crate alloc; -use core::fmt::Display; use alloc::boxed::Box; +use core::fmt::Display; +#[cfg(not(feature = "std"))] +use crate::StdError; +use spin::Once; #[cfg(feature = "std")] use std::error::Error as StdError; -#[cfg(not(feature = "std"))] -use crate::StdError as StdError; -use spin::Once; #[allow(unreachable_pub)] pub use into_diagnostic::*; @@ -95,9 +95,20 @@ pub fn set_hook(hook: ErrorHook) -> Result<(), InstallError> { Ok(()) } +pub(crate) fn capture_handler(error: &(dyn Diagnostic + 'static)) -> Box { + static DEFAULT: Once = Once::new(); + let hook = HOOK.get().unwrap_or_else(|| { + DEFAULT.call_once(|| default_hook()); + DEFAULT.get().unwrap() + }); + + hook(error) +} + #[cfg_attr(track_caller, track_caller)] -#[cfg_attr(not(track_caller), allow(unused_mut))] -fn capture_handler(error: &(dyn Diagnostic + 'static)) -> Box { +pub(crate) fn capture_handler_with_location( + error: &(dyn Diagnostic + 'static), +) -> Box { static DEFAULT: Once = Once::new(); let hook = HOOK.get().unwrap_or_else(|| { DEFAULT.call_once(|| default_hook()); diff --git a/src/eyreish/ptr.rs b/src/eyreish/ptr.rs index 947b5bd..9852b69 100644 --- a/src/eyreish/ptr.rs +++ b/src/eyreish/ptr.rs @@ -1,8 +1,8 @@ extern crate alloc; +use alloc::boxed::Box; use core::marker::PhantomData; use core::ptr::NonNull; -use alloc::boxed::Box; #[repr(transparent)] /// A raw pointer that owns its pointee diff --git a/src/eyreish/wrapper.rs b/src/eyreish/wrapper.rs index 6c03cc0..73c6a2e 100644 --- a/src/eyreish/wrapper.rs +++ b/src/eyreish/wrapper.rs @@ -2,13 +2,8 @@ extern crate alloc; use core::fmt::{self, Debug, Display}; -#[cfg(feature = "std")] -use std::error::Error as StdError; -#[cfg(not(feature = "std"))] -use crate::StdError as StdError; +use crate::StdError; use alloc::boxed::Box; -use alloc::string::String; -use alloc::vec::Vec; use crate::{Diagnostic, LabeledSpan, Report, SourceCode}; @@ -216,6 +211,11 @@ impl StdError for WithSourceCode { #[cfg(test)] mod tests { + + use std::{ + boxed::Box, + string::{String, ToString}, + }; use thiserror::Error; use crate::{Diagnostic, LabeledSpan, Report, SourceCode, SourceSpan}; diff --git a/src/handler.rs b/src/handler.rs index 37e4826..1efec17 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -1,3 +1,7 @@ +extern crate alloc; +use alloc::boxed::Box; +use alloc::string::String; + use crate::highlighters::Highlighter; use crate::highlighters::MietteHighlighter; use crate::protocol::Diagnostic; @@ -491,7 +495,10 @@ mod syscall { #[inline] pub(super) fn supports_color() -> bool { cfg_if! { - if #[cfg(feature = "fancy-no-syscall")] { + if #[cfg(feature = "fancy-no-backtrace")] { + supports_color::on(supports_color::Stream::Stderr).is_some() + } else if #[cfg(feature = "fancy-no-syscall")] { + // In no-std environment without color support, default to no color support false } else { supports_color::on(supports_color::Stream::Stderr).is_some() @@ -502,8 +509,11 @@ mod syscall { #[inline] pub(super) fn supports_color_has_16m() -> Option { cfg_if! { - if #[cfg(feature = "fancy-no-syscall")] { - None + if #[cfg(feature = "fancy-no-backtrace")] { + supports_color::on(supports_color::Stream::Stderr).map(|color| color.has_16m) + } else if #[cfg(feature = "fancy-no-syscall")] { + // In no-std environment without color support, default to no RGB color support + Some(false) } else { supports_color::on(supports_color::Stream::Stderr).map(|color| color.has_16m) } diff --git a/src/handlers/debug.rs b/src/handlers/debug.rs index 1c77062..8e9ff3c 100644 --- a/src/handlers/debug.rs +++ b/src/handlers/debug.rs @@ -1,7 +1,7 @@ extern crate alloc; -use core::fmt; use alloc::vec::Vec; +use core::fmt; use crate::{protocol::Diagnostic, ReportHandler}; diff --git a/src/handlers/graphical.rs b/src/handlers/graphical.rs index 37b6bf8..3b66aa4 100644 --- a/src/handlers/graphical.rs +++ b/src/handlers/graphical.rs @@ -1,4 +1,10 @@ -use std::fmt::{self, Write}; +extern crate alloc; + +use alloc::boxed::Box; +use alloc::format; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::fmt::{self, Write}; use owo_colors::{OwoColorize, Style, StyledList}; use unicode_width::{UnicodeWidthChar, UnicodeWidthStr}; diff --git a/src/handlers/json.rs b/src/handlers/json.rs index 966e348..a5d5708 100644 --- a/src/handlers/json.rs +++ b/src/handlers/json.rs @@ -1,7 +1,7 @@ extern crate alloc; -use core::fmt::{self, Write}; use alloc::string::ToString; +use core::fmt::{self, Write}; use crate::{ diagnostic_chain::DiagnosticChain, protocol::Diagnostic, ReportHandler, Severity, SourceCode, diff --git a/src/handlers/narratable.rs b/src/handlers/narratable.rs index 86f23b3..418b9ef 100644 --- a/src/handlers/narratable.rs +++ b/src/handlers/narratable.rs @@ -7,9 +7,9 @@ use unicode_width::{UnicodeWidthChar, UnicodeWidthStr}; use crate::diagnostic_chain::DiagnosticChain; use crate::protocol::{Diagnostic, Severity}; use crate::{LabeledSpan, MietteError, ReportHandler, SourceCode, SourceSpan, SpanContents}; +use alloc::boxed::Box; use alloc::string::String; use alloc::vec::Vec; -use alloc::boxed::Box; /** [`ReportHandler`] that renders plain text and avoids extraneous graphics. diff --git a/src/handlers/theme.rs b/src/handlers/theme.rs index 360b2da..64980d8 100644 --- a/src/handlers/theme.rs +++ b/src/handlers/theme.rs @@ -1,5 +1,7 @@ -use std::io::IsTerminal; - +extern crate alloc; +use alloc::string::String; +use alloc::vec; +use alloc::vec::Vec; use owo_colors::Style; /** diff --git a/src/highlighters/blank.rs b/src/highlighters/blank.rs index 50a9c65..f32f9df 100644 --- a/src/highlighters/blank.rs +++ b/src/highlighters/blank.rs @@ -1,3 +1,8 @@ +extern crate alloc; + +use alloc::boxed::Box; +use alloc::vec; +use alloc::vec::Vec; use owo_colors::Style; use crate::SpanContents; diff --git a/src/highlighters/mod.rs b/src/highlighters/mod.rs index 0af1aa2..5f95836 100644 --- a/src/highlighters/mod.rs +++ b/src/highlighters/mod.rs @@ -13,6 +13,11 @@ use std::{ops::Deref, sync::Arc}; +extern crate alloc; +use alloc::boxed::Box; +use alloc::sync::Arc; +use alloc::vec::Vec; + use crate::SpanContents; use owo_colors::Styled; diff --git a/src/highlighters/syntect.rs b/src/highlighters/syntect.rs index 75759fc..ca848f6 100644 --- a/src/highlighters/syntect.rs +++ b/src/highlighters/syntect.rs @@ -1,5 +1,10 @@ use std::path::Path; +extern crate alloc; +use alloc::boxed::Box; +use alloc::vec; +use alloc::vec::Vec; + // all syntect imports are explicitly qualified, but their paths are shortened for convenience #[allow(clippy::module_inception)] mod syntect { diff --git a/src/lib.rs b/src/lib.rs index 7c2fd56..24cefff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,8 @@ #![no_std] - #![deny(missing_docs, missing_debug_implementations, nonstandard_style)] #![warn(unreachable_pub, rust_2018_idioms)] #![allow(unexpected_cfgs)] + //! You run miette? You run her code like the software? Oh. Oh! Error code for //! coder! Error code for One Thousand Lines! //! @@ -98,6 +98,7 @@ //! ## Example //! //! ```rust +//! # extern crate alloc; //! /* //! You can derive a `Diagnostic` from any `std::error::Error` type. //! @@ -195,6 +196,7 @@ //! the trait directly, just like with `std::error::Error`. //! //! ```rust +//! # extern crate alloc; //! // lib/error.rs //! use miette::{Diagnostic, SourceSpan}; //! use thiserror::Error; @@ -362,6 +364,7 @@ //! attribute: //! //! ```rust +//! # extern crate alloc; //! use miette::Diagnostic; //! use thiserror::Error; //! @@ -382,6 +385,7 @@ //! (very high quality and detailed!) documentation on this diagnostic: //! //! ```rust +//! # extern crate alloc; //! use miette::Diagnostic; //! use thiserror::Error; //! @@ -412,6 +416,7 @@ //! `derive(Diagnostic)` macro: //! //! ```rust +//! # extern crate alloc; //! use miette::{Diagnostic, SourceSpan}; //! use thiserror::Error; //! @@ -450,6 +455,7 @@ //! enum variants: //! //! ```rust +//! # extern crate alloc; //! use miette::Diagnostic; //! use thiserror::Error; //! @@ -463,6 +469,7 @@ //! your diagnostic: //! //! ```rust +//! # extern crate alloc; //! use miette::Diagnostic; //! use thiserror::Error; //! @@ -501,6 +508,7 @@ //! `Diagnostic` type: //! //! ```rust +//! # extern crate alloc; //! use miette::Diagnostic; //! use thiserror::Error; //! @@ -519,6 +527,7 @@ //! method for that: //! //! ```rust,no_run +//! # extern crate alloc; //! use miette::{Diagnostic, SourceSpan}; //! use thiserror::Error; //! @@ -551,6 +560,7 @@ //! emitted at the same time: //! //! ```rust,no_run +//! # extern crate alloc; //! use miette::{Diagnostic, Report, SourceSpan}; //! use thiserror::Error; //! @@ -612,6 +622,7 @@ //! will likely want to use _both_: //! //! ```rust +//! # extern crate alloc; //! use miette::Diagnostic; //! use thiserror::Error; //! @@ -817,6 +828,11 @@ //! and some from [`thiserror`](https://github.com/dtolnay/thiserror), also //! under the Apache License. Some code is taken from //! [`ariadne`](https://github.com/zesterer/ariadne), which is MIT licensed. + +// For doctests that use Diagnostic derive macro +#[cfg(test)] +extern crate alloc; + #[cfg(feature = "std")] extern crate std; diff --git a/src/macro_helpers.rs b/src/macro_helpers.rs index 47a6e5f..157f2b3 100644 --- a/src/macro_helpers.rs +++ b/src/macro_helpers.rs @@ -51,7 +51,6 @@ impl ToLabeledSpan for ToLabelSpanWrapper { span } } -#[cfg(not(feature = "std"))] impl ToLabeledSpan for ToLabelSpanWrapper where T: Into, diff --git a/src/miette_diagnostic.rs b/src/miette_diagnostic.rs index 07ed724..dc0fa28 100644 --- a/src/miette_diagnostic.rs +++ b/src/miette_diagnostic.rs @@ -1,14 +1,13 @@ extern crate alloc; +#[cfg(not(feature = "std"))] +use crate::StdError as Error; +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; use core::fmt::{Debug, Display}; #[cfg(feature = "std")] use std::error::Error; -#[cfg(not(feature = "std"))] -use crate::StdError as Error; -use alloc::string::String; -use alloc::vec::{self, Vec}; -use alloc::format; -use alloc::boxed::Box; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; diff --git a/src/named_source.rs b/src/named_source.rs index 415f088..0f2804e 100644 --- a/src/named_source.rs +++ b/src/named_source.rs @@ -12,9 +12,9 @@ pub struct NamedSource { extern crate alloc; +use alloc::boxed::Box; use alloc::string::String; use alloc::string::ToString; -use alloc::boxed::Box; impl core::fmt::Debug for NamedSource { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { diff --git a/src/panic.rs b/src/panic.rs index b1dfd4a..ef6f427 100644 --- a/src/panic.rs +++ b/src/panic.rs @@ -1,4 +1,11 @@ -use std::{error::Error, fmt::Display}; +use std::boxed::Box; +use std::{ + eprintln, + error::Error, + fmt::Display, + format, + string::{String, ToString}, +}; use backtrace::Backtrace; @@ -104,7 +111,7 @@ impl Panic { #[cfg(test)] mod tests { - use std::error::Error; + use std::{borrow::ToOwned, error::Error}; use super::*; diff --git a/src/protocol.rs b/src/protocol.rs index 10bb283..636aefa 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -5,13 +5,13 @@ full reporting and such features. */ extern crate alloc; -use core::fmt::{self, Display}; -#[cfg(feature = "std")] -use std::fs; -use core::panic::Location; -use core::ops; use alloc::boxed::Box; use alloc::string::String; +use core::fmt::{self, Display}; +use core::ops; +use core::panic::Location; +#[cfg(feature = "std")] +use std::fs; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -152,9 +152,6 @@ impl From for Box { fn from(s: String) -> Self { struct StringError(String); - #[cfg(feature = "std")] - impl std::error::Error for StringError {} - #[cfg(not(feature = "std"))] impl crate::StdError for StringError {} impl Diagnostic for StringError {} diff --git a/src/source_impls.rs b/src/source_impls.rs index 4fa60c3..efa415c 100644 --- a/src/source_impls.rs +++ b/src/source_impls.rs @@ -3,14 +3,14 @@ Default trait implementations for [`SourceCode`]. */ extern crate alloc; -use core::fmt::Debug; use alloc::borrow::Cow; use alloc::borrow::ToOwned; -use alloc::collections::VecDeque; -use alloc::sync::Arc; -use alloc::string::String; -use alloc::vec::Vec; use alloc::boxed::Box; +use alloc::collections::VecDeque; +use alloc::string::String; +use alloc::sync::Arc; +use alloc::vec::Vec; +use core::fmt::Debug; use crate::{MietteError, MietteSpanContents, SourceCode, SourceSpan, SpanContents}; diff --git a/tests/color_format.rs b/tests/color_format.rs index 4e95856..f0f1ad5 100644 --- a/tests/color_format.rs +++ b/tests/color_format.rs @@ -1,5 +1,7 @@ #![cfg(feature = "fancy-no-backtrace")] +extern crate alloc; + use miette::{Diagnostic, MietteHandler, MietteHandlerOpts, ReportHandler, RgbColors}; use regex::Regex; use std::ffi::OsString; @@ -83,7 +85,9 @@ fn check_colors MietteHandlerOpts>( // // Since environment variables are shared for the entire process, we need // to ensure that only one test that modifies these env vars runs at a time. - let lock = COLOR_ENV_VARS.lock().unwrap(); + let lock = COLOR_ENV_VARS + .lock() + .unwrap_or_else(|poisoned| poisoned.into_inner()); let guards = ( EnvVarGuard::new("NO_COLOR"), diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 223810c..8c48253 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -10,5 +10,5 @@ pub fn bail_fmt() -> Result<()> { } pub fn bail_error() -> Result<()> { - bail!(io::Error::new(io::ErrorKind::Other, "oh no!")); + bail!(io::Error::other("oh no!")); } diff --git a/tests/derive.rs b/tests/derive.rs index aa631dc..3cc0e8b 100644 --- a/tests/derive.rs +++ b/tests/derive.rs @@ -1,3 +1,5 @@ +extern crate alloc; + use miette::{Diagnostic, Report, Severity, SourceSpan}; use thiserror::Error; diff --git a/tests/graphical.rs b/tests/graphical.rs index 93c9bce..e2548e1 100644 --- a/tests/graphical.rs +++ b/tests/graphical.rs @@ -1,5 +1,7 @@ #![cfg(feature = "fancy-no-backtrace")] +extern crate alloc; + use miette::{ Diagnostic, GraphicalReportHandler, GraphicalTheme, MietteError, NamedSource, NarratableReportHandler, Report, SourceSpan, diff --git a/tests/narrated.rs b/tests/narrated.rs index 52acd13..ced0b23 100644 --- a/tests/narrated.rs +++ b/tests/narrated.rs @@ -1,5 +1,7 @@ #![cfg(feature = "fancy-no-backtrace")] +extern crate alloc; + use miette::{Diagnostic, MietteError, NamedSource, NarratableReportHandler, Report, SourceSpan}; use miette::{GraphicalReportHandler, GraphicalTheme}; diff --git a/tests/test_boxed.rs b/tests/test_boxed.rs index 9f9f4e2..db8d214 100644 --- a/tests/test_boxed.rs +++ b/tests/test_boxed.rs @@ -42,13 +42,13 @@ fn test_boxed_str_stderr() { #[test] fn test_boxed_thiserror() { let error = MyError { - source: io::Error::new(io::ErrorKind::Other, "oh no!"), + source: io::Error::other("oh no!"), }; let report: Report = miette!(error); assert_eq!("oh no!", report.source().unwrap().to_string()); let error = MyError { - source: io::Error::new(io::ErrorKind::Other, "oh no!!!!"), + source: io::Error::other("oh no!!!!"), }; let error: Box = Box::new(error); let report = Report::new_boxed(error); @@ -203,7 +203,7 @@ fn test_boxed_custom_diagnostic() { let related = CustomDiagnostic::new(); let main_diagnostic = CustomDiagnostic::new() - .with_source(io::Error::new(io::ErrorKind::Other, "oh no!")) + .with_source(io::Error::other("oh no!")) .with_related(related); let report = Report::new_boxed(Box::new(main_diagnostic)); @@ -211,7 +211,7 @@ fn test_boxed_custom_diagnostic() { let related = CustomDiagnostic::new(); let main_diagnostic = CustomDiagnostic::new() - .with_source(io::Error::new(io::ErrorKind::Other, "oh no!")) + .with_source(io::Error::other("oh no!")) .with_related(related); let main_diagnostic = Box::new(main_diagnostic) as Box; let report = miette!(main_diagnostic); @@ -228,7 +228,7 @@ fn test_boxed_custom_diagnostic() { #[test] fn test_boxed_sources() { let error = MyError { - source: io::Error::new(io::ErrorKind::Other, "oh no!"), + source: io::Error::other("oh no!"), }; let error = Box::::from(error); let error: Report = miette!(error).wrap_err("it failed"); diff --git a/tests/test_derive_attr.rs b/tests/test_derive_attr.rs index f1b0f3d..8c13670 100644 --- a/tests/test_derive_attr.rs +++ b/tests/test_derive_attr.rs @@ -1,4 +1,6 @@ // Testing of the `diagnostic` attr used by derive(Diagnostic) +extern crate alloc; + use miette::{Diagnostic, LabeledSpan, NamedSource, SourceSpan}; use thiserror::Error; diff --git a/tests/test_derive_collection.rs b/tests/test_derive_collection.rs index 952b505..baf037c 100644 --- a/tests/test_derive_collection.rs +++ b/tests/test_derive_collection.rs @@ -1,3 +1,5 @@ +extern crate alloc; + use std::{ collections::{LinkedList, VecDeque}, ops::Range, diff --git a/tests/test_diagnostic_source_macro.rs b/tests/test_diagnostic_source_macro.rs index 1349303..33aebb6 100644 --- a/tests/test_diagnostic_source_macro.rs +++ b/tests/test_diagnostic_source_macro.rs @@ -1,3 +1,5 @@ +extern crate alloc; + use miette::Diagnostic; #[derive(Debug, miette::Diagnostic, thiserror::Error)] diff --git a/tests/test_json.rs b/tests/test_json.rs index 664318a..b055fc7 100644 --- a/tests/test_json.rs +++ b/tests/test_json.rs @@ -1,4 +1,6 @@ mod json_report_handler { + extern crate alloc; + use miette::{Diagnostic, MietteError, NamedSource, Report, SourceSpan}; use miette::JSONReportHandler; diff --git a/tests/test_source.rs b/tests/test_source.rs index 9511bdb..303c2f9 100644 --- a/tests/test_source.rs +++ b/tests/test_source.rs @@ -50,7 +50,7 @@ fn test_fmt_source() { #[test] #[ignore = "Again with the io::Error source issue?"] fn test_io_source() { - let io = io::Error::new(io::ErrorKind::Other, "oh no!"); + let io = io::Error::other("oh no!"); let error: Report = miette!(TestError::Io(io)); assert_eq!("oh no!", error.source().unwrap().to_string()); }