From 8fd1663860183f0a18904e2aa535daa1bdbf55c5 Mon Sep 17 00:00:00 2001 From: Alec Mocatta Date: Mon, 21 Oct 2019 16:52:46 +0100 Subject: [PATCH 1/4] Add .editorconfig for tab_width = 4 --- .editorconfig | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6697b3e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +[*] +tab_width = 4 + +[.*] +tab_width = 4 From 5f552570bd43287f0747a9c2bfe7517872025fed Mon Sep 17 00:00:00 2001 From: alecmocatta Date: Tue, 5 Nov 2019 09:07:34 +0000 Subject: [PATCH 2/4] Add a static assertion that variables aren't nameable types and update docs --- README.md | 68 ++++++++++++++++-------------- serde_closure_derive/src/lib.rs | 9 ++-- src/lib.rs | 75 +++++++++++++++++++-------------- 3 files changed, 85 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index e19021d..3ccbd3f 100644 --- a/README.md +++ b/README.md @@ -86,44 +86,45 @@ FnMut!(move |name| { ## Limitations There are currently some minor limitations: - * Captured variables with an uppercase first letter need to be explicitly - captured. If you see a panic like the following, fix the case of the - variable. -```text -thread 'main' panicked at 'A variable with an upper case first letter was implicitly captured. -Unfortunately due to current limitations it must be captured explicitly. -Please refer to the README.', tests/test.rs:205:10 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. -``` - * Functions called inside the closure might need to be disambiguated. This - also affects enum unit and tuple variants with a lowercase first letter. - If you see an error like either of the following, qualify `my_function` - as `self::my_function` and `my_enum_variant` as - `MyEnum::my_enum_variant`. + + * Use of types that start with a lowercase letter need might need to be + disambiguated from variables. If you see an error like the following, fix the + case of the type, or append it with `my_struct::<>` to disambiguate. ```text -error[E0277]: the trait bound `fn(usize) -> std::option::Option {my_function::}: fnref::_IMPL_DESERIALIZE_FOR_Fn::_serde::Serialize` is not satisfied - --> tests/test.rs:327:10 +error[E0308]: mismatched types + --> tests/test.rs:450:4 + | +449 | FnOnce!(move || { + | _____- +450 | | my_struct; + | | ^^^^^^^^^ expected struct `serde_closure::internal::a_variable`, found struct `my_struct` +451 | | }); + | |______- in this macro invocation | -314 | fn unfold(initial_state: St, f: F) -> Unfold - | ------ -315 | where -316 | F: Fn(&mut St) -> Option + Serialize, - | --------- required by this bound in `fnref::unfold` -... -327 | let _ = unfold(0_usize, Fn!(|acc: &mut _| my_function(*acc))); - | ^^^^^^ the trait `fnref::_IMPL_DESERIALIZE_FOR_Fn::_serde::Serialize` is not implemented for `fn(usize) -> std::option::Option {my_function::}` + = note: expected type `serde_closure::internal::a_variable` + found type `my_struct` ``` + + * Use of variables that start with an uppercase letter might need to be + disambiguated from types. If you see an error like the following, fix the + case of the variable, or wrap it with `(MyVariable)` to disambiguate. ```text -error[E0530]: function parameters cannot shadow tuple variants - --> tests/test.rs:173:47 +error: imports cannot refer to local variables + --> tests/test.rs:422:3 + | +417 | FnOnce!(move || { + | _____- +418 | | MyVariable; + | | ^^^^^^^^^^ +419 | | }); + | |______- in this macro invocation | -173 | FnMut!(|acc: &mut _| my_enum_variant(*acc)) - | ---------------------^^^^^^^^^^^^^^^------- - | | | - | | cannot be named the same as a tuple variant - | in this macro invocation ``` + * Functions and closures called inside the closure might need to be + disambiguated. This can be done the same as above with `function::<>` for + functions and `(closure)` for closures. + ## Serializing between processes Closures created by this crate are unnameable – i.e. just like normal closures, @@ -140,7 +141,10 @@ processes running the same binary. For example, if you have multiple forks of a process, or the same binary running on each of a cluster of machines, [`serde_traitobject`](https://github.com/alecmocatta/serde_traitobject) would -help you to send serializable closures between them. +help you to send serializable closures between them. This can be done by +upcasting the closure to a `Box`, which is +automatically serializable and deserializable with +[`serde`](https://github.com/serde-rs/serde). ## License Licensed under either of diff --git a/serde_closure_derive/src/lib.rs b/serde_closure_derive/src/lib.rs index 50f7331..abe012e 100644 --- a/serde_closure_derive/src/lib.rs +++ b/serde_closure_derive/src/lib.rs @@ -404,6 +404,10 @@ fn impl_fn_once(closure: Closure, kind: Kind) -> Result { #fn_impl } + { + #(let #env_variables = ::serde_closure::internal::a_variable;)* + } + let mut #ret_name = #impls_name::#name::new(#env_capture); let #env_types_name = ::serde_closure::internal::to_phantom(&#ret_name); @@ -716,11 +720,10 @@ impl<'a> State<'a> { expr: Box::new(a), }); } else { - let mut path_segment: PathSegment = (*path_segment).clone(); - path_segment.arguments = PathArguments::None; + let ident = (*ident).clone(); *expr = parse2(quote_spanned! { expr.span() => ({ - use #path_segment; + use #ident; fn eq(a: T, b: T) -> T { a } eq(#expr, #expr) }) diff --git a/src/lib.rs b/src/lib.rs index 2a303e7..03b61f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -104,44 +104,45 @@ //! //! # Limitations //! There are currently some minor limitations: -//! * Captured variables with an uppercase first letter need to be explicitly -//! captured. If you see a panic like the following, fix the case of the -//! variable. -//! ```text -//! thread 'main' panicked at 'A variable with an upper case first letter was implicitly captured. -//! Unfortunately due to current limitations it must be captured explicitly. -//! Please refer to the README.', tests/test.rs:205:10 -//! note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. -//! ``` -//! * Functions called inside the closure might need to be disambiguated. This -//! also affects enum unit and tuple variants with a lowercase first letter. -//! If you see an error like either of the following, qualify `my_function` -//! as `self::my_function` and `my_enum_variant` as -//! `MyEnum::my_enum_variant`. +//! +//! * Use of types that start with a lowercase letter need might need to be +//! disambiguated from variables. If you see an error like the following, fix +//! the case of the type, or append it with `my_struct::<>` to disambiguate. //! ```text -//! error[E0277]: the trait bound `fn(usize) -> std::option::Option {my_function::}: fnref::_IMPL_DESERIALIZE_FOR_Fn::_serde::Serialize` is not satisfied -//! --> tests/test.rs:327:10 +//! error[E0308]: mismatched types +//! --> tests/test.rs:450:4 +//! | +//! 449 | FnOnce!(move || { +//! | _____- +//! 450 | | my_struct; +//! | | ^^^^^^^^^ expected struct `serde_closure::internal::a_variable`, found struct `my_struct` +//! 451 | | }); +//! | |______- in this macro invocation //! | -//! 314 | fn unfold(initial_state: St, f: F) -> Unfold -//! | ------ -//! 315 | where -//! 316 | F: Fn(&mut St) -> Option + Serialize, -//! | --------- required by this bound in `fnref::unfold` -//! ... -//! 327 | let _ = unfold(0_usize, Fn!(|acc: &mut _| my_function(*acc))); -//! | ^^^^^^ the trait `fnref::_IMPL_DESERIALIZE_FOR_Fn::_serde::Serialize` is not implemented for `fn(usize) -> std::option::Option {my_function::}` +//! = note: expected type `serde_closure::internal::a_variable` +//! found type `my_struct` //! ``` +//! +//! * Use of variables that start with an uppercase letter might need to be +//! disambiguated from types. If you see an error like the following, fix the +//! case of the variable, or wrap it with `(MyVariable)` to disambiguate. //! ```text -//! error[E0530]: function parameters cannot shadow tuple variants -//! --> tests/test.rs:173:47 +//! error: imports cannot refer to local variables +//! --> tests/test.rs:422:3 +//! | +//! 417 | FnOnce!(move || { +//! | _____- +//! 418 | | MyVariable; +//! | | ^^^^^^^^^^ +//! 419 | | }); +//! | |______- in this macro invocation //! | -//! 173 | FnMut!(|acc: &mut _| my_enum_variant(*acc)) -//! | ---------------------^^^^^^^^^^^^^^^------- -//! | | | -//! | | cannot be named the same as a tuple variant -//! | in this macro invocation //! ``` //! +//! * Functions and closures called inside the closure might need to be +//! disambiguated. This can be done the same as above with `function::<>` for +//! functions and `(closure)` for closures. +//! //! # Serializing between processes //! //! Closures created by this crate are unnameable – i.e. just like normal @@ -158,7 +159,10 @@ //! For example, if you have multiple forks of a process, or the same binary //! running on each of a cluster of machines, //! [`serde_traitobject`](https://github.com/alecmocatta/serde_traitobject) -//! would help you to send serializable closures between them. +//! would help you to send serializable closures between them. This can be done +//! by upcasting the closure to a `Box`, which is +//! automatically serializable and deserializable with +//! [`serde`](https://github.com/serde-rs/serde). #![doc(html_root_url = "https://docs.rs/serde_closure/0.2.5")] #![feature(unboxed_closures, fn_traits)] @@ -233,6 +237,13 @@ pub mod internal { #[allow(missing_copy_implementations, missing_debug_implementations)] pub struct ZeroSizedAssertion; + + #[allow( + missing_copy_implementations, + missing_debug_implementations, + non_camel_case_types + )] + pub struct a_variable; } pub mod structs { From 5b7be3e0765d0f0a6ccdd40d4daa3619c37de0f7 Mon Sep 17 00:00:00 2001 From: alecmocatta Date: Tue, 5 Nov 2019 09:08:32 +0000 Subject: [PATCH 3/4] v0.2.6 --- Cargo.toml | 6 +++--- README.md | 8 ++++---- serde_closure_derive/Cargo.toml | 4 ++-- serde_closure_derive/src/lib.rs | 2 +- src/lib.rs | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fa1a99f..178812d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "serde_closure" -version = "0.2.5" +version = "0.2.6" license = "MIT OR Apache-2.0" authors = ["Alec Mocatta "] categories = ["development-tools","encoding","rust-patterns","network-programming"] @@ -14,7 +14,7 @@ This library provides macros that wrap closures to make them serializable and de """ repository = "https://github.com/alecmocatta/serde_closure" homepage = "https://github.com/alecmocatta/serde_closure" -documentation = "https://docs.rs/serde_closure/0.2.5" +documentation = "https://docs.rs/serde_closure/0.2.6" readme = "README.md" edition = "2018" @@ -23,7 +23,7 @@ azure-devops = { project = "alecmocatta/serde_closure", pipeline = "tests" } maintenance = { status = "actively-developed" } [dependencies] -serde_closure_derive = { version = "=0.2.5", path = "serde_closure_derive" } +serde_closure_derive = { version = "=0.2.6", path = "serde_closure_derive" } serde = { version = "1.0", features = ["derive"] } proc-macro-hack = "0.5" diff --git a/README.md b/README.md index 3ccbd3f..c2d5727 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![MIT / Apache 2.0 licensed](https://img.shields.io/crates/l/serde_closure.svg?maxAge=2592000)](#License) [![Build Status](https://dev.azure.com/alecmocatta/serde_closure/_apis/build/status/tests?branchName=master)](https://dev.azure.com/alecmocatta/serde_closure/_build/latest?branchName=master) -[Docs](https://docs.rs/serde_closure/0.2.5) +[Docs](https://docs.rs/serde_closure/0.2.6) Serializable and debuggable closures. @@ -30,9 +30,9 @@ requires nightly Rust for the `unboxed_closures` and `fn_traits` features (rust issue [#29625](https://github.com/rust-lang/rust/issues/29625)). * There are three macros, - [`FnOnce`](https://docs.rs/serde_closure/0.2.5/serde_closure/macro.FnOnce.html), - [`FnMut`](https://docs.rs/serde_closure/0.2.5/serde_closure/macro.FnMut.html) - and [`Fn`](https://docs.rs/serde_closure/0.2.5/serde_closure/macro.Fn.html), + [`FnOnce`](https://docs.rs/serde_closure/0.2.6/serde_closure/macro.FnOnce.html), + [`FnMut`](https://docs.rs/serde_closure/0.2.6/serde_closure/macro.FnMut.html) + and [`Fn`](https://docs.rs/serde_closure/0.2.6/serde_closure/macro.Fn.html), corresponding to the three types of Rust closure. * Wrap your closure with one of the macros and it will now implement `Copy`, `Clone`, `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`, `Serialize`, diff --git a/serde_closure_derive/Cargo.toml b/serde_closure_derive/Cargo.toml index 723fd48..c5c2094 100644 --- a/serde_closure_derive/Cargo.toml +++ b/serde_closure_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_closure_derive" -version = "0.2.5" +version = "0.2.6" license = "MIT OR Apache-2.0" authors = ["Alec Mocatta "] categories = ["development-tools","encoding","rust-patterns","network-programming"] @@ -14,7 +14,7 @@ See https://crates.io/crates/serde_closure for documentation. """ repository = "https://github.com/alecmocatta/serde_closure" homepage = "https://github.com/alecmocatta/serde_closure" -documentation = "https://docs.rs/serde_closure/0.2.5" +documentation = "https://docs.rs/serde_closure/0.2.6" edition = "2018" [badges] diff --git a/serde_closure_derive/src/lib.rs b/serde_closure_derive/src/lib.rs index abe012e..d26b88b 100644 --- a/serde_closure_derive/src/lib.rs +++ b/serde_closure_derive/src/lib.rs @@ -9,7 +9,7 @@ //! See [`serde_closure`](https://docs.rs/serde_closure/) for //! documentation. -#![doc(html_root_url = "https://docs.rs/serde_closure_derive/0.2.5")] +#![doc(html_root_url = "https://docs.rs/serde_closure_derive/0.2.6")] #![feature(proc_macro_diagnostic)] #![allow(non_snake_case)] // due to proc-macro-hack can't apply this directly diff --git a/src/lib.rs b/src/lib.rs index 03b61f6..3d51693 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -164,7 +164,7 @@ //! automatically serializable and deserializable with //! [`serde`](https://github.com/serde-rs/serde). -#![doc(html_root_url = "https://docs.rs/serde_closure/0.2.5")] +#![doc(html_root_url = "https://docs.rs/serde_closure/0.2.6")] #![feature(unboxed_closures, fn_traits)] #![warn( missing_copy_implementations, From 06fbfb802fe32864e6fda10c0378320e0b3b9ea2 Mon Sep 17 00:00:00 2001 From: alecmocatta Date: Tue, 5 Nov 2019 09:09:34 +0000 Subject: [PATCH 4/4] typo --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 3d51693..a59a45e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -249,7 +249,7 @@ pub mod internal { pub mod structs { //! Structs representing a serializable closure, created by the //! [`FnOnce`](macro@FnOnce), [`FnMut`](macro@FnMut) and [`Fn`](macro@Fn) - //! macros. They Implement [`std::ops::FnOnce`], [`std::ops::FnMut`] and + //! macros. They implement [`std::ops::FnOnce`], [`std::ops::FnMut`] and //! [`std::ops::Fn`] respectively, as well as [`Debug`](std::fmt::Debug), //! [`Serialize`](serde::Serialize) and [`Deserialize`](serde::Deserialize), //! and various convenience traits.