How to skip fields in a Display implementation?

I wish to skip certain fields when using the Display format to print it. As a test, I tried the main.rs program below:

// fmt
use std::fmt;

// Point2D
#[derive(Debug)]
struct Point2D {
    x: f64,
    y: f64,
}

// Display for Point2D.
impl fmt::Display for Point2D {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Customize so only x is displayed
        write!(f, "x: {}", self.x)
    }
}

// main
fn main() {
    let point = Point2D { x: 3.3, y: 7.2 };
    println!("Display: {}", point);
    println!("Debug: {:?}", point);
}

The output after Display below is what I am trying to get. Even though y is used by the Debug print, the program above gives a warning about y not being used. How should one display a subset of the fields in a structure ?

   Compiling cargo_test v0.1.0 (/Users/bradbell/trash/rust/cargo_test)
warning: field `y` is never read
 --> src/main.rs:8:5
  |
6 | struct Point2D {
  |        ------- field in this struct
7 |     x: f64,
8 |     y: f64,
  |     ^
  |
  = note: `Point2D` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
  = note: `#[warn(dead_code)]` on by default

warning: `cargo_test` (bin "cargo_test") generated 1 warning
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.55s
     Running `target/debug/cargo_test`
Display: x: 3.3
Debug: Point2D { x: 3.3, y: 7.2 }

There is nothing wrong with your Display implementation.

The warning is telling you that the y field is not being used anywhere “for real”. The Debug implementation doesn’t count as a usage, because Debug is for debugging (there are compilation options where Debug prints nothing) and if it counted, you'd rarely be warned about any unused fields since standard practice is to derive(Debug) on almost everything.

The warning will go away once your program makes real, non-debugging use of the y field anywhere in it.

3 Likes

As long as you use this field somewhere else, this warning would not be shown. And if it is used only in Debug, then why is it there at all?

Just to avoid falling into an X-Y situation from you or from future people coming from a search result, if you are asking this because you have structs with fields with sensitive information, what I would do in this case is to create an ad-hoc dto type without such fields and write the corresponding From trait implementation, besides creating newtypes for the sensitive information and using a library to do the implementations of debug and print such as secrecy.