@@ -122,7 +122,7 @@ fn transform_item(item: &TraitItem, bounds: &Vec<TypeParamBound>) -> TraitItem {
122
122
let TraitItem :: Fn ( fn_item @ TraitItemFn { sig, .. } ) = item else {
123
123
return item. clone ( ) ;
124
124
} ;
125
- let ( arrow, output) = if sig. asyncness . is_some ( ) {
125
+ let ( arrow, output, generics , default ) = if sig. asyncness . is_some ( ) {
126
126
let orig = match & sig. output {
127
127
ReturnType :: Default => quote ! { ( ) } ,
128
128
ReturnType :: Type ( _, ty) => quote ! { #ty } ,
@@ -134,7 +134,24 @@ fn transform_item(item: &TraitItem, bounds: &Vec<TypeParamBound>) -> TraitItem {
134
134
. chain ( bounds. iter ( ) . cloned ( ) )
135
135
. collect ( ) ,
136
136
} ) ;
137
- ( syn:: parse2 ( quote ! { -> } ) . unwrap ( ) , ty)
137
+ let mut generics = fn_item. sig . generics . clone ( ) ;
138
+ if fn_item. default . is_some ( ) {
139
+ if let Some ( wh) = & mut generics. where_clause {
140
+ wh. predicates
141
+ . push ( syn:: parse2 ( quote ! { Self : Sync } ) . unwrap ( ) ) ;
142
+ } else {
143
+ generics. where_clause = Some ( syn:: parse2 ( quote ! { where Self : Sync } ) . unwrap ( ) )
144
+ }
145
+ }
146
+ (
147
+ syn:: parse2 ( quote ! { -> } ) . unwrap ( ) ,
148
+ ty,
149
+ generics,
150
+ fn_item
151
+ . default
152
+ . as_ref ( )
153
+ . map ( |b| syn:: parse2 ( quote ! { { async move #b } } ) . unwrap ( ) ) ,
154
+ )
138
155
} else {
139
156
match & sig. output {
140
157
ReturnType :: Type ( arrow, ty) => match & * * ty {
@@ -143,7 +160,12 @@ fn transform_item(item: &TraitItem, bounds: &Vec<TypeParamBound>) -> TraitItem {
143
160
impl_token : it. impl_token ,
144
161
bounds : it. bounds . iter ( ) . chain ( bounds) . cloned ( ) . collect ( ) ,
145
162
} ) ;
146
- ( * arrow, ty)
163
+ (
164
+ * arrow,
165
+ ty,
166
+ fn_item. sig . generics . clone ( ) ,
167
+ fn_item. default . clone ( ) ,
168
+ )
147
169
}
148
170
_ => return item. clone ( ) ,
149
171
} ,
@@ -154,8 +176,10 @@ fn transform_item(item: &TraitItem, bounds: &Vec<TypeParamBound>) -> TraitItem {
154
176
sig : Signature {
155
177
asyncness : None ,
156
178
output : ReturnType :: Type ( arrow, Box :: new ( output) ) ,
179
+ generics,
157
180
..sig. clone ( )
158
181
} ,
182
+ default,
159
183
..fn_item. clone ( )
160
184
} )
161
185
}
@@ -164,8 +188,24 @@ fn mk_blanket_impl(attrs: &Attrs, tr: &ItemTrait) -> TokenStream {
164
188
let orig = & tr. ident ;
165
189
let variant = & attrs. variant . name ;
166
190
let items = tr. items . iter ( ) . map ( |item| blanket_impl_item ( item, variant) ) ;
191
+ // if there is a defaulted method, than that defaulted method has a bound of Self: Sync,
192
+ // which means the blanket impl must also require T: Sync
193
+ let self_is_sync = tr
194
+ . items
195
+ . iter ( )
196
+ . any ( |item| {
197
+ matches ! (
198
+ item,
199
+ TraitItem :: Fn ( TraitItemFn {
200
+ default : Some ( _) ,
201
+ ..
202
+ } )
203
+ )
204
+ } )
205
+ . then ( || quote ! { T : Sync } )
206
+ . unwrap_or_default ( ) ;
167
207
quote ! {
168
- impl <T > #orig for T where T : #variant {
208
+ impl <T > #orig for T where T : #variant, #self_is_sync {
169
209
#( #items) *
170
210
}
171
211
}
0 commit comments