Skip to content

Commit

Permalink
Rollup merge of #125987 - estebank:issue-122622, r=Nadrieril
Browse files Browse the repository at this point in the history
When `derive`ing, account for HRTB on `BareFn` fields

When given

```rust
trait SomeTrait {
    type SomeType<'a>;
}

#[derive(Clone)]
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.

<!--
If this PR is related to an unstable feature or an otherwise tracked effort,
please link to the relevant tracking issue here. If you don't know of a related
tracking issue or there are none, feel free to ignore this.

This PR will get automatically assigned to a reviewer. In case you would like
a specific user to review your work, you can assign it to them by using

    r​? <reviewer name>
-->
  • Loading branch information
matthiaskrgr authored Jun 5, 2024
2 parents a3a85f7 + e7ad2da commit 2519053
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
12 changes: 11 additions & 1 deletion compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,15 @@ fn find_type_parameters(

impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> {
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
&& let Some(segment) = path.segments.first()
&& self.ty_param_names.contains(&segment.ident.name)
Expand All @@ -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.
Expand Down
13 changes: 13 additions & 0 deletions tests/ui/derives/derive-hrtb-for-bare-fn-field-with-lifetime.rs
Original file line number Diff line number Diff line change
@@ -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() {}

0 comments on commit 2519053

Please sign in to comment.