Skip to content
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

Recursive generic type parameters can give confusing error messages #53191

Closed
ltratt opened this issue Aug 8, 2018 · 3 comments · Fixed by #127871
Closed

Recursive generic type parameters can give confusing error messages #53191

ltratt opened this issue Aug 8, 2018 · 3 comments · Fixed by #127871
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@ltratt
Copy link
Contributor

ltratt commented Aug 8, 2018

If I have code like this:

struct S<T> {
    parent: Option<Box<S<T>>>
}

I get the following compiler error message:

error[E0392]: parameter `T` is never used
  --> t.rs:12:10
   |
12 | struct S<T> {
   |          ^ unused type parameter
   |
   = help: consider removing `T` or using a marker such as `std::marker::PhantomData`

error: aborting due to previous error

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

The error message is, IMHO, technically correct, but not necessarily helpful. Now, in this particular example, it's relatively obvious what the mistake is, but I stumbled across it while doing a refactoring that tweaked a complex enum -- I was baffled for a while :) My intuitive explanation is that although I'm "using" T by passing it recursively to S I'm never "consuming" T by attaching it to a concrete type.

I wonder if E0392 might want to be special cased / reworded to cover this particular case? I appreciate it's not a common one, but I'm probably not the first person to do something silly like this.

@oli-obk oli-obk added the A-diagnostics Area: Messages for errors, warnings, and lints label Aug 8, 2018
@estebank estebank added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. D-papercut Diagnostics: An error or lint that needs small tweaks. labels Feb 14, 2020
@crlf0710 crlf0710 added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jun 11, 2020
@jberkenbilt
Copy link

I'm brand new to rust and ran into this while trying to reproduce another issue. I actually don't understand why this is silly or why the error applies. Without seeing this, I generated exactly the same code except my struct was called A. :-) I notice that this assertion passes, so I don't see exactly why it's an error without the phantoms.

use std::marker::PhantomData;
struct A<T> {
    x: Option<Box<A<T>>>,
    _z: PhantomData<T>,
}

fn main() {
    let a = A::<i32> {
        x: None,
        _z: PhantomData
    };
    assert!(a.x.is_none());
}

@peter-lyons-kehl
Copy link
Contributor

peter-lyons-kehl commented Mar 4, 2023

If you need recursive generic type parameters without PhantomData, and you're happy with nightly-only, see #108725. However, (even though BTreeMap/BTreeSet have been depending on it) we don't know yet whether that is the intended behavior or not, so unsure for how long it will be available.

@workingjubilee
Copy link
Member

I am usually an advocate for experimenting with nightly features, even "in production", but that is contingent on the fact that most nightly features are actually quite sound. I strongly advise against using an incomplete feature for any practical code of significant use.

@bors bors closed this as completed in 65de5d0 Jul 19, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Jul 19, 2024
Rollup merge of rust-lang#127871 - compiler-errors:recursive, r=estebank

Mention that type parameters are used recursively on bivariance error

Right now when a type parameter is used recursively, even with indirection (so it has a finite size) we say that the type parameter is unused:

```
struct B<T>(Box<B<T>>);
```

This is confusing, because the type parameter is *used*, it just doesn't have its variance constrained. This PR tweaks that message to mention that it must be used *non-recursively*.

Not sure if we should actually mention "variance" here, but also I'd somewhat prefer we don't keep the power users in the dark w.r.t the real underlying issue, which is that the variance isn't constrained. That technical detail is reserved for a note, though.

cc `@fee1-dead`

Fixes rust-lang#118976
Fixes rust-lang#26283
Fixes rust-lang#53191
Fixes rust-lang#105740
Fixes rust-lang#110466
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants