When derive
ing, account for HRTB on BareFn
fields
When given ```rust trait SomeTrait { type SomeType<'a>; } struct Foo<T: SomeTrait> { x: for<'a> fn(T::SomeType<'a>) } ``` expand to ```rust impl<T: ::core::clone::Clone + SomeTrait> ::core::clone::Clone for Foo<T> where for<'a> T::SomeType<'a>: ::core::clone::Clone { #[inline] fn clone(&self) -> Foo<T> { Foo { x: ::core::clone::Clone::clone(&self.x) } } } ``` instead of the previous invalid ``` impl<T: ::core::clone::Clone + SomeTrait> ::core::clone::Clone for Foo<T> where T::SomeType<'a>: ::core::clone::Clone { #[inline] fn clone(&self) -> Foo<T> { Foo { x: ::core::clone::Clone::clone(&self.x) } } } ``` Fix #122622.
This commit is contained in:
parent
8c4db851a7
commit
e7ad2da7f1
2 changed files with 24 additions and 1 deletions
|
@ -412,6 +412,15 @@ fn find_type_parameters(
|
||||||
|
|
||||||
impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> {
|
impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> {
|
||||||
fn visit_ty(&mut self, ty: &'a ast::Ty) {
|
fn visit_ty(&mut self, ty: &'a ast::Ty) {
|
||||||
|
let stack_len = self.bound_generic_params_stack.len();
|
||||||
|
if let ast::TyKind::BareFn(bare_fn) = &ty.kind
|
||||||
|
&& !bare_fn.generic_params.is_empty()
|
||||||
|
{
|
||||||
|
// Given a field `x: for<'a> fn(T::SomeType<'a>)`, we wan't to account for `'a` so
|
||||||
|
// that we generate `where for<'a> T::SomeType<'a>: ::core::clone::Clone`. #122622
|
||||||
|
self.bound_generic_params_stack.extend(bare_fn.generic_params.iter().cloned());
|
||||||
|
}
|
||||||
|
|
||||||
if let ast::TyKind::Path(_, path) = &ty.kind
|
if let ast::TyKind::Path(_, path) = &ty.kind
|
||||||
&& let Some(segment) = path.segments.first()
|
&& let Some(segment) = path.segments.first()
|
||||||
&& self.ty_param_names.contains(&segment.ident.name)
|
&& self.ty_param_names.contains(&segment.ident.name)
|
||||||
|
@ -422,7 +431,8 @@ fn find_type_parameters(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
visit::walk_ty(self, ty)
|
visit::walk_ty(self, ty);
|
||||||
|
self.bound_generic_params_stack.truncate(stack_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Place bound generic params on a stack, to extract them when a type is encountered.
|
// Place bound generic params on a stack, to extract them when a type is encountered.
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
//@ run-pass
|
||||||
|
// Issue #122622: `#[derive(Clone)]` should work for HRTB function type taking an associated type
|
||||||
|
#![allow(dead_code)]
|
||||||
|
trait SomeTrait {
|
||||||
|
type SomeType<'a>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Foo<T: SomeTrait> {
|
||||||
|
x: for<'a> fn(T::SomeType<'a>)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Reference in a new issue