Search code examples
genericsrustcompiler-construction

Why are unused type parameters on Rust structs considered an error and not a warning?


Before somebody marks this as a duplicate, I know how to fix it (and that has been answered already), but I'd like to understand why this limitation exists, and I found no answer on here or in the Rust docs.

For example, I wrote something that goes something like this:

struct ItemList<T> {
  items: Vec<T>
}
impl<T> ItemList<T> {
  fn getFirstItem(&self) -> Link<T> { Link { position: 0 } }
}

struct Link<T> {
  position: usize
}
impl<T> Link<T> {
  fn getFromList<'a>(&self, list: &'a ItemList<T>) -> &'a T {
    &list.items[self.position]
  }
}

But rustc rejects my code with this error:

error[E0392]: parameter `T` is never used
 --> src/main.rs:8:13
  |
8 | struct Link<T> {
  |             ^ unused parameter
  |
  = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
  = help: if you intended `T` to be a const parameter, use `const T: usize` instead

For more information about this error, try `rustc --explain E0392`.

Why is that an error and not a warning? The type parameters only reduce the performance during compile time (if I understood it correctly), so why would you enforce removing it or using a PhantomData marker? Does it have some implications that I missed?


Solution

  • It's a variance issue.

    Rust determines the variance of a type parameter by its usage. If the type is not used, Rust cannot know the variance of the type.

    The Rustonomicon has a chapter about variance.