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