- 
                Notifications
    
You must be signed in to change notification settings  - Fork 104
 
no_std support (via an enabled-by-default "std" feature) #157
Conversation
| @@ -0,0 +1,433 @@ | |||
| // Copyright 2014 The Rust Project Developers. See the COPYRIGHT | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a vendored version the stable parts of libstd's error.rs.
I know, "Eww", right? I'm not sure of a better solution though.
| //! [`Display`]: ../fmt/trait.Display.html | ||
| //! [`cause`]: trait.Error.html#method.cause | ||
| // This file contains the stable parts of std::error, vendored and modified | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The story here becomes even more complicated when we vendor the originally-in-libcore code which got moved into std into error-chain to make it no_std friendly.
| @@ -0,0 +1,37 @@ | |||
| //! Re-exports of types for glossing over no_std/std distinctions | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This whole module is a giant hack so we have a singular name we can use across both no_std and std to refer to these modules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I now see https://github.com/brson/error-chain/pull/64/files and it looks like it was using a similar hack... /cc @Yamakaky
| 
           Well, all of the  Even on nightly it breaks, because much of the documentation assumes   | 
    
| 
           Okay, after tweaking the build matrix a little bit, everything passes except the  Not sure what to do here... possibly just disable the smoke tests with   | 
    
Adds basic support for using error-chain in no_std contexts by disabling an enabled-by-default "std" feature.
| 
           I made the tests for   | 
    
| 
           This would need a major version bump since it's changing the minimum Rust version of   | 
    
| 
           Alternatively   | 
    
| 
           A slightly less backwards variant: have   | 
    
| 
           As this PR stands, it expects to get   | 
    
| 
           Maybe we should open a PR to move Error to core? Seems like to be possible. Part of std::fmt would have to be moved to, but I think it should be possible.  | 
    
| 
           @Yamakaky there was already a PR to do that which was rejected: rust-lang/rust#33149 Might be worth asking on that PR (all right, I just did)  | 
    
| 
           The libcore PR was rejected because it made  I think that can be bypassed with this hack (a combination of what I'll call the "exotic closure" trait and "predicate" trait): in libcore: #[doc(hidden)]
#[unstable(feature="libstd_implementation_detail")]
pub trait ErrorOrStrMapper {
    type Output;
    fn from_error<E: Error>(self, e: E) -> Self::Output;
    fn from_str(self, s: &str) -> Self::Output;
}
#[doc(hidden)]
#[unstable(feature="libstd_implementation_detail")]
trait ErrorOrStr {
    fn convert<F: ErrorOrStrMapper>(self, f: F) -> F::Output;
}
impl<E: Error> ErrorOrStr for E {
    fn to_error<F: ErrorOrStrMapper>(self, f: F) -> F::Output {
        f.from_error(self)
    }
}
// ok because libcore knows that `! &'a str : Error`
impl<'a> ErrorOrStr for &'a str {
    fn to_error<F: ErrorOrStrMapper>(self, f: F) -> F::Output {
        f.from_str(self)
    }
}in liballoc ( struct StringError(Box<str>);
struct BoxErrorMapper;
impl ErrorOrStrMapper for BoxErrorMapper {
    type Output = Box<Error + Send + Sync>;
    fn from_error<E: Error>(self, e: E) -> Self::Output {
        Box::new(e)
    }
    fn from_str(self, s: &str) -> Self::Output {
        // I'm not sure on that `From` - we might want to return an
        // OomError here if we fail to allocate enough memory.
        Box::new(StringError(From::from(s)))
    }
}
impl<E: ErrorOrStr> From<E> for Box<Error + Send + Sync> {
    fn from(err: E) -> Self {
        err.to_error(BoxErrorMapper)
    }
}
impl<E: ErrorOrStr> From<E> for Box<Error> {
    fn from(err: E) -> Self {
        err.to_error(BoxErrorMapper)
    }
}
impl From<Box<str>> for Box<Error + Send + Sync> {
    fn from(s: Box<str>) -> Self {
        Box::new(StringError(s))
    }
}
// ok because String is local, so we know `!String: ErrorOrStr`
impl From<Box<str>> for Box<Error> {
    fn from(s: String) -> Self {
        Box::new(StringError(s))
    }
}in libcollections: // ok because String is local, so we know `!String: ErrorOrStr`
impl From<String> for Box<Error + Send + Sync> {
    fn from(s: String) -> Self {
        Self::from(s.into_boxed_str())
    }
}
// ok because String is local, so we know `!String: ErrorOrStr`
impl From<String> for Box<Error> {
    fn from(s: String) -> Self {
        Self::from(s.into_boxed_str())
    }
}The downside is that the docs will have the   | 
    
| 
           @arielb1 perhaps that's worth mentioning on rust-lang/rust#33149 ?  | 
    
| #[cfg(not(feature = "std"))] | ||
| pub use collections::string; | ||
| #[cfg(feature = "std")] | ||
| pub use std::string; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be clearer to use something like that:
pub use imp::*;
#[cfg(not(feature = "std"))]
mod imp {
    pub use core::ops;
    ...
}
#[cfg(feature = "std")]
mod imp {
    pub use std::ops;
    ...
}| pub mod types; | ||
| 
               | 
          ||
| #[cfg(not(feature = "std"))] | ||
| pub mod error; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be put in types.rs
| 
           This entire PR is blocked on getting   | 
    
| 
           Oh, right, sorry. No, I haven't heard about it.  | 
    
| 
           So, this PR has diverged from master, depends on a blocker I don't think is going to get addressed soon, and at this point I no longer work in  Perhaps I should close it, and we can revisit if   | 
    
Adds basic support for using error-chain in no_std contexts by disabling an
enabled-by-default "std" feature.