title: Why are trait methods with generic type parameters object-unsafe?
body: <p>To quote <a href="https://doc.rust-lang.org/stable/book/ch17-02-trait-objects.html" rel="noreferrer">the Book</a> (emphasis mine),</p>
  <blockquote>
  <p>The same is true of generic type parameters that are filled in with concrete type parameters when the trait is used: the concrete types become part of the type that implements the trait. When the type is forgotten through the use of a trait object, there is no way to know what types to fill in the generic type parameters with.</p>
  </blockquote>
  <p>I cannot understand the rationale. For a concrete example, consider the following</p>
  <pre><code>pub trait Echoer {
      fn echo&lt;T&gt;(&amp;self, v: T) -&gt; T;
  }
  
  pub struct Foo { }
  
  impl Echoer for Foo {
      fn echo&lt;T&gt;(&amp;self, v: T) -&gt; T {
          println!(&quot;v = {}&quot;, v);
          return v;
      }
  }
  
  pub fn passthrough&lt;T&gt;(e: Box&lt;dyn Echoer&gt;, v: T) {
      return e.echo(v);
  }
  
  fn main() {
      let foo = Foo { };
      passthrough(foo, 42);
  }
  </code></pre>
  <p>The result is, of course, an error</p>
  <pre><code>$ cargo run
     Compiling gui v0.1.0 (/tmp/gui)
  error[E0038]: the trait `Echoer` cannot be made into an object
    --&gt; src/main.rs:14:27
     |
  14 | pub fn passthrough&lt;T&gt;(e: Box&lt;dyn Echoer&gt;, v: T) {
     |                           ^^^^^^^^^^^^^^^ `Echoer` cannot be made into an object
     |
     = help: consider moving `echo` to another trait
  note: for a trait to be &quot;object safe&quot; it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit &lt;https://doc.rust-lang.org/reference/items/traits.html#object-safety&gt;
    --&gt; src/main.rs:2:8
     |
  1  | pub trait Echoer {
     |           ------ this trait cannot be made into an object...
  2  |     fn echo&lt;T&gt;(&amp;self, v: T) -&gt; T;
     |        ^^^^ ...because method `echo` has generic type parameters
  
  error: aborting due to previous error
  
  For more information about this error, try `rustc --explain E0038`.
  error: could not compile `gui`
  
  To learn more, run the command again with --verbose.
  </code></pre>
  <p>From my understanding, even though <code>e</code> forgets about its concrete type when being cast into a trait object, it can still infer that it needs to fill the generic type parameter of <code>echo&lt;T&gt;</code> with <code>i32</code>, since it's called inside <code>passthrough&lt;T&gt;</code>, which is monomorphized to <code>passthrough&lt;i32&gt;</code> at compile time.</p>
  <p>What does &quot;the concrete types become part of the type that implements the trait&quot; mean? Why can't trait methods fill their generic type parameters at compile time, e.g. just call <code>echo&lt;i32&gt;</code>?</p>