Skip to content

Commit

Permalink
Allow disabling std dependency on 1.81+
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Nov 6, 2024
1 parent 8277ec4 commit 0e885c1
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
strategy:
fail-fast: false
matrix:
rust: [nightly, beta, stable, 1.70.0]
rust: [nightly, beta, stable, 1.81.0, 1.70.0]
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
Expand Down
16 changes: 16 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ license = "MIT OR Apache-2.0"
repository = "https://github.com/dtolnay/thiserror"
rust-version = "1.61"

[features]
default = ["std"]

# Std feature enables support for formatting std::path::{Path, PathBuf}
# conveniently in an error message.
#
# #[derive(Error, Debug)]
# #[error("failed to create configuration file {path}")]
# pub struct MyError {
# pub path: PathBuf,
# pub source: std::io::Error,
# }
#
# Without std, this would need to be written #[error("... {}", path.display())].
std = []

[dependencies]
thiserror-impl = { version = "=1.0.68", path = "impl" }

Expand Down
9 changes: 8 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,14 @@ fn main() {
println!("cargo:rerun-if-env-changed=RUSTC_BOOTSTRAP");
}

let rustc = match rustc_minor_version() {
// core::error::Error stabilized in Rust 1.81
// https://blog.rust-lang.org/2024/09/05/Rust-1.81.0.html#coreerrorerror
let rustc = rustc_minor_version();
if cfg!(not(feature = "std")) && rustc.map_or(false, |rustc| rustc < 81) {
println!("cargo:rustc-cfg=feature=\"std\"");
}

let rustc = match rustc {
Some(rustc) => rustc,
None => return,
};
Expand Down
1 change: 1 addition & 0 deletions build/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// member access API. If the current toolchain is able to compile it, then
// thiserror is able to provide backtrace support.

#![no_std]
#![feature(error_generic_member_access)]

use core::error::{Error, Request};
Expand Down
2 changes: 1 addition & 1 deletion src/aserror.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::error::Error;
use core::panic::UnwindSafe;
use std::error::Error;

#[doc(hidden)]
pub trait AsDynError<'a>: Sealed {
Expand Down
35 changes: 35 additions & 0 deletions src/display.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use core::fmt::Display;
#[cfg(feature = "std")]
use std::path::{self, Path, PathBuf};

#[doc(hidden)]
Expand All @@ -21,6 +22,7 @@ where
}
}

#[cfg(feature = "std")]
impl<'a> AsDisplay<'a> for Path {
type Target = path::Display<'a>;

Expand All @@ -30,6 +32,7 @@ impl<'a> AsDisplay<'a> for Path {
}
}

#[cfg(feature = "std")]
impl<'a> AsDisplay<'a> for PathBuf {
type Target = path::Display<'a>;

Expand All @@ -42,5 +45,37 @@ impl<'a> AsDisplay<'a> for PathBuf {
#[doc(hidden)]
pub trait Sealed {}
impl<T: Display> Sealed for &T {}
#[cfg(feature = "std")]
impl Sealed for Path {}
#[cfg(feature = "std")]
impl Sealed for PathBuf {}

// Add a synthetic second impl of AsDisplay to prevent the "single applicable
// impl" rule from making too weird inference decision based on the single impl
// for &T, which could lead to code that compiles with thiserror's std feature
// off but breaks under feature unification when std is turned on by an
// unrelated crate.
#[cfg(not(feature = "std"))]
mod placeholder {
use super::{AsDisplay, Sealed};
use core::fmt::{self, Display};

pub struct Placeholder;

impl<'a> AsDisplay<'a> for Placeholder {
type Target = Self;

#[inline]
fn as_display(&'a self) -> Self::Target {
Placeholder
}
}

impl Display for Placeholder {
fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
unreachable!()
}
}

impl Sealed for Placeholder {}
}
12 changes: 9 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@
//!
//! [`anyhow`]: https://github.com/dtolnay/anyhow

#![no_std]
#![doc(html_root_url = "https://docs.rs/thiserror/1.0.68")]
#![allow(
clippy::module_name_repetitions,
Expand All @@ -270,6 +271,11 @@
#[cfg(all(thiserror_nightly_testing, not(error_generic_member_access)))]
compile_error!("Build script probe failed to compile.");

#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "std")]
extern crate std as core;

mod aserror;
mod display;
#[cfg(error_generic_member_access)]
Expand All @@ -287,9 +293,9 @@ pub mod __private {
#[cfg(error_generic_member_access)]
#[doc(hidden)]
pub use crate::provide::ThiserrorProvide;
#[cfg(not(thiserror_no_backtrace_type))]
#[doc(hidden)]
pub use std::backtrace::Backtrace;
pub use core::error::Error;
#[cfg(all(feature = "std", not(thiserror_no_backtrace_type)))]
#[doc(hidden)]
pub use std::error::Error;
pub use std::backtrace::Backtrace;
}
2 changes: 1 addition & 1 deletion src/provide.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::error::{Error, Request};
use core::error::{Error, Request};

#[doc(hidden)]
pub trait ThiserrorProvide: Sealed {
Expand Down

0 comments on commit 0e885c1

Please sign in to comment.