Hacker News new | ask | show | jobs
by arjie 3738 days ago
Interesting. I'd read that code as "For all T, if we have a Buffer<T>, print out the Vec<T>'s elements" and it makes sense that this doesn't work. It isn't that the compiler doesn't know about it, but that T is not constrained within the form to something printable and consequently you can't print it. It would seem more confusing if it had indeed worked, since that would mean (in a semantic sense) that T is auto-constrained to the types that are actually used as T, so you can't reason about the code having the T on its own but only within the context of the larger form.

Not arguing or anything about what error messages are valid. I just found your perspective about the "compiler not knowing" interesting and felt like sharing this.

1 comments

Ah, you are right. It's not so much that the compiler doesn't know something, but that the compiler does know something: T could have been an non-printable type. You are being protected against panics that might have resulted from passing vectors of non-printable types in.

I still think the error message could be a lot better, as the word 'implementation' is confusing. What's happened here is that Buffer was being used in a for-loop as if it always contained printable types, when actually there was no assurance that this was the case.

Edit: Highly recommend reading the comments of the two people that responded to me, as they're both more correct and more helpful while I was trying to work things out as I wrote my comments.

In fact noting pretty much what you wrote in the first paragraph would improve it a lot: below the initial error message (above the expansion stuff) it could note

    requires that "i" implements Debug, but

    src/x/mod.rs:15 impl<T> Info for Buffer<T> {
    does not specify that T must be Debug

    hint: you can bound T to Debug:

        impl <T> Info for Buffer<T> where T: Debug {

    this means the code will only work with types which implements Debug, 
    but lets you use Debug operations in your methods
Worse, the rest of the error message gives completely the wrong direction for this error case, it gives an advice for a concrete type T, not for a generic one.
> You are being protected against panics that might have resulted from passing vectors of non-printable types in.

Not quite. Rust's generics are instantiated statically - the compiler generates code specific to the type parameters passed in. The compiler must handle cases where it could not find a conforming function implemented for that the type, otherwise no code can be generated. Without the use of traits to constrain types you could get around this by printing a stack trace of the instantiation, but that causes even worse error messages - ie. the ones you see coming from C++ compilers.