From f42738a9b69fa2a0ca57417e9ce43707017b90cf Mon Sep 17 00:00:00 2001 From: MegaBluejay Date: Tue, 8 Aug 2023 16:25:30 +0300 Subject: [PATCH 01/11] Limit trait bounds in derived IntoIterator to actually required ones --- impl/src/into_iterator.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/impl/src/into_iterator.rs b/impl/src/into_iterator.rs index f10dbf7a..243e8346 100644 --- a/impl/src/into_iterator.rs +++ b/impl/src/into_iterator.rs @@ -1,5 +1,5 @@ use crate::utils::{ - add_extra_generic_param, add_extra_ty_param_bound_ref, SingleFieldData, State, + add_extra_generic_param, add_extra_where_clauses, SingleFieldData, State, }; use proc_macro2::TokenStream; use quote::{quote, ToTokens}; @@ -26,16 +26,19 @@ pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result }; From 8fe540f988307324e89dd2bccfe3f1b5de547ae4 Mon Sep 17 00:00:00 2001 From: MegaBluejay Date: Tue, 8 Aug 2023 16:26:15 +0300 Subject: [PATCH 02/11] Remove unused add_extra_ty_param_bound_ref function --- impl/src/utils.rs | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/impl/src/utils.rs b/impl/src/utils.rs index 9523591b..32e12bac 100644 --- a/impl/src/utils.rs +++ b/impl/src/utils.rs @@ -152,27 +152,6 @@ pub fn add_extra_ty_param_bound<'a>( generics } -pub fn add_extra_ty_param_bound_ref<'a>( - generics: &'a Generics, - bound: &'a TokenStream, - ref_type: RefType, -) -> Generics { - match ref_type { - RefType::No => add_extra_ty_param_bound(generics, bound), - _ => { - let generics = generics.clone(); - let idents = generics.type_params().map(|x| &x.ident); - let ref_with_lifetime = ref_type.reference_with_lifetime(); - add_extra_where_clauses( - &generics, - quote! { - where #(#ref_with_lifetime #idents: #bound),* - }, - ) - } - } -} - pub fn add_extra_generic_param( generics: &Generics, generic_param: TokenStream, From 88ae590b1a209a564b74552345e790b85ccf7f1e Mon Sep 17 00:00:00 2001 From: MegaBluejay Date: Tue, 8 Aug 2023 16:35:54 +0300 Subject: [PATCH 03/11] Add tests for generic IntoIterator derives --- tests/into_iterator.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/into_iterator.rs b/tests/into_iterator.rs index 7f9d6a36..8c78f242 100644 --- a/tests/into_iterator.rs +++ b/tests/into_iterator.rs @@ -45,3 +45,22 @@ impl ::core::iter::IntoIterator for Numbers3 { as ::core::iter::IntoIterator>::into_iter(self.numbers) } } + +#[derive(IntoIterator)] +struct Generic1 { + #[into_iterator(owned, ref, ref_mut)] + items: Vec, +} + +#[derive(IntoIterator)] +struct Generic2<'a, T, U> { + #[into_iterator(owned, ref, ref_mut)] + items: Vec, + useless: &'a U, +} + +#[derive(IntoIterator)] +struct Generic3<'a, 'b, T> { + #[into_iterator(owned, ref, ref_mut)] + items: &'a mut Vec<&'b mut T>, +} From b8cef6f21615df97ce32a1ff71d016493fccf3ef Mon Sep 17 00:00:00 2001 From: MegaBluejay Date: Tue, 8 Aug 2023 16:46:25 +0300 Subject: [PATCH 04/11] Add changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16795055..353d2212 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fix `Error` derive not working with `const` generics. - Support trait objects for source in Error, e.g. `Box` +- Fix bounds on derived `IntoIterator` impls for generic structs + ([#284](https://github.com/JelteF/derive_more/pull/284)) ## 0.99.10 - 2020-09-11 From 7acdaf3c8f74d9c88b65292a0b3271063ae4ec67 Mon Sep 17 00:00:00 2001 From: MegaBluejay Date: Tue, 8 Aug 2023 21:27:41 +0300 Subject: [PATCH 05/11] Improve generic IntoIterator test --- tests/into_iterator.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/into_iterator.rs b/tests/into_iterator.rs index 8c78f242..0beccdaf 100644 --- a/tests/into_iterator.rs +++ b/tests/into_iterator.rs @@ -53,7 +53,10 @@ struct Generic1 { } #[derive(IntoIterator)] -struct Generic2<'a, T, U> { +struct Generic2<'a, T, U: Send> +where + T: Send, +{ #[into_iterator(owned, ref, ref_mut)] items: Vec, useless: &'a U, From e6b9e4a6b580b14092df8ec0446debe17b9f75c1 Mon Sep 17 00:00:00 2001 From: MegaBluejay Date: Thu, 10 Aug 2023 15:33:03 +0300 Subject: [PATCH 06/11] Add value tests for IntoIterator --- tests/into_iterator.rs | 87 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/tests/into_iterator.rs b/tests/into_iterator.rs index 0beccdaf..991e593b 100644 --- a/tests/into_iterator.rs +++ b/tests/into_iterator.rs @@ -7,18 +7,56 @@ extern crate alloc; #[cfg(not(feature = "std"))] use alloc::vec::Vec; +use std::fmt::Debug; + use derive_more::IntoIterator; +fn test_into_iter>( + iter: I, + vals: &[T], +) { + assert_eq!(iter.into_iter().collect::>(), vals); +} + +fn test_into_iter_all(mut iter: I, mut vals: Vec) +where + T: PartialEq + Debug, + I: IntoIterator, + for<'a> &'a I: IntoIterator, + for<'a> &'a mut I: IntoIterator, +{ + test_into_iter(&mut iter, &vals.iter_mut().collect::>()); + test_into_iter(&iter, &vals.iter().collect::>()); + test_into_iter(iter, &vals); +} + #[derive(IntoIterator)] #[into_iterator(owned, ref, ref_mut)] struct MyVec(Vec); +#[test] +fn tuple_single() { + let numbers = vec![1, 2, 3]; + test_into_iter_all(MyVec(numbers.clone()), numbers); +} + #[derive(IntoIterator)] #[into_iterator(owned, ref, ref_mut)] struct Numbers { numbers: Vec, } +#[test] +fn named_single() { + let numbers = vec![1, 2, 3]; + test_into_iter_all( + Numbers { + numbers: numbers.clone(), + }, + numbers, + ); +} + #[derive(IntoIterator)] struct Numbers2 { #[into_iterator(owned, ref, ref_mut)] @@ -27,6 +65,18 @@ struct Numbers2 { useless2: bool, } +fn named_many() { + let numbers = vec![1, 2, 3]; + test_into_iter_all( + Numbers2 { + numbers: numbers.clone(), + useless: true, + useless2: true, + }, + numbers, + ); +} + #[derive(IntoIterator)] struct Numbers3 { #[into_iterator(ref, ref_mut)] @@ -52,6 +102,17 @@ struct Generic1 { items: Vec, } +#[test] +fn generic() { + let numbers = vec![1, 2, 3]; + test_into_iter_all( + Generic1 { + items: numbers.clone(), + }, + numbers, + ); +} + #[derive(IntoIterator)] struct Generic2<'a, T, U: Send> where @@ -62,8 +123,30 @@ where useless: &'a U, } +#[test] +fn generic_bounds() { + let numbers = vec![1, 2, 3]; + let useless = false; + test_into_iter_all( + Generic2 { + items: numbers.clone(), + useless: &useless, + }, + numbers, + ); +} + #[derive(IntoIterator)] -struct Generic3<'a, 'b, T> { +struct Generic3<'a, T> { #[into_iterator(owned, ref, ref_mut)] - items: &'a mut Vec<&'b mut T>, + items: Vec<&'a mut T>, +} + +#[test] +fn generic_refs() { + let mut numbers = vec![1, 2, 3]; + let mut numbers2 = numbers.clone(); + let number_refs = numbers.iter_mut().collect::>(); + let number_refs2 = numbers2.iter_mut().collect::>(); + test_into_iter_all(Generic3 { items: number_refs }, number_refs2); } From d1f0d8db11e20a5d35f1e4c93c9aba8626c6d0fa Mon Sep 17 00:00:00 2001 From: MegaBluejay Date: Thu, 10 Aug 2023 15:38:19 +0300 Subject: [PATCH 07/11] Add test for automatic owned only generic IntoIterator --- tests/into_iterator.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/into_iterator.rs b/tests/into_iterator.rs index 991e593b..8e24a063 100644 --- a/tests/into_iterator.rs +++ b/tests/into_iterator.rs @@ -150,3 +150,22 @@ fn generic_refs() { let number_refs2 = numbers2.iter_mut().collect::>(); test_into_iter_all(Generic3 { items: number_refs }, number_refs2); } + +#[derive(IntoIterator)] +struct Generic4 { + #[into_iterator] + items: Vec, + useless: bool, +} + +#[test] +fn generic_owned() { + let numbers = vec![1, 2, 3]; + test_into_iter( + Generic4 { + items: numbers.clone(), + useless: true, + }, + &numbers, + ); +} From b319608c8d72046bc98167b50261f2af27dfb0c7 Mon Sep 17 00:00:00 2001 From: MegaBluejay Date: Thu, 10 Aug 2023 15:44:03 +0300 Subject: [PATCH 08/11] Better formatting in tests --- tests/into_iterator.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/into_iterator.rs b/tests/into_iterator.rs index 8e24a063..667e9a9c 100644 --- a/tests/into_iterator.rs +++ b/tests/into_iterator.rs @@ -37,6 +37,7 @@ struct MyVec(Vec); #[test] fn tuple_single() { let numbers = vec![1, 2, 3]; + test_into_iter_all(MyVec(numbers.clone()), numbers); } @@ -49,6 +50,7 @@ struct Numbers { #[test] fn named_single() { let numbers = vec![1, 2, 3]; + test_into_iter_all( Numbers { numbers: numbers.clone(), @@ -67,6 +69,7 @@ struct Numbers2 { fn named_many() { let numbers = vec![1, 2, 3]; + test_into_iter_all( Numbers2 { numbers: numbers.clone(), @@ -105,6 +108,7 @@ struct Generic1 { #[test] fn generic() { let numbers = vec![1, 2, 3]; + test_into_iter_all( Generic1 { items: numbers.clone(), @@ -127,6 +131,7 @@ where fn generic_bounds() { let numbers = vec![1, 2, 3]; let useless = false; + test_into_iter_all( Generic2 { items: numbers.clone(), @@ -146,8 +151,10 @@ struct Generic3<'a, T> { fn generic_refs() { let mut numbers = vec![1, 2, 3]; let mut numbers2 = numbers.clone(); + let number_refs = numbers.iter_mut().collect::>(); let number_refs2 = numbers2.iter_mut().collect::>(); + test_into_iter_all(Generic3 { items: number_refs }, number_refs2); } @@ -161,6 +168,7 @@ struct Generic4 { #[test] fn generic_owned() { let numbers = vec![1, 2, 3]; + test_into_iter( Generic4 { items: numbers.clone(), From 4d24ae97cda80fcdc22001bf25a69f44620daa95 Mon Sep 17 00:00:00 2001 From: MegaBluejay Date: Thu, 10 Aug 2023 15:51:54 +0300 Subject: [PATCH 09/11] Improve generic_refs test --- tests/into_iterator.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/into_iterator.rs b/tests/into_iterator.rs index 667e9a9c..5eec936b 100644 --- a/tests/into_iterator.rs +++ b/tests/into_iterator.rs @@ -142,9 +142,9 @@ fn generic_bounds() { } #[derive(IntoIterator)] -struct Generic3<'a, T> { - #[into_iterator(owned, ref, ref_mut)] - items: Vec<&'a mut T>, +struct Generic3<'a, 'b, T> { + #[into_iterator(owned)] + items: &'a mut Vec<&'b mut T>, } #[test] @@ -152,10 +152,15 @@ fn generic_refs() { let mut numbers = vec![1, 2, 3]; let mut numbers2 = numbers.clone(); - let number_refs = numbers.iter_mut().collect::>(); - let number_refs2 = numbers2.iter_mut().collect::>(); + let mut number_refs = numbers.iter_mut().collect::>(); + let mut number_refs2 = numbers2.iter_mut().collect::>(); - test_into_iter_all(Generic3 { items: number_refs }, number_refs2); + test_into_iter( + Generic3 { + items: &mut number_refs, + }, + &number_refs2.iter_mut().collect::>(), + ) } #[derive(IntoIterator)] From 5bb32558c615ba07985244070114945a4970c8ac Mon Sep 17 00:00:00 2001 From: MegaBluejay Date: Thu, 10 Aug 2023 19:41:55 +0300 Subject: [PATCH 10/11] Fix IntoIterator tests with no_std --- tests/into_iterator.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/into_iterator.rs b/tests/into_iterator.rs index 5eec936b..e1d8719d 100644 --- a/tests/into_iterator.rs +++ b/tests/into_iterator.rs @@ -2,12 +2,13 @@ #![allow(dead_code, unused_imports)] #[cfg(not(feature = "std"))] +#[macro_use] extern crate alloc; #[cfg(not(feature = "std"))] use alloc::vec::Vec; -use std::fmt::Debug; +use core::fmt::Debug; use derive_more::IntoIterator; From 5e3bdd73dc9c8dcbe6337c38133d8059824d6a47 Mon Sep 17 00:00:00 2001 From: tyranron Date: Fri, 11 Aug 2023 13:07:26 +0300 Subject: [PATCH 11/11] Corrections --- CHANGELOG.md | 2 +- tests/into_iterator.rs | 92 ++++++++++++++++++------------------------ 2 files changed, 41 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 353d2212..694012e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,7 +72,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fix `Error` derive not working with `const` generics. - Support trait objects for source in Error, e.g. `Box` -- Fix bounds on derived `IntoIterator` impls for generic structs +- Fix bounds on derived `IntoIterator` impls for generic structs. ([#284](https://github.com/JelteF/derive_more/pull/284)) ## 0.99.10 - 2020-09-11 diff --git a/tests/into_iterator.rs b/tests/into_iterator.rs index e1d8719d..6458ec12 100644 --- a/tests/into_iterator.rs +++ b/tests/into_iterator.rs @@ -7,39 +7,27 @@ extern crate alloc; #[cfg(not(feature = "std"))] use alloc::vec::Vec; - use core::fmt::Debug; use derive_more::IntoIterator; -fn test_into_iter>( - iter: I, - vals: &[T], -) { +#[track_caller] +fn assert_iter>(iter: I, vals: &[T]) { assert_eq!(iter.into_iter().collect::>(), vals); } -fn test_into_iter_all(mut iter: I, mut vals: Vec) -where - T: PartialEq + Debug, - I: IntoIterator, - for<'a> &'a I: IntoIterator, - for<'a> &'a mut I: IntoIterator, -{ - test_into_iter(&mut iter, &vals.iter_mut().collect::>()); - test_into_iter(&iter, &vals.iter().collect::>()); - test_into_iter(iter, &vals); -} - #[derive(IntoIterator)] #[into_iterator(owned, ref, ref_mut)] struct MyVec(Vec); #[test] fn tuple_single() { - let numbers = vec![1, 2, 3]; + let mut vals = vec![1, 2, 3]; + let mut iter = MyVec(vals.clone()); - test_into_iter_all(MyVec(numbers.clone()), numbers); + assert_iter(&mut iter, &vals.iter_mut().collect::>()); + assert_iter(&iter, &vals.iter().collect::>()); + assert_iter(iter, &vals); } #[derive(IntoIterator)] @@ -50,14 +38,14 @@ struct Numbers { #[test] fn named_single() { - let numbers = vec![1, 2, 3]; + let mut vals = vec![1, 2, 3]; + let mut iter = Numbers { + numbers: vals.clone(), + }; - test_into_iter_all( - Numbers { - numbers: numbers.clone(), - }, - numbers, - ); + assert_iter(&mut iter, &vals.iter_mut().collect::>()); + assert_iter(&iter, &vals.iter().collect::>()); + assert_iter(iter, &vals); } #[derive(IntoIterator)] @@ -69,16 +57,16 @@ struct Numbers2 { } fn named_many() { - let numbers = vec![1, 2, 3]; + let mut vals = vec![1, 2, 3]; + let mut iter = Numbers2 { + numbers: vals.clone(), + useless: true, + useless2: true, + }; - test_into_iter_all( - Numbers2 { - numbers: numbers.clone(), - useless: true, - useless2: true, - }, - numbers, - ); + assert_iter(&mut iter, &vals.iter_mut().collect::>()); + assert_iter(&iter, &vals.iter().collect::>()); + assert_iter(iter, &vals); } #[derive(IntoIterator)] @@ -108,14 +96,14 @@ struct Generic1 { #[test] fn generic() { - let numbers = vec![1, 2, 3]; + let mut vals = vec![1, 2, 3]; + let mut iter = Generic1 { + items: vals.clone(), + }; - test_into_iter_all( - Generic1 { - items: numbers.clone(), - }, - numbers, - ); + assert_iter(&mut iter, &vals.iter_mut().collect::>()); + assert_iter(&iter, &vals.iter().collect::>()); + assert_iter(iter, &vals); } #[derive(IntoIterator)] @@ -130,16 +118,16 @@ where #[test] fn generic_bounds() { - let numbers = vec![1, 2, 3]; + let mut vals = vec![1, 2, 3]; let useless = false; + let mut iter = Generic2 { + items: vals.clone(), + useless: &useless, + }; - test_into_iter_all( - Generic2 { - items: numbers.clone(), - useless: &useless, - }, - numbers, - ); + assert_iter(&mut iter, &vals.iter_mut().collect::>()); + assert_iter(&iter, &vals.iter().collect::>()); + assert_iter(iter, &vals); } #[derive(IntoIterator)] @@ -156,7 +144,7 @@ fn generic_refs() { let mut number_refs = numbers.iter_mut().collect::>(); let mut number_refs2 = numbers2.iter_mut().collect::>(); - test_into_iter( + assert_iter( Generic3 { items: &mut number_refs, }, @@ -175,7 +163,7 @@ struct Generic4 { fn generic_owned() { let numbers = vec![1, 2, 3]; - test_into_iter( + assert_iter( Generic4 { items: numbers.clone(), useless: true,