Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,26 @@ jobs:
strategy:
fail-fast: false
matrix:
msrv: ["1.75.0"]
os:
- ubuntu
- macOS
- windows
runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/checkout@v4

- uses: SebRollen/[email protected]
id: msrv
with:
file: Cargo.toml
field: package.rust-version

- uses: dtolnay/rust-toolchain@v1
with:
toolchain: nightly
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: ${{ matrix.msrv }}
toolchain: ${{ steps.msrv.outputs.value }}

- name: Install minimal dependencies versions
run: cargo +nightly update -Z minimal-versions
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Support `Option` fields for `Error::source()` in `Error` derive.
([#459](https://github.com/JelteF/derive_more/pull/459))

### Changed

- The minimum supported Rust version (MSRV) is now Rust 1.81.
([#466](https://github.com/JelteF/derive_more/pull/466))

### Fixed

- Suppress deprecation warnings in generated code.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "derive_more"
version = "2.0.1"
edition = "2021"
rust-version = "1.75.0"
rust-version = "1.81.0"
description = "Adds #[derive(x)] macros for more traits"
authors = ["Jelte Fennema <[email protected]>"]
license = "MIT"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[![Latest Version](https://img.shields.io/crates/v/derive_more.svg)](https://crates.io/crates/derive_more)
[![Rust Documentation](https://docs.rs/derive_more/badge.svg)](https://docs.rs/derive_more)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/JelteF/derive_more/master/LICENSE)
[![Rust 1.75+](https://img.shields.io/badge/rustc-1.75+-lightgray.svg)](https://blog.rust-lang.org/2023/12/28/Rust-1.75.0.html)
[![Rust 1.81+](https://img.shields.io/badge/rustc-1.81+-lightgray.svg)](https://blog.rust-lang.org/2024/09/05/Rust-1.81.0)
[![Unsafe Forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance)

Rust has lots of builtin traits that are implemented for its basic types, such
Expand Down Expand Up @@ -216,7 +216,7 @@ extern crate derive_more;

## [MSRV] policy

This library requires Rust 1.75 or higher.
This library requires Rust 1.81 or higher.

Changing [MSRV] (minimum supported Rust version) of this crate is treated as a **minor version change** in terms of [Semantic Versioning].
- So, if [MSRV] changes are **NOT concerning** for your project, just use the default [caret requirement]:
Expand Down
2 changes: 1 addition & 1 deletion impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "derive_more-impl"
version = "2.0.1"
edition = "2021"
rust-version = "1.75.0"
rust-version = "1.81.0"
description = "Internal implementation of `derive_more` crate"
authors = ["Jelte Fennema <[email protected]>"]
license = "MIT"
Expand Down
10 changes: 3 additions & 7 deletions impl/doc/error.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Deriving `Error` will generate an `Error` implementation, that contains
(depending on the type) a `source()` and a `provide()` method. Please note,
at the time of writing `provide()` is only supported on nightly rust. So you
at the time of writing `provide()` is only supported on nightly Rust. So you
have to use that to make use of it.

For a struct, these methods always do the same. For an `enum` they have separate
Expand Down Expand Up @@ -44,12 +44,8 @@ ignored for one of these methods by using `#[error(not(backtrace))]` or

### What works in `no_std`?

If you want to use the `Error` derive on `no_std` environments, then
you need to compile with nightly, or wait until Rust 1.81 when `Error`
in `core` is expected to be stabilized.

Backtraces don't work though, because the `Backtrace` type is only available in
`std`.
`Error` derive fully works on `no_std` environments, except the `provide()`
method usage, because the `Backtrace` type is only available in `std`.


### `Option`al fields
Expand Down
24 changes: 6 additions & 18 deletions impl/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ pub fn expand(
// Not using `#[inline]` here on purpose, since this is almost never part
// of a hot codepath.
quote! {
// TODO: Use `derive_more::core::error::Error` once `error_in_core` Rust feature is
// stabilized.
fn source(&self) -> Option<&(dyn derive_more::with_trait::Error + 'static)> {
fn source(&self) -> Option<&(dyn derive_more::core::error::Error + 'static)> {
use derive_more::__private::AsDynError as _;
#source
}
Expand Down Expand Up @@ -84,9 +82,7 @@ pub fn expand(
where #(
#bounds: derive_more::core::fmt::Debug
+ derive_more::core::fmt::Display
// TODO: Use `derive_more::core::error::Error` once `error_in_core`
// Rust feature is stabilized.
+ derive_more::with_trait::Error
+ derive_more::core::error::Error
+ 'static
),*
},
Expand All @@ -97,9 +93,7 @@ pub fn expand(

let render = quote! {
#[automatically_derived]
// TODO: Use `derive_more::core::error::Error` once `error_in_core` Rust feature is
// stabilized.
impl #impl_generics derive_more::with_trait::Error for #ident #ty_generics #where_clause {
impl #impl_generics derive_more::core::error::Error for #ident #ty_generics #where_clause {
#source
#provide
}
Expand Down Expand Up @@ -229,9 +223,7 @@ impl ParsedFields<'_, '_> {
let source_provider = self.source.map(|source| {
let source_expr = &self.data.members[source];
quote! {
// TODO: Use `derive_more::core::error::Error` once `error_in_core` Rust feature is
// stabilized.
derive_more::with_trait::Error::provide(&#source_expr, request);
derive_more::core::error::Error::provide(&#source_expr, request);
}
});
let backtrace_provider = self
Expand Down Expand Up @@ -261,9 +253,7 @@ impl ParsedFields<'_, '_> {
let pattern = self.data.matcher(&[source], &[quote! { source }]);
Some(quote! {
#pattern => {
// TODO: Use `derive_more::core::error::Error` once `error_in_core` Rust
// feature is stabilized.
derive_more::with_trait::Error::provide(source, request);
derive_more::core::error::Error::provide(source, request);
}
})
}
Expand All @@ -275,9 +265,7 @@ impl ParsedFields<'_, '_> {
Some(quote! {
#pattern => {
request.provide_ref::<::std::backtrace::Backtrace>(backtrace);
// TODO: Use `derive_more::core::error::Error` once `error_in_core` Rust
// feature is stabilized.
derive_more::with_trait::Error::provide(source, request);
derive_more::core::error::Error::provide(source, request);
}
})
}
Expand Down
10 changes: 4 additions & 6 deletions src/add.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Definitions used in derived implementations of [`core::ops::Add`]-like traits.

use core::fmt;
use core::{error::Error, fmt};

use crate::UnitError;

Expand Down Expand Up @@ -30,8 +30,7 @@ impl fmt::Display for WrongVariantError {
}
}

#[cfg(feature = "std")]
impl std::error::Error for WrongVariantError {}
impl Error for WrongVariantError {}

/// Possible errors returned by the derived implementations of binary
/// arithmetic or logic operations.
Expand All @@ -53,9 +52,8 @@ impl fmt::Display for BinaryError {
}
}

#[cfg(feature = "std")]
impl std::error::Error for BinaryError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
impl Error for BinaryError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::Mismatch(e) => e.source(),
Self::Unit(e) => e.source(),
Expand Down
12 changes: 5 additions & 7 deletions src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub use self::try_into::TryIntoError;

#[cfg(feature = "try_from")]
mod try_from {
use core::fmt;
use core::{error::Error, fmt};

/// Error returned by the derived [`TryFrom`] implementation on enums to
/// convert from their repr.
Expand Down Expand Up @@ -42,14 +42,13 @@ mod try_from {
}
}

#[cfg(feature = "std")]
// `T` should only be an integer type and therefore be debug
impl<T: fmt::Debug> std::error::Error for TryFromReprError<T> {}
// `T` should only be an integer type and therefore be `Debug`.
impl<T: fmt::Debug> Error for TryFromReprError<T> {}
}

#[cfg(feature = "try_into")]
mod try_into {
use core::fmt;
use core::{error::Error, fmt};

/// Error returned by the derived [`TryInto`] implementation.
///
Expand Down Expand Up @@ -92,6 +91,5 @@ mod try_into {
}
}

#[cfg(feature = "std")]
impl<T: fmt::Debug> std::error::Error for TryIntoError<T> {}
impl<T: fmt::Debug> Error for TryIntoError<T> {}
}
3 changes: 0 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,7 @@ pub mod with_trait {
UpperHex,
);

#[cfg(not(feature = "std"))]
re_export_traits!("error", error_traits, core::error, Error);
#[cfg(feature = "std")]
re_export_traits!("error", error_traits, std::error, Error);

re_export_traits!("from", from_traits, core::convert, From);

Expand Down
5 changes: 2 additions & 3 deletions src/ops.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Definitions used in derived implementations of [`core::ops`] traits.

use core::fmt;
use core::{error::Error, fmt};

/// Error returned by the derived implementations when an arithmetic or logic
/// operation is invoked on a unit-like variant of an enum.
Expand All @@ -24,5 +24,4 @@ impl fmt::Display for UnitError {
}
}

#[cfg(feature = "std")]
impl std::error::Error for UnitError {}
impl Error for UnitError {}
5 changes: 2 additions & 3 deletions src/str.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::fmt;
use core::{error::Error, fmt};

/// Error of parsing an enum value its string representation.
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
Expand All @@ -21,5 +21,4 @@ impl fmt::Display for FromStrError {
}
}

#[cfg(feature = "std")]
impl std::error::Error for FromStrError {}
impl Error for FromStrError {}
9 changes: 5 additions & 4 deletions src/try_unwrap.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::{error::Error, fmt};

/// Error returned by the derived [`TryUnwrap`] implementation.
///
/// [`TryUnwrap`]: macro@crate::TryUnwrap
Expand Down Expand Up @@ -32,8 +34,8 @@ impl<T> TryUnwrapError<T> {
}
}

impl<T> core::fmt::Display for TryUnwrapError<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
impl<T> fmt::Display for TryUnwrapError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Attempt to call `{enum_name}::{func_name}()` on a `{enum_name}::{variant_name}` value",
Expand All @@ -44,5 +46,4 @@ impl<T> core::fmt::Display for TryUnwrapError<T> {
}
}

#[cfg(feature = "std")]
impl<T: core::fmt::Debug> std::error::Error for TryUnwrapError<T> {}
impl<T: fmt::Debug> Error for TryUnwrapError<T> {}
7 changes: 1 addition & 6 deletions src/vendor/thiserror/aserror.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
#[cfg(not(feature = "std"))]
use core::error::Error;
#[cfg(feature = "std")]
use std::error::Error;

use core::panic::UnwindSafe;
use core::{error::Error, panic::UnwindSafe};

#[doc(hidden)]
pub trait AsDynError<'a>: Sealed {
Expand Down
11 changes: 3 additions & 8 deletions tests/error/derives_for_enums_with_source.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#![allow(dead_code)] // some code is tested for type checking only

#[cfg(not(feature = "std"))]
use alloc::boxed::Box;

use super::*;

type RenamedOption<T> = Option<T>;
Expand All @@ -15,7 +18,6 @@ enum TestErr {
source: SimpleErr,
field: i32,
},
#[cfg(feature = "std")]
NamedImplicitBoxedSource {
source: Box<dyn Error + Send + 'static>,
field: i32,
Expand All @@ -24,7 +26,6 @@ enum TestErr {
source: Option<SimpleErr>,
field: i32,
},
#[cfg(feature = "std")]
NamedImplicitOptionalBoxedSource {
source: Option<Box<dyn Error + Send + 'static>>,
field: i32,
Expand All @@ -49,7 +50,6 @@ enum TestErr {
explicit_source: RenamedOption<SimpleErr>,
field: i32,
},
#[cfg(feature = "std")]
NamedExplicitRenamedOptionalBoxedSource {
#[error(source(optional))]
explicit_source: RenamedOption<Box<dyn Error + Send + 'static>>,
Expand Down Expand Up @@ -84,7 +84,6 @@ enum TestErr {
#[error(source(optional))] RenamedOption<SimpleErr>,
i32,
),
#[cfg(feature = "std")]
UnnamedExplicitRenamedOptionalBoxedSource(
#[error(source(optional))] RenamedOption<Box<dyn Error + Send + 'static>>,
i32,
Expand Down Expand Up @@ -154,7 +153,6 @@ fn named_implicit_optional_source() {
assert!(err.source().unwrap().is::<SimpleErr>());
}

#[cfg(feature = "std")]
#[test]
fn named_implicit_boxed_source() {
let err = TestErr::NamedImplicitBoxedSource {
Expand All @@ -166,7 +164,6 @@ fn named_implicit_boxed_source() {
assert!(err.source().unwrap().is::<SimpleErr>());
}

#[cfg(feature = "std")]
#[test]
fn named_implicit_optional_boxed_source() {
let err = TestErr::NamedImplicitOptionalBoxedSource {
Expand Down Expand Up @@ -221,7 +218,6 @@ fn named_explicit_renamed_optional_source() {
assert!(err.source().unwrap().is::<SimpleErr>());
}

#[cfg(feature = "std")]
#[test]
fn named_explicit_renamed_optional_boxed_source() {
let err = TestErr::NamedExplicitRenamedOptionalBoxedSource {
Expand Down Expand Up @@ -325,7 +321,6 @@ fn unnamed_explicit_renamed_optional_source() {
assert!(err.source().unwrap().is::<SimpleErr>());
}

#[cfg(feature = "std")]
#[test]
fn unnamed_explicit_renamed_optional_boxed_source() {
let err = TestErr::UnnamedExplicitRenamedOptionalBoxedSource(
Expand Down
Loading