-
Notifications
You must be signed in to change notification settings - Fork 13.3k
derive Debug incorrect assumption #52560
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
Comments
This is simply how The problem is, given an arbitrary struct definition, struct Foo<A, B, C> {
stuff: Pair<A, B>,
thing: Builder<B>,
marker: PhantomData<C>,
} the derive macro for impl<A, B, C> Debug for Foo<A, B, C>
where ?????
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Foo")
.field("stuff", &self.stuff)
.field("thing", &self.thing)
.field("marker", &self.marker)
.finish()
}
} but the question is, what should be used for the At this point we don't know anything else about the types defined here; we don't know what where // require each field to impl Debug
Pair<A, B>: Debug,
Builder<B>: Debug,
PhantomData<C>: Debug, or a conservative guess that is correct in 90% of use-cases: where // require each type param to impl Debug
A: Debug, B: Debug, C: Debug rust goes with the second option. No doubt, it is an annoying limitation for many people when they first run into it, and there have been discussions about possible ways to improve the situation, such as in this RFC. |
Should at least be
Edit: this is handled in #65192:
|
@ExpHP I see your point, however in this case there is no field that would even have |
Indeed, for your specific struct, it does seem to be possible to generate an use std::fmt;
impl<B: Bar<Item=Bi>, Bi: fmt::Debug> fmt::Debug for Foo<B> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("Foo").field(&self.0).finish()
}
} This impl is possible to generate based on the facts that:
Support for generating impls like this is a change that could go through the RFC process. Personally speaking, I would not be too enthusiastic about it due to rather general issues (I see it providing little value to offset the base cost that comes with any feature like this, which is that the presence of a supported use case constrains future design decisions) |
As an aside, I think that it is generally better when possible to write the following // use as Foo<B::Item>
struct Foo<B>(B); The advantage of writing it this way is variance; the above form of Of course, this advice is not one-size-fits-all; in some cases it is desirable to have the |
In my case what the But yeah, when possible, I agree. |
Hello,
I'm guessing there "might" be something wrong how the
Debug
trait is derived in case a type is owned but not actually needed for formatting the object. The following code fails becauseB
is not necessarilyDebug
which is correct, however sinceFoo
doesn't actually have an instance ofB
as a field, that shouldn't be needed, andB::Item
is restricted toDebug
:The text was updated successfully, but these errors were encountered: