如何忽略`#[derive(Debug)]` 的通用参数?

How to ignore generic argument for `#[derive(Debug)]`?

这是代表我 运行 遇到的问题类型的最小值 example

use core::fmt::Debug;

pub trait Config {
    type A: Debug;
}

#[derive(Debug)]
pub struct Info<T: Config> {
    pub field: T::A,
}

pub struct Conf;

impl Config for Conf {
    type A = i128;
}

fn main() {
    let s = Info::<Conf> {
        field: 123
    };
    dbg!(s);
}

我正在使用的框架 (Substrate) 使用了 Config 特性的概念,它聚合了模块(托盘)的所有通用类型。

问题是尝试 #[derive(Debug)] 只使用对象关联类型的结构 T 实现 Config 仍然需要 T 实现 Debug本身。

error[E0277]: `Conf` doesn't implement `Debug`
  --> src/main.rs:22:5
   |
22 |     dbg!(s);
   |     ^^^^^^^ `Conf` cannot be formatted using `{:?}`
   |
   = help: the trait `Debug` is not implemented for `Conf`
   = note: add `#[derive(Debug)]` to `Conf` or manually `impl Debug for Conf`

此外,我无法控制 Conf 对象的实现。无论如何,我不会尝试打印任何关于 Conf 对象本身的信息。

有没有办法让 Info#[derive(Debug)] 忽略 T

不幸的是,不是今天。您必须手动实施 Debug

impl<T: Config> fmt::Debug for Info<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Info").field("field", &self.field).finish()
    }
}

有意使创建所谓的“完美派生”成为可能:根据需要而不是通用参数派生边界。参见示例 this lang team design meeting proposal。但是现在什么都没有。