Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upAuto-impl `Debug` for all types when needed #2207
Comments
prasannavl
changed the title
Analysis based auto-impl of `Debug` for all types
Auto-impl `Debug` for all types when needed
Nov 4, 2017
This comment has been minimized.
This comment has been minimized.
le-jzr
commented
Nov 4, 2017
|
I would say that it's unnecessary to do analysis. Just have the compiler auto-derive |
This comment has been minimized.
This comment has been minimized.
|
The |
This comment has been minimized.
This comment has been minimized.
|
@scottmcm Is this the one you're talking about: https://www.reddit.com/r/rust/comments/6poulm/tip_print_a_t_without_requiring_t_debug/ If so, that helps. But it requires the type to be specialized. I find that again to be leading down the same hole. Except now, it compiles successfully and prints messages that aren't really helpful when you don't have explicit specialization. I think having a system similar to how |
This comment has been minimized.
This comment has been minimized.
Centril
added
the
T-lang
label
Dec 6, 2017
This comment has been minimized.
This comment has been minimized.
matthiaskrgr
commented
Mar 6, 2018
|
If I make a struct derive mod a {
#[derive(Debug)]
pub struct Foo {
pub x: i32,
y: i32,
}
impl Foo {
pub fn new(x: i32) -> Foo {
Foo { x, y: x * 2 }
}
}
}
fn main() {
use a;
let a = a::Foo::new(3);
//println!("{}", a.y); // does not work!
println!("{:?}", a); // does work, due to Debug
}=>
|
prasannavl commentedNov 4, 2017
•
edited
Currently, two traits control the print fmt -
DisplayandDebug.Displaymakes sense to be manually implemented. However Debug trait not only just quickly becomes tedious, but soon ends up in trait bounds and then starts to really pollute the code, even when it's unrelated to the problem space.TL;DR:
format! ("{:?}", x)implies#derive[Debug] for typeof(x).(x as Debug).fmt)Eg:
Let's say one writes a naive algorithm for quicksort. And as a good programming citizen, leaves his/her debug/trace code, that may or may not get removed in the release build.
Well, the problem here is I need the
Debugtrait bound, even though, it isn't a part of the actual problem space. And now every type passed to this generic method has to implement it in order for it to work. This is problematic. I thinkDebughas the potential to pollute the ecosystem this way.Solution:
Learning from other languages (Go, .NET etc) - these compilers just do it for you automatically. Go runtime does the job of printing out, and .NET, for example automatically derives
.ToString(). However, this is not ideal for the a zero-abstraction language like Rust, especially since some of them also use Reflection.So, what I'd like to explore, is the possibility of letting the compiler auto-implement
Debugin addition to#[derive(Debug)]for whichever types that leaves hints that it requires it. Hints could be in the form of compiler support that can be activated by theformat!macros, and or more sophisticated analysis. So, there's always a default implementation, that provides a sensible format like Go. While a language like Go uses reflection, in Rust the compiler should have sufficient knowledge to print all of the data anyway, with the exception of references and pointers (which can just simply print the pointer values, since this can be overridden and by implementing theDebugtrait manually.)Hypothetically, if we assume this is exists, then in the above example
Debugwill no longer be a trait bound, since we can safely let the compiler satisfy it when needed. And since the compiler already has knowledge of whatTis going to be, it will simply mark the typeTto do#derive[Debug]when the compiler has direct access to T, or do a side implementation for it in the library being compiled, as it sees theformat!macros, or whichever the mechanism to drop the hints are. Just to clarify - theformat!macro is just a naive example to express the idea - it may or may not be the right place to drops the hints. But sinceDebugtrait only really makes sense inside a format, I think that would be one way to do it. Or may be simply finding out all calls that imply(x as Debug).fmtwould make more sense.This effectively allows
Debugto mostly become a forgotten hero behind the scenes. Andprintln!("{:?}", x)should just work automatically.However, I don't have knowledge of the compiler internals at the moment, so I'm unsure of the implementation details. I hope someone can shine some light on it.