From 9bf1917ef67e6ea5ffe478338ed6913afe8ff212 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 11 Apr 2020 02:17:49 -0400 Subject: [PATCH] Properly handle `where` clauses on tuple structs Previously, we were generating the `where` clause in the wrong position for the generated projection struct, leading to a compilation error. --- .../src/pin_project/derive.rs | 16 ++++++++++++-- tests/project.rs | 21 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/pin-project-internal/src/pin_project/derive.rs b/pin-project-internal/src/pin_project/derive.rs index f00d888d..1ed1c569 100644 --- a/pin-project-internal/src/pin_project/derive.rs +++ b/pin-project-internal/src/pin_project/derive.rs @@ -261,12 +261,24 @@ impl Context { let proj_generics = &self.proj.generics; let where_clause = self.orig.generics.split_for_impl().2; + // For tuple structs, we need to generate `(T1, T2) where Foo: Bar` + // For non-tuple structs, we need to generate `where Foo: Bar { field1: T }` + let (where_clause_fields, where_clause_ref_fields) = match fields { + Fields::Named(_) => { + (quote!(#where_clause #proj_fields), quote!(#where_clause #proj_ref_fields)) + } + Fields::Unnamed(_) => { + (quote!(#proj_fields #where_clause), quote!(#proj_ref_fields #where_clause)) + } + Fields::Unit => unreachable!(), + }; + let mut proj_items = quote! { #[allow(clippy::mut_mut)] // This lint warns `&mut &mut `. #[allow(dead_code)] // This lint warns unused fields/variants. - #vis struct #proj_ident #proj_generics #where_clause #proj_fields + #vis struct #proj_ident #proj_generics #where_clause_fields #[allow(dead_code)] // This lint warns unused fields/variants. - #vis struct #proj_ref_ident #proj_generics #where_clause #proj_ref_fields + #vis struct #proj_ref_ident #proj_generics #where_clause_ref_fields }; let proj_body = quote! { diff --git a/tests/project.rs b/tests/project.rs index 6463ab57..b88ccd83 100644 --- a/tests/project.rs +++ b/tests/project.rs @@ -194,3 +194,24 @@ mod project_use_2 { fn project_use(self) {} } } + +#[pin_project] +struct StructWhereClause +where + T: Copy, +{ + field: T, +} + +#[pin_project] +struct TupleStructWhereClause(T) +where + T: Copy; + +#[pin_project] +enum EnumWhereClause +where + T: Copy, +{ + Variant(T), +}