Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve derive(Debug) #98190

Merged
merged 3 commits into from
Jun 26, 2022
Merged

Commits on Jun 23, 2022

  1. Rename some ExtCtxt methods.

    The new names are more accurate.
    
    Co-authored-by: Scott McMurray <scottmcm@users.noreply.github.com>
    nnethercote and scottmcm committed Jun 23, 2022
    Configuration menu
    Copy the full SHA
    7586e79 View commit details
    Browse the repository at this point in the history
  2. Optimize the code produced by derive(Debug).

    This commit adds new methods that combine sequences of existing
    formatting methods.
    - `Formatter::debug_{tuple,struct}_field[12345]_finish`, equivalent to a
      `Formatter::debug_{tuple,struct}` + N x `Debug{Tuple,Struct}::field` +
      `Debug{Tuple,Struct}::finish` call sequence.
    - `Formatter::debug_{tuple,struct}_fields_finish` is similar, but can
      handle any number of fields by using arrays.
    
    These new methods are all marked as `doc(hidden)` and unstable. They are
    intended for the compiler's own use.
    
    Special-casing up to 5 fields gives significantly better performance
    results than always using arrays (as was tried in rust-lang#95637).
    
    The commit also changes the `Debug` deriving code to use these new methods. For
    example, where the old `Debug` code for a struct with two fields would be like
    this:
    ```
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match *self {
    	Self {
    	    f1: ref __self_0_0,
    	    f2: ref __self_0_1,
    	} => {
    	    let debug_trait_builder = &mut ::core::fmt::Formatter::debug_struct(f, "S2");
    	    let _ = ::core::fmt::DebugStruct::field(debug_trait_builder, "f1", &&(*__self_0_0));
    	    let _ = ::core::fmt::DebugStruct::field(debug_trait_builder, "f2", &&(*__self_0_1));
    	    ::core::fmt::DebugStruct::finish(debug_trait_builder)
    	}
        }
    }
    ```
    the new code is like this:
    ```
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match *self {
    	Self {
    	    f1: ref __self_0_0,
    	    f2: ref __self_0_1,
    	} => ::core::fmt::Formatter::debug_struct_field2_finish(
    	    f,
    	    "S2",
    	    "f1",
    	    &&(*__self_0_0),
    	    "f2",
    	    &&(*__self_0_1),
    	),
        }
    }
    ```
    This shrinks the code produced for `Debug` instances
    considerably, reducing compile times and binary sizes.
    
    Co-authored-by: Scott McMurray <scottmcm@users.noreply.github.com>
    nnethercote and scottmcm committed Jun 23, 2022
    Configuration menu
    Copy the full SHA
    5b54363 View commit details
    Browse the repository at this point in the history
  3. Rewrite TyKind::fmt.

    The handwritten versions more compact and easier to read than the
    derived version.
    nnethercote committed Jun 23, 2022
    Configuration menu
    Copy the full SHA
    20f0cda View commit details
    Browse the repository at this point in the history