-
Notifications
You must be signed in to change notification settings - Fork 102
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.