-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Rust complains about unused type parameter which is only used to parameterize another #23246
Comments
This is actually intended behavior due to a recently merged RFC. The idea here is that the compiler needs to know what constraints it can put on the type parameter You can check out the examples for
You probably don't want to store |
Thanks for the helpful explanation, @alexcrichton. You also conveniently educated me on associated types, which I was wondering about but didn't know what to search for (I was wondering "why is |
I just stumbled upon this limitation in a context where
Edit: I'm aware of several workarounds. These include adding |
Hi, I had a similar problem regarding to unused type parameter. struct Quicksort<T>; // <---- unused parameter warning
trait Sorter<T> {
fn sort(&self,ar<T>){...}
fn join(...);
fn split(...);
}
impl<T> Quicksort<T> {
pub fn sort(&self,ar<T>){
Sorter::sort(self, ar<T>) ;
}
}
impl<T> Sorter<T> for Quicksort<T>{
fn join(...) {...}
fn split(...) {...}
} Any help to resolve the problem? because struct Quicksort does not have any fields. The type parameter is solely for the sort function from trait. |
For those who will look here for answers: Taking @Piping example for illustration. struct Quicksort; Now Continuing. Type parameter can be introduced at function level. impl Quicksort {
pub fn sort<T>(&self,ar<T>){
Sorter::sort(self, ar<T>) ;
}
} Now when it comes to implementing a trait things goes smoothly again since type parameter is already exists in impl<T> Sorter<T> for Quicksort {
fn join(...) {...}
fn split(...) {...}
} There are few places where you actually need artificial type parameter.
trait Trait {
type X;
} Now either the type in question will be able to implement the struct Foo;
impl Trait for Foo {
type X = u32;
} Or it has to have this artificial type parameter after all. struct Foo<T>(PhantomData<T>);
impl<T> Trait for Foo<T> {
type X = T;
} |
In case you're still interested, I had a similar problem and I solved it by creating an additional variant that stores the pub enum Empty {}
pub enum Foo<A, B> {
X(A),
// ...
Void(Empty, PhantomData<B>),
} The good news is that it's zero-cost and does not pollute the variants you do use. The bad news is that, until never type exhaustive matching comes to Rust, this approach will pollute the code when you match on your enum (although you could macro your way around it): match foo {
Foo::A(_) => (),
// ...
Foo::Void(empty, _) => match empty {},
// ^
// phantom data
} |
@alexcrichton |
@mankinskin I agree. PhantomData in this instance just pollutes the code. It is an implementation detail that should never be exposed in a public API (which is what happens with both @AdrienChampion 's and @neithernut 's code. It's also exceedingly irritiating, adding code complexity, complicating construction (so making it harder to just pass generic enum members as closures w/o writing extra code, etc. It's a code smell in Rust itself. |
Looking back to @alexcrichton's response and the RFC, I think the question is not so much why unused type parameters cause an error, but why the compiler considers type parameters unused in examples like the OP's. To me, it seems like In Scala for example, the equivalent would be If getting the compiler to recognize these variance bounds would be complicated, perhaps lifetime and non-lifetime parameters could be handled differently? As the RFC notes, only lifetimes have subtype relationships, so it seems like non-lifetime parameters might as well be "inherently" invariant, and not subject to inference. Code like |
I think perhaps we should reopen this one. The associated RFC doesn't seem to justify a compiler error in code like: pub struct Foo<A> {
a: A,
}
pub struct Bar<A, F>
where
F: AsRef<Foo<A>>,
{
foo: F,
} |
Changes of this magnitude would require an RFC these days, and I would encourage folks to either open an RFC or a thread on users or internals rather than continuing to comment on an issue that was closed almost six years ago. |
But can't this issue be reopened? This is kind of the first place you end up at when googling about this, and the discussion is basically already here. I don't think there is a lot of designing left to do, it just needs to be implemented in the right way. I can try to write up an RFC some time, but it is not high on my priority list right now and I am completely unexperienced with rustc. Opening up this issue for now would at least raise attention to it and helps resolving this faster. |
Large scale changes to the language, of which this is one, require an RFC. I am not on the lang team, but this isn't actually a bug: this is a request for a change to how the language works. A bug being open for it is not the procedure by which this would be changed. |
@mankinskin I agree completely, and I feel your frustration; I share it, and it's got worse as rust has become more widely used. Rust's core team also have a very narrow view of what a bug is - one that with my software craftsmanship hat on I couldn't disagree with more strongly. Rust's development has been captured by the bureaucratically minded; the same mindset that has infested wikipedia, and parodied beautifully in Brazil. Personally, I find it rude; it shows disinterest in the views of those outside of the main development, and the idea that anyone can have a good idea. |
@raphaelcohn I know what you mean and we should always be wary of overdoing that, it might stagnate innovation, but I also think there is value in organization and strict review. Rust's promise is to be a secure language, that means it must takes steps carefully, which makes it more difficult to innovate. I agree that there eventually needs to be an RFC for this but I don't really see the point of restricting discussions about feature changes in these github issues. I suppose they use this as a bug tracker, and new features are not supposed to be tracked here. In general, I think there are a lot of improvements that could be made to the entire open source workflow nowadays. The tools don't really integrate well, basically just using hyperlinks. For open source work there ought to be issue dependencies, resource budgets, integrated documentations and tests, voting on forks, funding, user permissions, all of that. That would make open source a lot more "open" and transparent. It has to come eventually, but there still needs some work to be done. |
Moderation note: what @steveklabnik said is correct. The kind of unconstructive broad criticism that has taken place in the past few comments is not appropriate here. Since this discussion doesn't seem to be headed anywhere good, and the next steps if one were to make progress have been clarified, I'm going to lock this thread. |
Code:
Compile:
I'm pretty new to rust, so forgive me if I've missed something. But I can't see a way to say "my struct contains a type T2, which implements
SomeGenericTrait<T>
" without my struct also being parameterized over T, as I'm doing here. But rust thinks that I'm not using T.I tried adding:
to my struct def, which makes it compile. So it doesn't look like this is just one error message obscuring another, rust does really think this is the only thing wrong with my code.
The text was updated successfully, but these errors were encountered: