9814: Generate default impl when converting `#[derive(Debug)]` to manual impl r=yoshuawuyts a=yoshuawuyts

This patch makes it so when you convert `#[derive(Debug)]` to a manual impl, a default body is provided that's equivalent to the original output of `#[derive(Debug)]`. This should make it drastically easier to write custom `Debug` impls, especially when all you want to do is quickly omit a single field which is `!Debug`.

This is implemented for enums, record structs, tuple structs, empty structs - and it sets us up to implement variations on this in the future for other traits (like `PartialEq` and `Hash`).

Thanks!

## Codegen diff
This is the difference in codegen for record structs with this patch:
```diff
struct Foo {
    bar: String,
}

impl fmt::Debug for Foo {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        todo!();
+        f.debug_struct("Foo").field("bar", &self.bar).finish()
    }
}
```

Co-authored-by: Irina Shestak <shestak.irina@gmail.com>
Co-authored-by: Yoshua Wuyts <yoshuawuyts@gmail.com>
Co-authored-by: Yoshua Wuyts <yoshuawuyts+github@gmail.com>
This commit is contained in:
bors[bot] 2021-08-08 22:30:37 +00:00 committed by GitHub
commit 5664a2b0b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 210 additions and 29 deletions

View file

@ -311,6 +311,9 @@ pub fn expr_method_call(
) -> ast::Expr {
expr_from_text(&format!("{}.{}{}", receiver, method, arg_list))
}
pub fn expr_macro_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr {
expr_from_text(&format!("{}!{}", f, arg_list))
}
pub fn expr_ref(expr: ast::Expr, exclusive: bool) -> ast::Expr {
expr_from_text(&if exclusive { format!("&mut {}", expr) } else { format!("&{}", expr) })
}
@ -318,6 +321,9 @@ pub fn expr_closure(pats: impl IntoIterator<Item = ast::Param>, expr: ast::Expr)
let params = pats.into_iter().join(", ");
expr_from_text(&format!("|{}| {}", params, expr))
}
pub fn expr_field(receiver: ast::Expr, field: &str) -> ast::Expr {
expr_from_text(&format!("{}.{}", receiver, field))
}
pub fn expr_paren(expr: ast::Expr) -> ast::Expr {
expr_from_text(&format!("({})", expr))
}