diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e722e6c7..68dd4978 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -116,6 +116,10 @@ jobs: test-features: name: test features + strategy: + fail-fast: false + matrix: + std: ["std", "no_std"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -128,7 +132,7 @@ jobs: go install github.com/pelletier/go-toml/cmd/tomljson@latest echo "$HOME/go/bin" >> $GITHUB_PATH - - run: ci/test_all_features.sh + - run: ci/test_all_features.sh ${{ matrix.std }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 10267153..0332d278 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). should prevent code style linters from attempting to modify the generated code. - Upgrade to `syn` 2.0. +- The `Error` derive now works in nightly `no_std` environments when enabling + `#![feature(error_in_core)]`. ### Fixed diff --git a/Cargo.toml b/Cargo.toml index c65cb138..7ad2a175 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,9 @@ members = ["impl"] [dependencies] derive_more-impl = { version = "=0.99.17", path = "impl" } +[build-dependencies] +rustc_version = { version = "0.4", optional = true } + [dev-dependencies] rustversion = "1.0" trybuild = "1.0.56" @@ -50,7 +53,7 @@ debug = ["derive_more-impl/debug"] deref = ["derive_more-impl/deref"] deref_mut = ["derive_more-impl/deref_mut"] display = ["derive_more-impl/display"] -error = ["derive_more-impl/error", "std"] +error = ["derive_more-impl/error"] from = ["derive_more-impl/from"] from_str = ["derive_more-impl/from_str"] index = ["derive_more-impl/index"] @@ -96,7 +99,7 @@ full = [ "try_unwrap", ] -testing-helpers = ["derive_more-impl/testing-helpers"] +testing-helpers = ["derive_more-impl/testing-helpers", "dep:rustc_version"] [[test]] name = "add_assign" @@ -151,7 +154,7 @@ required-features = ["display"] [[test]] name = "error" path = "tests/error_tests.rs" -required-features = ["error", "std"] +required-features = ["error"] [[test]] name = "from" diff --git a/build.rs b/build.rs new file mode 100644 index 00000000..dbd20bb6 --- /dev/null +++ b/build.rs @@ -0,0 +1,15 @@ +#[cfg(not(feature = "testing-helpers"))] +fn detect_nightly() {} + +#[cfg(feature = "testing-helpers")] +fn detect_nightly() { + use rustc_version::{version_meta, Channel}; + + if version_meta().unwrap().channel == Channel::Nightly { + println!("cargo:rustc-cfg=nightly"); + } +} + +fn main() { + detect_nightly(); +} diff --git a/ci/test_all_features.sh b/ci/test_all_features.sh index cff8db1f..9357d570 100755 --- a/ci/test_all_features.sh +++ b/ci/test_all_features.sh @@ -1,6 +1,12 @@ #!/usr/bin/env bash + +std='' +if [ "${1:-}" = 'std' ]; then + std=',std' +fi + set -euxo pipefail -for feature in $(tomljson Cargo.toml | jq --raw-output '.features | keys[]' | grep -v 'default\|std\|testing-helpers'); do - cargo test -p derive_more --tests --no-default-features --features "$feature,testing-helpers"; +for feature in $(tomljson Cargo.toml | jq --raw-output '.features | keys[]' | grep -v 'default\|std\|full\|testing-helpers'); do + cargo +nightly test -p derive_more --tests --no-default-features --features "$feature$std,testing-helpers" done diff --git a/impl/Cargo.toml b/impl/Cargo.toml index b9054526..51719c39 100644 --- a/impl/Cargo.toml +++ b/impl/Cargo.toml @@ -33,7 +33,7 @@ unicode-xid = { version = "0.2.2", optional = true } rustc_version = { version = "0.4", optional = true } [dev-dependencies] -derive_more = { path = "..", features = ["add", "debug", "error", "from_str", "not", "try_into", "try_unwrap"] } +derive_more = { path = "..", features = ["add", "debug", "error", "from_str", "not", "std", "try_into", "try_unwrap"] } itertools = "0.11.0" [badges] diff --git a/impl/doc/error.md b/impl/doc/error.md index 81e2ac60..20ff24cf 100644 --- a/impl/doc/error.md +++ b/impl/doc/error.md @@ -42,13 +42,25 @@ ignored for one of these methods by using `#[error(not(backtrace))]` or `#[error(not(source))]`. +### What works in `no_std`? + +If you want to use the `Error` derive on `no_std` environments, then you need to +compile with nightly and enable this feature: +```ignore +#![feature(error_in_core)] +``` + +Backtraces don't work though, because the `Backtrace` type is only available in +`std`. + + ## Example usage ```rust # #![cfg_attr(nightly, feature(error_generic_member_access, provide_any))] -// Nightly requires enabling this features: +// Nightly requires enabling these features: // #![feature(error_generic_member_access, provide_any)] # #[cfg(not(nightly))] fn main() {} # #[cfg(nightly)] fn main() { diff --git a/impl/src/error.rs b/impl/src/error.rs index 3fd10ea4..4c4ba983 100644 --- a/impl/src/error.rs +++ b/impl/src/error.rs @@ -18,7 +18,7 @@ pub fn expand( let state = State::with_attr_params( input, trait_name, - quote! { ::std::error }, + quote! { ::derive_more::__private::Error }, trait_name.to_lowercase(), allowed_attr_params(), )?; @@ -39,7 +39,7 @@ pub fn expand( let source = source.map(|source| { quote! { - fn source(&self) -> Option<&(dyn ::std::error::Error + 'static)> { + fn source(&self) -> Option<&(dyn ::derive_more::__private::Error + 'static)> { use ::derive_more::__private::AsDynError; #source } @@ -48,7 +48,7 @@ pub fn expand( let provide = provide.map(|provide| { quote! { - fn provide<'_demand>(&'_demand self, demand: &mut ::std::any::Demand<'_demand>) { + fn provide<'_demand>(&'_demand self, demand: &mut ::core::any::Demand<'_demand>) { #provide } } @@ -62,7 +62,7 @@ pub fn expand( &generics, quote! { where - #ident #ty_generics: ::std::fmt::Debug + ::std::fmt::Display + #ident #ty_generics: ::core::fmt::Debug + ::core::fmt::Display }, ); } @@ -73,7 +73,7 @@ pub fn expand( &generics, quote! { where - #(#bounds: ::std::fmt::Debug + ::std::fmt::Display + ::std::error::Error + 'static),* + #(#bounds: ::core::fmt::Debug + ::core::fmt::Display + ::derive_more::__private::Error + 'static),* }, ); } @@ -82,7 +82,7 @@ pub fn expand( let render = quote! { #[automatically_derived] - impl #impl_generics ::std::error::Error for #ident #ty_generics #where_clause { + impl #impl_generics ::derive_more::__private::Error for #ident #ty_generics #where_clause { #source #provide } @@ -207,7 +207,7 @@ impl<'input, 'state> ParsedFields<'input, 'state> { let source_provider = self.source.map(|source| { let source_expr = &self.data.members[source]; quote! { - ::std::error::Error::provide(&#source_expr, demand); + ::derive_more::__private::Error::provide(&#source_expr, demand); } }); let backtrace_provider = self @@ -217,7 +217,7 @@ impl<'input, 'state> ParsedFields<'input, 'state> { .then(|| { let backtrace_expr = &self.data.members[backtrace]; quote! { - demand.provide_ref::(&#backtrace_expr); + demand.provide_ref::<::std::backtrace::Backtrace>(&#backtrace_expr); } }); @@ -237,7 +237,7 @@ impl<'input, 'state> ParsedFields<'input, 'state> { let pattern = self.data.matcher(&[source], &[quote! { source }]); Some(quote! { #pattern => { - ::std::error::Error::provide(source, demand); + ::derive_more::__private::Error::provide(source, demand); } }) } @@ -248,8 +248,8 @@ impl<'input, 'state> ParsedFields<'input, 'state> { ); Some(quote! { #pattern => { - demand.provide_ref::(backtrace); - ::std::error::Error::provide(source, demand); + demand.provide_ref::<::std::backtrace::Backtrace>(backtrace); + ::derive_more::__private::Error::provide(source, demand); } }) } @@ -257,7 +257,7 @@ impl<'input, 'state> ParsedFields<'input, 'state> { let pattern = self.data.matcher(&[backtrace], &[quote! { backtrace }]); Some(quote! { #pattern => { - demand.provide_ref::(backtrace); + demand.provide_ref::<::std::backtrace::Backtrace>(backtrace); } }) } diff --git a/impl/src/fmt/display.rs b/impl/src/fmt/display.rs index 0e9983a5..7eb893e4 100644 --- a/impl/src/fmt/display.rs +++ b/impl/src/fmt/display.rs @@ -331,12 +331,16 @@ impl<'a> Expansion<'a> { /// Generates trait bounds for a struct or an enum variant. fn generate_bounds(&self) -> Vec { let Some(fmt) = &self.attrs.fmt else { - return self.fields.iter().next().map(|f| { - let ty = &f.ty; - let trait_ident = &self.trait_ident; - vec![parse_quote! { #ty: ::core::fmt::#trait_ident }] - }) - .unwrap_or_default(); + return self + .fields + .iter() + .next() + .map(|f| { + let ty = &f.ty; + let trait_ident = &self.trait_ident; + vec![parse_quote! { #ty: ::core::fmt::#trait_ident }] + }) + .unwrap_or_default(); }; fmt.bounded_types(self.fields) diff --git a/src/lib.rs b/src/lib.rs index 911b5445..82ced1e8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ #![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(all(not(feature = "std"), feature = "error"), feature(error_in_core))] // These links overwrite the ones in `README.md` // to become proper intra-doc links in Rust docs. //! [`From`]: crate::From @@ -77,6 +78,11 @@ mod vendor; #[doc(hidden)] #[cfg(feature = "error")] pub mod __private { + #[cfg(not(feature = "std"))] + pub use ::core::error::Error; + #[cfg(feature = "std")] + pub use ::std::error::Error; + pub use crate::vendor::thiserror::aserror::AsDynError; } diff --git a/src/vendor/thiserror/aserror.rs b/src/vendor/thiserror/aserror.rs index 5fea84ef..c3e086f0 100644 --- a/src/vendor/thiserror/aserror.rs +++ b/src/vendor/thiserror/aserror.rs @@ -1,5 +1,9 @@ +#[cfg(not(feature = "std"))] +use core::error::Error; +#[cfg(feature = "std")] use std::error::Error; -use std::panic::UnwindSafe; + +use core::panic::UnwindSafe; pub trait AsDynError<'a>: Sealed { fn as_dyn_error(&self) -> &(dyn Error + 'a); diff --git a/tests/add.rs b/tests/add.rs index ac0230f2..4c38fdae 100644 --- a/tests/add.rs +++ b/tests/add.rs @@ -1,3 +1,4 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] use derive_more::Add; diff --git a/tests/add_assign.rs b/tests/add_assign.rs index 93270d35..48795851 100644 --- a/tests/add_assign.rs +++ b/tests/add_assign.rs @@ -1,3 +1,4 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] use derive_more::AddAssign; diff --git a/tests/as_mut.rs b/tests/as_mut.rs index 1ca576e0..2a973d45 100644 --- a/tests/as_mut.rs +++ b/tests/as_mut.rs @@ -1,7 +1,12 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] -use std::path::PathBuf; -use std::ptr; +#[cfg(not(feature = "std"))] +extern crate alloc; + +#[cfg(not(feature = "std"))] +use alloc::{string::String, vec, vec::Vec}; +use core::ptr; use derive_more::AsMut; @@ -39,36 +44,64 @@ fn single_field_struct() { assert!(ptr::eq(&mut item.first, item.as_mut())); } -#[derive(AsMut)] -struct MultiFieldTuple(#[as_mut] String, #[as_mut] PathBuf, Vec); - -#[test] -fn multi_field_tuple() { - let mut item = MultiFieldTuple("test".into(), PathBuf::new(), vec![]); - - assert!(ptr::eq(&mut item.0, item.as_mut())); - assert!(ptr::eq(&mut item.1, item.as_mut())); -} - -#[derive(AsMut)] -struct MultiFieldStruct { - #[as_mut] - first: String, - #[as_mut] - second: PathBuf, - third: Vec, -} - -#[test] -fn multi_field_struct() { - let mut item = MultiFieldStruct { - first: "test".into(), - second: PathBuf::new(), - third: vec![], - }; - - assert!(ptr::eq(&mut item.first, item.as_mut())); - assert!(ptr::eq(&mut item.second, item.as_mut())); +#[cfg(feature = "std")] +mod pathbuf { + use std::path::PathBuf; + + use super::*; + + #[derive(AsMut)] + struct MultiFieldTuple(#[as_mut] String, #[as_mut] PathBuf, Vec); + + #[test] + fn multi_field_tuple() { + let mut item = MultiFieldTuple("test".into(), PathBuf::new(), vec![]); + + assert!(ptr::eq(&mut item.0, item.as_mut())); + assert!(ptr::eq(&mut item.1, item.as_mut())); + } + + #[derive(AsMut)] + struct MultiFieldStruct { + #[as_mut] + first: String, + #[as_mut] + second: PathBuf, + third: Vec, + } + + #[test] + fn multi_field_struct() { + let mut item = MultiFieldStruct { + first: "test".into(), + second: PathBuf::new(), + third: vec![], + }; + + assert!(ptr::eq(&mut item.first, item.as_mut())); + assert!(ptr::eq(&mut item.second, item.as_mut())); + } + + #[derive(AsMut)] + struct MultiFieldGenericStruct { + #[as_mut] + first: Vec, + #[as_mut] + second: PathBuf, + third: Vec, + } + + #[test] + fn multi_field_generic_struct() { + let mut item = MultiFieldGenericStruct { + first: b"test".to_vec(), + second: PathBuf::new(), + third: vec![], + }; + + assert!(ptr::eq(&mut item.first, item.as_mut())); + assert!(ptr::eq(&mut item.second, item.as_mut())); + } } #[derive(AsMut)] @@ -82,24 +115,3 @@ fn single_field_generic_struct() { assert!(ptr::eq(&mut item.first, item.as_mut())); } - -#[derive(AsMut)] -struct MultiFieldGenericStruct { - #[as_mut] - first: Vec, - #[as_mut] - second: PathBuf, - third: Vec, -} - -#[test] -fn multi_field_generic_struct() { - let mut item = MultiFieldGenericStruct { - first: b"test".to_vec(), - second: PathBuf::new(), - third: vec![], - }; - - assert!(ptr::eq(&mut item.first, item.as_mut())); - assert!(ptr::eq(&mut item.second, item.as_mut())); -} diff --git a/tests/as_ref.rs b/tests/as_ref.rs index 0e51569d..d28f9343 100644 --- a/tests/as_ref.rs +++ b/tests/as_ref.rs @@ -1,7 +1,12 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] -use std::path::PathBuf; -use std::ptr; +#[cfg(not(feature = "std"))] +extern crate alloc; + +#[cfg(not(feature = "std"))] +use alloc::{string::String, vec, vec::Vec}; +use core::ptr; use derive_more::AsRef; @@ -39,36 +44,43 @@ fn single_field_struct() { assert!(ptr::eq(&item.first, item.as_ref())); } -#[derive(AsRef)] -struct MultiFieldTuple(#[as_ref] String, #[as_ref] PathBuf, Vec); - -#[test] -fn multi_field_tuple() { - let item = MultiFieldTuple("test".into(), PathBuf::new(), vec![]); - - assert!(ptr::eq(&item.0, item.as_ref())); - assert!(ptr::eq(&item.1, item.as_ref())); -} - -#[derive(AsRef)] -struct MultiFieldStruct { - #[as_ref] - first: String, - #[as_ref] - second: PathBuf, - third: Vec, -} - -#[test] -fn multi_field_struct() { - let item = MultiFieldStruct { - first: "test".into(), - second: PathBuf::new(), - third: vec![], - }; - - assert!(ptr::eq(&item.first, item.as_ref())); - assert!(ptr::eq(&item.second, item.as_ref())); +#[cfg(feature = "std")] +mod pathbuf { + use std::path::PathBuf; + + use super::*; + + #[derive(AsRef)] + struct MultiFieldTuple(#[as_ref] String, #[as_ref] PathBuf, Vec); + + #[test] + fn multi_field_tuple() { + let item = MultiFieldTuple("test".into(), PathBuf::new(), vec![]); + + assert!(ptr::eq(&item.0, item.as_ref())); + assert!(ptr::eq(&item.1, item.as_ref())); + } + + #[derive(AsRef)] + struct MultiFieldStruct { + #[as_ref] + first: String, + #[as_ref] + second: PathBuf, + third: Vec, + } + + #[test] + fn multi_field_struct() { + let item = MultiFieldStruct { + first: "test".into(), + second: PathBuf::new(), + third: vec![], + }; + + assert!(ptr::eq(&item.first, item.as_ref())); + assert!(ptr::eq(&item.second, item.as_ref())); + } } #[derive(AsRef)] diff --git a/tests/constructor.rs b/tests/constructor.rs index 8f9be453..6199d1d1 100644 --- a/tests/constructor.rs +++ b/tests/constructor.rs @@ -1,3 +1,4 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] use derive_more::Constructor; diff --git a/tests/debug.rs b/tests/debug.rs index daf3dab1..de9ff611 100644 --- a/tests/debug.rs +++ b/tests/debug.rs @@ -1,7 +1,14 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] +#[cfg(not(feature = "std"))] +extern crate alloc; + mod structs { mod unit { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)] @@ -25,6 +32,9 @@ mod structs { } mod single_field { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)] @@ -47,6 +57,9 @@ mod structs { } mod str_field { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)] @@ -74,6 +87,9 @@ mod structs { } mod interpolated_field { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)] @@ -101,6 +117,9 @@ mod structs { } mod ignore { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)] @@ -123,6 +142,9 @@ mod structs { } mod multi_field { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)] @@ -161,6 +183,9 @@ mod structs { } mod str_field { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)] @@ -204,6 +229,9 @@ mod structs { } mod interpolated_field { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)] @@ -247,6 +275,9 @@ mod structs { } mod ignore { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)] @@ -295,11 +326,14 @@ mod enums { #[derive(Debug)] enum Void {} - const fn assert() {} + const fn assert() {} const _: () = assert::(); } mod unit_variant { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)] @@ -321,6 +355,9 @@ mod enums { } mod single_field_variant { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)] @@ -407,6 +444,9 @@ mod enums { } mod multi_field_variant { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)] @@ -532,6 +572,9 @@ mod enums { } mod generic { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; struct NotDebug; @@ -818,6 +861,9 @@ mod generic { } mod associated_type_field_enumerator { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; trait Trait { @@ -875,6 +921,9 @@ mod generic { } mod complex_type_field_enumerator { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)] @@ -931,6 +980,9 @@ mod generic { } mod reference { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[test] @@ -955,6 +1007,9 @@ mod generic { } mod indirect { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)] @@ -976,6 +1031,9 @@ mod generic { } mod bound { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[test] diff --git a/tests/deref.rs b/tests/deref.rs index afb34d7e..9c6263ea 100644 --- a/tests/deref.rs +++ b/tests/deref.rs @@ -1,5 +1,12 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code, unused_imports)] +#[cfg(not(feature = "std"))] +extern crate alloc; + +#[cfg(not(feature = "std"))] +use ::alloc::{boxed::Box, vec::Vec}; + use derive_more::Deref; #[derive(Deref)] diff --git a/tests/deref_mut.rs b/tests/deref_mut.rs index 988c5295..fb1fe87e 100644 --- a/tests/deref_mut.rs +++ b/tests/deref_mut.rs @@ -1,5 +1,12 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code, unused_imports)] +#[cfg(not(feature = "std"))] +extern crate alloc; + +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, format, vec, vec::Vec}; + use derive_more::DerefMut; #[derive(DerefMut)] diff --git a/tests/display.rs b/tests/display.rs index e12c07fb..8683c8c3 100644 --- a/tests/display.rs +++ b/tests/display.rs @@ -1,9 +1,17 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code, unused_imports)] -use std::{ - fmt::{Binary, Display}, - path::PathBuf, +#[cfg(not(feature = "std"))] +extern crate alloc; + +#[cfg(not(feature = "std"))] +use alloc::{ + boxed::Box, + format, + string::{String, ToString}, + vec::Vec, }; +use core::fmt::{Binary, Display}; use derive_more::{Binary, Display, Octal, UpperHex}; @@ -331,7 +339,7 @@ mod enums { } mod generic { - use derive_more::Display; + use super::*; trait Bound {} diff --git a/tests/error/derives_for_enums_with_source.rs b/tests/error/derives_for_enums_with_source.rs index f1867fa0..d8e5db7d 100644 --- a/tests/error/derives_for_enums_with_source.rs +++ b/tests/error/derives_for_enums_with_source.rs @@ -12,6 +12,7 @@ enum TestErr { source: SimpleErr, field: i32, }, + #[cfg(feature = "std")] NamedImplicitBoxedSource { source: Box, field: i32, @@ -98,6 +99,7 @@ fn named_implicit_source() { assert!(err.source().unwrap().is::()); } +#[cfg(feature = "std")] #[test] fn named_implicit_boxed_source() { let err = TestErr::NamedImplicitBoxedSource { diff --git a/tests/error/mod.rs b/tests/error/mod.rs index 6b7785a7..a041ec17 100644 --- a/tests/error/mod.rs +++ b/tests/error/mod.rs @@ -1,3 +1,6 @@ +#[cfg(not(feature = "std"))] +use core::error::Error; +#[cfg(feature = "std")] use std::error::Error; use derive_more::Error; @@ -29,17 +32,17 @@ use derive_more::Error; /// ``` macro_rules! derive_display { (@fmt) => { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { write!(f, "") } }; ($type:ident) => { - impl ::std::fmt::Display for $type { + impl ::core::fmt::Display for $type { derive_display!(@fmt); } }; ($type:ident, $($type_parameters:ident),*) => { - impl<$($type_parameters),*> ::std::fmt::Display for $type<$($type_parameters),*> { + impl<$($type_parameters),*> ::core::fmt::Display for $type<$($type_parameters),*> { derive_display!(@fmt); } }; @@ -50,7 +53,7 @@ mod derives_for_generic_enums_with_source; mod derives_for_generic_structs_with_source; mod derives_for_structs_with_source; -#[cfg(nightly)] +#[cfg(all(feature = "std", nightly))] mod nightly; derive_display!(SimpleErr); diff --git a/tests/error_tests.rs b/tests/error_tests.rs index 952a8dd2..28388ac0 100644 --- a/tests/error_tests.rs +++ b/tests/error_tests.rs @@ -1,3 +1,5 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(nightly, feature(error_generic_member_access, provide_any))] +#![cfg_attr(not(feature = "std"), feature(error_in_core))] mod error; diff --git a/tests/from.rs b/tests/from.rs index 12542210..f6b26c8e 100644 --- a/tests/from.rs +++ b/tests/from.rs @@ -1,5 +1,15 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] +#[cfg(not(feature = "std"))] +extern crate alloc; + +#[cfg(not(feature = "std"))] +use alloc::{ + borrow::Cow, + string::{String, ToString}, +}; +#[cfg(feature = "std")] use std::borrow::Cow; use derive_more::From; @@ -181,7 +191,7 @@ struct Name(String); fn explicit_complex_types_name() { let name = "EƤrendil"; let expected = Name(name.into()); - assert_eq!(expected, name.to_owned().into()); + assert_eq!(expected, name.to_string().into()); assert_eq!(expected, name.into()); assert_eq!(expected, Cow::Borrowed(name).into()); } diff --git a/tests/from_str.rs b/tests/from_str.rs index c336201d..64f2848c 100644 --- a/tests/from_str.rs +++ b/tests/from_str.rs @@ -1,5 +1,12 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] +#[cfg(not(feature = "std"))] +extern crate alloc; + +#[cfg(not(feature = "std"))] +use alloc::string::ToString; + use derive_more::FromStr; #[derive(FromStr)] diff --git a/tests/generics.rs b/tests/generics.rs index 89934e7a..039e8903 100644 --- a/tests/generics.rs +++ b/tests/generics.rs @@ -1,3 +1,4 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code, non_camel_case_types)] use derive_more::{ diff --git a/tests/index.rs b/tests/index.rs index 105e5892..b972388b 100644 --- a/tests/index.rs +++ b/tests/index.rs @@ -1,5 +1,12 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code, unused_imports)] +#[cfg(not(feature = "std"))] +extern crate alloc; + +#[cfg(not(feature = "std"))] +use alloc::vec::Vec; + use derive_more::Index; #[derive(Index)] diff --git a/tests/into.rs b/tests/into.rs index da632249..7328d3a4 100644 --- a/tests/into.rs +++ b/tests/into.rs @@ -1,5 +1,12 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] +#[cfg(not(feature = "std"))] +extern crate alloc; + +#[cfg(not(feature = "std"))] +use alloc::{borrow::Cow, string::String}; +#[cfg(feature = "std")] use std::borrow::Cow; use derive_more::Into; diff --git a/tests/into_iterator.rs b/tests/into_iterator.rs index a1bfb78d..7f9d6a36 100644 --- a/tests/into_iterator.rs +++ b/tests/into_iterator.rs @@ -1,5 +1,12 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code, unused_imports)] +#[cfg(not(feature = "std"))] +extern crate alloc; + +#[cfg(not(feature = "std"))] +use alloc::vec::Vec; + use derive_more::IntoIterator; #[derive(IntoIterator)] diff --git a/tests/is_variant.rs b/tests/is_variant.rs index d8f41ad3..e778ca47 100644 --- a/tests/is_variant.rs +++ b/tests/is_variant.rs @@ -1,3 +1,4 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] use derive_more::IsVariant; diff --git a/tests/lib.rs b/tests/lib.rs index 2c60dd8f..0a734ecc 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1,3 +1,5 @@ +#![cfg_attr(not(feature = "std"), no_std)] + use derive_more::{ Add, AddAssign, Binary, BitAnd, BitOr, BitXor, Constructor, Deref, DerefMut, Display, Div, From, FromStr, Index, IndexMut, Into, IntoIterator, Mul, MulAssign, diff --git a/tests/mul.rs b/tests/mul.rs index 1d71fd2e..706c3ec3 100644 --- a/tests/mul.rs +++ b/tests/mul.rs @@ -1,3 +1,4 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] use derive_more::Mul; diff --git a/tests/mul_assign.rs b/tests/mul_assign.rs index ce23362b..51087ac6 100644 --- a/tests/mul_assign.rs +++ b/tests/mul_assign.rs @@ -1,6 +1,7 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] -use std::marker::PhantomData; +use core::marker::PhantomData; use derive_more::MulAssign; diff --git a/tests/not.rs b/tests/not.rs index d822e74a..bb340fac 100644 --- a/tests/not.rs +++ b/tests/not.rs @@ -1,3 +1,4 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] use derive_more::Not; diff --git a/tests/sum.rs b/tests/sum.rs index 8a4e4e1d..d220fd5a 100644 --- a/tests/sum.rs +++ b/tests/sum.rs @@ -1,3 +1,5 @@ +#![cfg_attr(not(feature = "std"), no_std)] + use derive_more::Sum; #[derive(Sum)] diff --git a/tests/try_into.rs b/tests/try_into.rs index e88a1054..6d158ec5 100644 --- a/tests/try_into.rs +++ b/tests/try_into.rs @@ -1,5 +1,12 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] +#[cfg(not(feature = "std"))] +extern crate alloc; + +#[cfg(not(feature = "std"))] +use alloc::string::ToString; + use derive_more::TryInto; // Ensure that the `TryInto` macro is hygienic and doesn't break when `Result` diff --git a/tests/try_unwrap.rs b/tests/try_unwrap.rs index 2280bc8f..abcc9270 100644 --- a/tests/try_unwrap.rs +++ b/tests/try_unwrap.rs @@ -1,5 +1,12 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] +#[cfg(not(feature = "std"))] +extern crate alloc; + +#[cfg(not(feature = "std"))] +use alloc::string::ToString; + use derive_more::TryUnwrap; #[derive(TryUnwrap)] diff --git a/tests/unwrap.rs b/tests/unwrap.rs index a690d28b..dca8fc4c 100644 --- a/tests/unwrap.rs +++ b/tests/unwrap.rs @@ -1,3 +1,4 @@ +#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] use derive_more::Unwrap;