mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-17 22:46:50 +00:00
Rollup merge of #89829 - voidc:assoc-const-variance, r=lcnr
Consider types appearing in const expressions to be invariant This is an approach to fix #80977. Currently, a type parameter which is only used in a constant expression is considered bivariant and will trigger error E0392 *"parameter T is never used"*. Here is a short example: ```rust pub trait Foo { const N: usize; } struct Bar<T: Foo>([u8; T::N]) where [(); T::N]:; ``` ([playgound](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2015&gist=b51a272853f75925e72efc1597478aa5)) While it is possible to silence this error by adding a `PhantomData<T>` field, I think the better solution would be to make `T` invariant. This would be analogous to the invariance constraints added for associated types. However, I'm quite new to the compiler and unsure whether this is the right approach. r? ``@varkor`` (since you authored #60058)
This commit is contained in:
commit
2b874f0242
@ -223,8 +223,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
self.add_constraints_from_region(current, lt, variance_i)
|
||||
}
|
||||
GenericArgKind::Type(ty) => self.add_constraints_from_ty(current, ty, variance_i),
|
||||
GenericArgKind::Const(_) => {
|
||||
// Consts impose no constraints.
|
||||
GenericArgKind::Const(val) => {
|
||||
self.add_constraints_from_const(current, val, variance_i)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -263,7 +263,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
self.add_constraints_from_mt(current, &ty::TypeAndMut { ty, mutbl }, variance);
|
||||
}
|
||||
|
||||
ty::Array(typ, _) => {
|
||||
ty::Array(typ, len) => {
|
||||
self.add_constraints_from_const(current, len, variance);
|
||||
self.add_constraints_from_ty(current, typ, variance);
|
||||
}
|
||||
|
||||
@ -385,13 +386,32 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
self.add_constraints_from_region(current, lt, variance_i)
|
||||
}
|
||||
GenericArgKind::Type(ty) => self.add_constraints_from_ty(current, ty, variance_i),
|
||||
GenericArgKind::Const(_) => {
|
||||
// Consts impose no constraints.
|
||||
GenericArgKind::Const(val) => {
|
||||
self.add_constraints_from_const(current, val, variance)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds constraints appropriate for a const expression `val`
|
||||
/// in a context with ambient variance `variance`
|
||||
fn add_constraints_from_const(
|
||||
&mut self,
|
||||
current: &CurrentItem,
|
||||
val: &ty::Const<'tcx>,
|
||||
variance: VarianceTermPtr<'a>,
|
||||
) {
|
||||
debug!("add_constraints_from_const(val={:?}, variance={:?})", val, variance);
|
||||
|
||||
match &val.val {
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
let substs = uv.substs(self.tcx());
|
||||
self.add_constraints_from_invariant_substs(current, substs, variance);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds constraints appropriate for a function with signature
|
||||
/// `sig` appearing in a context with ambient variance `variance`
|
||||
fn add_constraints_from_sig(
|
||||
|
@ -8,15 +8,5 @@ LL | inner: [(); { [|_: &T| {}; 0].len() }],
|
||||
|
|
||||
= help: consider moving this anonymous constant into a `const` function
|
||||
|
||||
error[E0392]: parameter `T` is never used
|
||||
--> $DIR/issue-67375.rs:5:12
|
||||
|
|
||||
LL | struct Bug<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
|
||||
error: aborting due to previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0392`.
|
||||
|
@ -3,7 +3,7 @@
|
||||
#![cfg_attr(full, feature(generic_const_exprs))]
|
||||
|
||||
struct Bug<T> {
|
||||
//~^ ERROR parameter `T` is never used
|
||||
//[min]~^ ERROR parameter `T` is never used
|
||||
inner: [(); { [|_: &T| {}; 0].len() }],
|
||||
//[min]~^ ERROR generic parameters may not be used in const operations
|
||||
//[full]~^^ ERROR overly complex generic constant
|
||||
|
@ -12,16 +12,6 @@ LL | let x: S = MaybeUninit::uninit();
|
||||
= note: expected type parameter `S`
|
||||
found union `MaybeUninit<_>`
|
||||
|
||||
error[E0392]: parameter `S` is never used
|
||||
--> $DIR/issue-67945-1.rs:7:12
|
||||
|
|
||||
LL | struct Bug<S> {
|
||||
| ^ unused parameter
|
||||
|
|
||||
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
|
||||
= help: if you intended `S` to be a const parameter, use `const S: usize` instead
|
||||
error: aborting due to previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0392.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
@ -5,7 +5,7 @@
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
struct Bug<S> {
|
||||
//~^ ERROR parameter `S` is never used
|
||||
//[min]~^ ERROR parameter `S` is never used
|
||||
A: [(); {
|
||||
let x: S = MaybeUninit::uninit();
|
||||
//[min]~^ ERROR generic parameters may not be used in const operations
|
||||
|
17
src/test/ui/variance/variance-associated-consts.rs
Normal file
17
src/test/ui/variance/variance-associated-consts.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// Test that the variance computation considers types that
|
||||
// appear in const expressions to be invariant.
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(generic_const_exprs)]
|
||||
|
||||
trait Trait {
|
||||
const Const: usize;
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct Foo<T: Trait> { //~ ERROR [o]
|
||||
field: [u8; <T as Trait>::Const]
|
||||
}
|
||||
|
||||
fn main() { }
|
10
src/test/ui/variance/variance-associated-consts.stderr
Normal file
10
src/test/ui/variance/variance-associated-consts.stderr
Normal file
@ -0,0 +1,10 @@
|
||||
error[E0208]: [o]
|
||||
--> $DIR/variance-associated-consts.rs:13:1
|
||||
|
|
||||
LL | / struct Foo<T: Trait> {
|
||||
LL | | field: [u8; <T as Trait>::Const]
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user