Skip to content

Commit

Permalink
Got Rust to Segfault!
Browse files Browse the repository at this point in the history
  • Loading branch information
TheLostLambda committed Apr 24, 2024
1 parent ea4296d commit e5ea323
Show file tree
Hide file tree
Showing 13 changed files with 165 additions and 281 deletions.
2 changes: 2 additions & 0 deletions .helix/languages.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[language-server.rust-analyzer]
config = { cargo = { features = "all" } }
53 changes: 1 addition & 52 deletions src/eyreish/context.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::error::{ContextError, ErrorImpl};
use super::error::ContextError;
use super::{Report, WrapErr};
use core::fmt::{self, Debug, Display, Write};

Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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>
Expand Down
140 changes: 55 additions & 85 deletions src/eyreish/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ 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};
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 {
Expand All @@ -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.
Expand Down Expand Up @@ -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>,
};
Expand All @@ -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>,
};
Expand All @@ -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>,
};
Expand All @@ -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>>,
};
Expand Down Expand Up @@ -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>,
};
Expand Down Expand Up @@ -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())
}
}
Expand Down Expand Up @@ -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)
})
}
}

Expand Down Expand Up @@ -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),
}
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/eyreish/into_diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))))
}
}
6 changes: 3 additions & 3 deletions src/eyreish/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/eyreish/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)*)
)
};
Expand Down
2 changes: 2 additions & 0 deletions src/eyreish/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit e5ea323

Please sign in to comment.