make an effort at no_std support

This commit is contained in:
Jane Lusby 2020-02-28 08:54:39 -08:00
parent 6c1a9af5b8
commit 11757c1da5
13 changed files with 91 additions and 75 deletions

View File

@ -10,7 +10,7 @@ jobs:
matrix:
rust:
- stable
- 1.31.0
- 1.34.0
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
@ -29,7 +29,7 @@ jobs:
rust:
- stable
- nightly
- 1.31.0
- 1.34.0
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
@ -39,10 +39,10 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: test
- uses: actions-rs/cargo@v1
with:
command: test
args: --no-default-features
# - uses: actions-rs/cargo@v1
# with:
# command: test
# args: --no-default-features
fmt:
name: Rustfmt
@ -51,7 +51,7 @@ jobs:
matrix:
rust:
- stable
- 1.31.0
- 1.34.0
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
@ -71,7 +71,7 @@ jobs:
matrix:
rust:
- stable
- 1.31.0
- 1.34.0
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1

View File

@ -4,20 +4,6 @@ pub(crate) use std::backtrace::Backtrace;
#[cfg(not(backtrace))]
pub(crate) enum Backtrace {}
// #[cfg(backtrace)]
// macro_rules! backtrace {
// () => {
// Some(Backtrace::capture())
// };
// }
#[cfg(not(backtrace))]
macro_rules! backtrace {
() => {
None
};
}
#[cfg(backtrace)]
macro_rules! backtrace_if_absent {
($err:expr) => {
@ -28,7 +14,7 @@ macro_rules! backtrace_if_absent {
};
}
#[cfg(all(feature = "std", not(backtrace)))]
#[cfg(not(backtrace))]
macro_rules! backtrace_if_absent {
($err:expr) => {
None

View File

@ -1,5 +1,5 @@
use crate::error::ContextError;
use crate::{WrapErr, ErrReport, StdError, EyreContext};
use crate::{ErrReport, EyreContext, StdError, WrapErr};
use core::fmt::{self, Debug, Display, Write};
#[cfg(backtrace)]

View File

@ -1,13 +1,15 @@
use crate::alloc::Box;
use std::any::Any;
use crate::backtrace::Backtrace;
use crate::chain::Chain;
use crate::EyreContext;
use crate::{ErrReport, StdError};
use core::any::Any;
use core::any::TypeId;
use core::fmt::{self, Debug, Display};
use core::mem::{self, ManuallyDrop};
use core::ptr::{self, NonNull};
use crate::EyreContext;
#[cfg(backtrace)]
use crate::backtrace::Backtrace;
#[cfg(feature = "std")]
use core::ops::{Deref, DerefMut};
@ -138,9 +140,7 @@ where
}
#[cfg(feature = "std")]
pub(crate) fn from_boxed(
error: Box<dyn StdError + Send + Sync>,
) -> Self {
pub(crate) fn from_boxed(error: Box<dyn StdError + Send + Sync>) -> Self {
use crate::wrapper::BoxedError;
let error = BoxedError(error);
let vtable = &ErrorVTable {
@ -163,10 +163,7 @@ where
//
// Unsafe because the given vtable must have sensible behavior on the error
// value of type E.
unsafe fn construct<E>(
error: E,
vtable: &'static ErrorVTable<C>,
) -> Self
unsafe fn construct<E>(error: E, vtable: &'static ErrorVTable<C>) -> Self
where
E: StdError + Send + Sync + 'static,
{
@ -245,10 +242,7 @@ where
where
D: Display + Send + Sync + 'static,
{
let error: ContextError<D, ErrReport<C>> = ContextError {
msg,
error: self,
};
let error: ContextError<D, ErrReport<C>> = ContextError { msg, error: self };
let vtable = &ErrorVTable {
object_drop: object_drop::<ContextError<D, ErrReport<C>>, C>,
@ -431,6 +425,10 @@ where
Some(&mut *addr.cast::<E>().as_ptr())
}
}
pub fn context<T: Any>(&self) -> Option<&T> {
self.inner.context()
}
}
#[cfg(feature = "std")]
@ -490,7 +488,7 @@ where
struct ErrorVTable<C>
where
C: EyreContext,
C: EyreContext,
{
object_drop: unsafe fn(Box<ErrorImpl<(), C>>),
object_ref: unsafe fn(&ErrorImpl<(), C>) -> &(dyn StdError + Send + Sync + 'static),
@ -627,12 +625,14 @@ where
D: 'static,
{
if TypeId::of::<D>() == target {
let unerased = e as *const ErrorImpl<(), C> as *const ErrorImpl<ContextError<D, ErrReport<C>>, C>;
let unerased =
e as *const ErrorImpl<(), C> as *const ErrorImpl<ContextError<D, ErrReport<C>>, C>;
let addr = &(*unerased)._object.msg as *const D as *mut ();
Some(NonNull::new_unchecked(addr))
} else {
// Recurse down the context chain per the inner error's vtable.
let unerased = e as *const ErrorImpl<(), C> as *const ErrorImpl<ContextError<D, ErrReport<C>>, C>;
let unerased =
e as *const ErrorImpl<(), C> as *const ErrorImpl<ContextError<D, ErrReport<C>>, C>;
let source = &(*unerased)._object.error;
(source.inner.vtable.object_downcast)(&source.inner, target)
}
@ -717,9 +717,10 @@ where
unsafe { &mut *(self.vtable.object_mut)(self) }
}
pub fn context<T: Any>(&self) -> Option<&T> {
self.context.context_raw(TypeId::of::<T>())?.downcast_ref::<T>()
self.context
.context_raw(TypeId::of::<T>())?
.downcast_ref::<T>()
}
#[cfg(backtrace)]

View File

@ -1,6 +1,6 @@
use crate::error::ErrorImpl;
use core::fmt::{self, Write};
use crate::EyreContext;
use core::fmt::{self, Write};
impl<C> ErrorImpl<(), C>
where
@ -52,6 +52,7 @@ where
#[cfg(test)]
mod tests {
use super::*;
use crate::alloc::String;
#[test]
fn one_digit() {

View File

@ -44,7 +44,7 @@
// let error = $msg;
// (&error).eyre_kind().new(error)
use crate::{EyreContext, ErrReport};
use crate::{ErrReport, EyreContext};
use core::fmt::{Debug, Display};
#[cfg(feature = "std")]

View File

@ -195,6 +195,12 @@ mod alloc {
#[cfg(feature = "std")]
pub use std::boxed::Box;
#[cfg(not(feature = "std"))]
pub use alloc::string::String;
#[cfg(feature = "std")]
pub use std::string::String;
}
#[macro_use]
@ -208,12 +214,11 @@ mod macros;
mod wrapper;
use crate::alloc::Box;
use crate::backtrace::Backtrace;
use crate::error::ErrorImpl;
use core::any::{Any, TypeId};
use core::fmt::Display;
use core::mem::ManuallyDrop;
use std::backtrace::Backtrace;
use std::any::{Any, TypeId};
#[cfg(not(feature = "std"))]
use core::fmt::Debug;
@ -222,7 +227,7 @@ use core::fmt::Debug;
use std::error::Error as StdError;
#[cfg(not(feature = "std"))]
trait StdError: Debug + Display {
pub trait StdError: Debug + Display {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
None
}
@ -330,26 +335,32 @@ where
}
pub trait EyreContext: Sized + Send + Sync + 'static {
fn default(err: &(dyn std::error::Error + 'static)) -> Self;
fn default(err: &(dyn StdError + 'static)) -> Self;
fn context_raw(&self, typeid: TypeId) -> Option<&dyn Any>;
fn display(&self, error: &(dyn std::error::Error + 'static), f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result;
fn display(
&self,
error: &(dyn StdError + 'static),
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result;
fn debug(&self, error: &(dyn std::error::Error + 'static), f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result;
fn debug(
&self,
error: &(dyn StdError + 'static),
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result;
}
pub struct DefaultContext {
pub backtrace: Option<Backtrace>,
backtrace: Option<Backtrace>,
}
impl EyreContext for DefaultContext {
fn default(error: &(dyn std::error::Error + 'static)) -> Self {
fn default(_error: &(dyn StdError + 'static)) -> Self {
let backtrace = backtrace_if_absent!(error);
Self {
backtrace
}
Self { backtrace }
}
fn context_raw(&self, typid: TypeId) -> Option<&dyn Any> {
@ -359,11 +370,15 @@ impl EyreContext for DefaultContext {
}
}
fn display(&self, error: &(dyn std::error::Error + 'static), f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
fn display(
&self,
error: &(dyn StdError + 'static),
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
write!(f, "{}", error)?;
if f.alternate() {
for cause in Chain::new(error).skip(1) {
for cause in crate::chain::Chain::new(error).skip(1) {
write!(f, ": {}", cause)?;
}
}
@ -371,7 +386,11 @@ impl EyreContext for DefaultContext {
Ok(())
}
fn debug(&self, error: &(dyn std::error::Error + 'static), f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
fn debug(
&self,
error: &(dyn StdError + 'static),
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
use core::fmt::Write as _;
if f.alternate() {
@ -383,7 +402,7 @@ impl EyreContext for DefaultContext {
if let Some(cause) = error.source() {
write!(f, "\n\nCaused by:")?;
let multiple = cause.source().is_some();
for (n, error) in Chain::new(cause).enumerate() {
for (n, error) in crate::chain::Chain::new(cause).enumerate() {
writeln!(f)?;
let mut indented = fmt::Indented {
inner: f,
@ -398,7 +417,11 @@ impl EyreContext for DefaultContext {
{
use std::backtrace::BacktraceStatus;
let backtrace = self.backtrace.as_ref().or_else(|| error.backtrace()).expect("backtrace capture failed");
let backtrace = self
.backtrace
.as_ref()
.or_else(|| error.backtrace())
.expect("backtrace capture failed");
if let BacktraceStatus::Captured = backtrace.status() {
let mut backtrace = backtrace.to_string();
if backtrace.starts_with("stack backtrace:") {
@ -650,11 +673,11 @@ where
// Not public API. Referenced by macro-generated code.
#[doc(hidden)]
pub mod private {
use crate::{EyreContext, ErrReport};
use crate::{ErrReport, EyreContext};
use core::fmt::{Debug, Display};
// #[cfg(backtrace)]
// use std::backtrace::Backtrace;
// #[cfg(backtrace)]
// use std::backtrace::Backtrace;
pub use core::result::Result::Err;

View File

@ -1,4 +1,4 @@
use eyre::{ErrReport, eyre};
use eyre::{eyre, ErrReport};
use std::error::Error as StdError;
use std::io;
use thiserror::Error;

View File

@ -1,7 +1,7 @@
mod drop;
use crate::drop::{DetectDrop, Flag};
use eyre::{WrapErr, ErrReport, Result};
use eyre::{ErrReport, Result, WrapErr};
use std::fmt::{self, Display};
use thiserror::Error;

View File

@ -1,4 +1,4 @@
use eyre::{bail, WrapErr, Result};
use eyre::{bail, Result, WrapErr};
use std::io;
fn f() -> Result<()> {

View File

@ -1,7 +1,7 @@
mod common;
use self::common::*;
use eyre::{Result, ensure};
use eyre::{ensure, Result};
#[test]
fn test_messages() {
@ -19,13 +19,13 @@ fn test_ensure() {
assert!(f().is_ok());
let v = 1;
let f = || -> Result<()>{
let f = || -> Result<()> {
ensure!(v + v == 2, "This is correct, v: {}", v);
Ok(())
};
assert!(f().is_ok());
let f = || -> Result<()>{
let f = || -> Result<()> {
ensure!(v + v == 1, "This is not correct, v: {}", v);
Ok(())
};

View File

@ -1,8 +1,8 @@
mod drop;
use self::drop::{DetectDrop, Flag};
use eyre::ErrReport;
use eyre::DefaultContext;
use eyre::ErrReport;
use std::marker::Unpin;
use std::mem;
@ -13,7 +13,10 @@ fn test_error_size() {
#[test]
fn test_null_pointer_optimization() {
assert_eq!(mem::size_of::<Result<(), ErrReport>>(), mem::size_of::<usize>());
assert_eq!(
mem::size_of::<Result<(), ErrReport>>(),
mem::size_of::<usize>()
);
}
#[test]
@ -25,6 +28,8 @@ fn test_autotraits() {
#[test]
fn test_drop() {
let has_dropped = Flag::new();
drop(ErrReport::<DefaultContext>::new(DetectDrop::new(&has_dropped)));
drop(ErrReport::<DefaultContext>::new(DetectDrop::new(
&has_dropped,
)));
assert!(has_dropped.get());
}

View File

@ -1,4 +1,4 @@
use eyre::{ErrReport, eyre};
use eyre::{eyre, ErrReport};
use std::error::Error as StdError;
use std::fmt::{self, Display};
use std::io;