rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.36k stars 12.72k forks source link

Inconsistent Compiler Warning for Unused Type Parameter with Generic Constraints in Nightly with #![feature(generic_const_exprs)] #115037

Open pscott31 opened 1 year ago

pscott31 commented 1 year ago

I tried this code:

#![feature(generic_const_exprs)]

pub trait MyTrait<T> {}

pub struct MyStruct<D: MyTrait<U>, U> {
    foo: D,
}

pub trait OtherTrait {
    const LENGTH: usize;
}

pub struct OtherStruct<C: OtherTrait, D: MyTrait<U>, U>
where
    [(); C::LENGTH]:,
{
    foo: D,
    state: [bool; C::LENGTH],
}

I expected to see this happen: In this code, MyStruct produces an "unused type parameter" warning, while OtherStruct does not, despite both structs having a similar usage of U within a trait bound. Without #![feature(generic_const_exprs)] both are accepted.

Instead, this happened: The compiler raises a warning for MyStruct but not for OtherStruct.

Meta

rustc --version --verbose:

rustc 1.73.0-nightly (6ef7d16be 2023-08-19)
binary: rustc
commit-hash: 6ef7d16be0fb9d6ecf300c27990f4bff49d22d46
commit-date: 2023-08-19
host: x86_64-unknown-linux-gnu
release: 1.73.0-nightly
Backtrace

``` error[E0392]: parameter `U` is never used --> src/matrix.rs:48:36 | 48 | pub struct MyStruct, U> { | ^ unused parameter | = help: consider removing `U`, referring to it in a field, or using a marker such as `PhantomData` = help: if you intended `U` to be a const parameter, use `const U: usize` instead ```

I fully appreciate the warning I get from the compiler when enabling the feature, so I really have nothing to complain about - but thought the report might be helpfull none the less :)

asquared31415 commented 1 year ago

Some interesting information: referring to any const ends up suppressing all unused params errors.

#![allow(incomplete_features)]
#![feature(generic_const_exprs)]

pub trait MyTrait<T> {}

const UWU: usize = 5;

pub struct S<D: MyTrait<U>, U> {
    // If the struct refers to a const, it doesn't emit any unused param errors
    _x: [(); UWU],
    // no error emitted for use of D either
    // foo: D,
}

Removing the GCE feature gate makes this code emit an error.

@rustbot label +requires-nightly +requires-incomplete-features +F-generic_const_exprs +T-compiler -needs-triage

fmease commented 1 year ago

Some interesting information: referring to any const ends up suppressing all unused params errors.

That's because under generic_const_exprs, the const expr UWU “captures” the generic parameters that are in scope (they are passed as arguments to the unevaluated const / const projection) and as a result change the variance of D and U from bivariant (i.e., unused) to invariant.

However, that does seem kinda fishy :O