mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Rollup merge of #132971 - BoxyUwU:handle_infers_in_anon_consts, r=compiler-errors
Handle infer vars in anon consts on stable Fixes #132955 Diagnostics will sometimes try to replace generic parameters with inference variables in failing goals. This means that if we have some failing goal with an array repeat expr count anon const in it, we will wind up with some `ty::ConstKind::Unevaluated(anon_const_def, [?x])` during diagnostics which will then ICE if we do not handle inference variables correctly on stable when normalizing type system consts. r? ```@compiler-errors```
This commit is contained in:
commit
aa189460b8
@ -325,6 +325,9 @@ impl<'tcx> Const<'tcx> {
|
|||||||
|
|
||||||
match c.kind() {
|
match c.kind() {
|
||||||
ConstKind::Value(ty, val) => Ok(tcx.valtree_to_const_val((ty, val))),
|
ConstKind::Value(ty, val) => Ok(tcx.valtree_to_const_val((ty, val))),
|
||||||
|
ConstKind::Expr(_) => {
|
||||||
|
bug!("Normalization of `ty::ConstKind::Expr` is unimplemented")
|
||||||
|
}
|
||||||
_ => Err(tcx.dcx().delayed_bug("Unevaluated `ty::Const` in MIR body").into()),
|
_ => Err(tcx.dcx().delayed_bug("Unevaluated `ty::Const` in MIR body").into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -578,16 +578,28 @@ pub fn try_evaluate_const<'tcx>(
|
|||||||
(args, param_env)
|
(args, param_env)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if tcx.def_kind(uv.def) == DefKind::AnonConst && uv.has_non_region_infer() {
|
||||||
// FIXME: We don't check anything on stable as the only way we can wind up with
|
// FIXME: remove this when `const_evaluatable_unchecked` is a hard error.
|
||||||
// an unevaluated constant containing generic parameters is through array repeat
|
|
||||||
// expression counts which have a future compat lint for usage of generic parameters
|
|
||||||
// instead of a hard error.
|
|
||||||
//
|
//
|
||||||
// This codepath is however also reachable by `generic_const_exprs` and some other
|
// Diagnostics will sometimes replace the identity args of anon consts in
|
||||||
// feature gates which allow constants in the type system to use generic parameters.
|
// array repeat expr counts with inference variables so we have to handle this
|
||||||
// In theory we should be checking for generic parameters here and returning an error
|
// even though it is not something we should ever actually encounter.
|
||||||
// in such cases.
|
//
|
||||||
|
// Array repeat expr counts are allowed to syntactically use generic parameters
|
||||||
|
// but must not actually depend on them in order to evalaute succesfully. This means
|
||||||
|
// that it is actually fine to evalaute them in their own environment rather than with
|
||||||
|
// the actually provided generic arguments.
|
||||||
|
tcx.dcx().delayed_bug(
|
||||||
|
"Encountered anon const with inference variable args but no error reported",
|
||||||
|
);
|
||||||
|
|
||||||
|
let args = GenericArgs::identity_for_item(tcx, uv.def);
|
||||||
|
let param_env = tcx.param_env(uv.def);
|
||||||
|
(args, param_env)
|
||||||
|
} else {
|
||||||
|
// FIXME: This codepath is reachable under `associated_const_equality` and in the
|
||||||
|
// future will be reachable by `min_generic_const_args`. We should handle inference
|
||||||
|
// variables and generic parameters properly instead of doing nothing.
|
||||||
(uv.args, param_env)
|
(uv.args, param_env)
|
||||||
};
|
};
|
||||||
let uv = ty::UnevaluatedConst::new(uv.def, args);
|
let uv = ty::UnevaluatedConst::new(uv.def, args);
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
// Regression test for #132955 checking that we handle anon consts with
|
||||||
|
// inference variables in their generic arguments correctly.
|
||||||
|
//
|
||||||
|
// This arose via diagnostics where we would have some failing goal such
|
||||||
|
// as `[u8; AnonConst<Self>]: PartialEq<Self::A>`, then as part of diagnostics
|
||||||
|
// we would replace all generic parameters with inference vars which would yield
|
||||||
|
// a self type of `[u8; AnonConst<?x>]` and then attempt to normalize `AnonConst<?x>`.
|
||||||
|
|
||||||
|
pub trait T {
|
||||||
|
type A;
|
||||||
|
const P: Self::A;
|
||||||
|
|
||||||
|
fn a() {
|
||||||
|
[0u8; std::mem::size_of::<Self::A>()] == Self::P;
|
||||||
|
//~^ ERROR: can't compare
|
||||||
|
//~| ERROR: constant expression depends on a generic parameter
|
||||||
|
//~| ERROR: constant expression depends on a generic parameter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,31 @@
|
|||||||
|
error: constant expression depends on a generic parameter
|
||||||
|
--> $DIR/failing_goal_with_repeat_expr_anon_const.rs:14:15
|
||||||
|
|
|
||||||
|
LL | [0u8; std::mem::size_of::<Self::A>()] == Self::P;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this may fail depending on what value the parameter takes
|
||||||
|
|
||||||
|
error: constant expression depends on a generic parameter
|
||||||
|
--> $DIR/failing_goal_with_repeat_expr_anon_const.rs:14:47
|
||||||
|
|
|
||||||
|
LL | [0u8; std::mem::size_of::<Self::A>()] == Self::P;
|
||||||
|
| ^^
|
||||||
|
|
|
||||||
|
= note: this may fail depending on what value the parameter takes
|
||||||
|
|
||||||
|
error[E0277]: can't compare `[u8; std::mem::size_of::<Self::A>()]` with `<Self as T>::A`
|
||||||
|
--> $DIR/failing_goal_with_repeat_expr_anon_const.rs:14:47
|
||||||
|
|
|
||||||
|
LL | [0u8; std::mem::size_of::<Self::A>()] == Self::P;
|
||||||
|
| ^^ no implementation for `[u8; std::mem::size_of::<Self::A>()] == <Self as T>::A`
|
||||||
|
|
|
||||||
|
= help: the trait `PartialEq<<Self as T>::A>` is not implemented for `[u8; std::mem::size_of::<Self::A>()]`
|
||||||
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
||||||
|
LL | pub trait T where [u8; std::mem::size_of::<Self::A>()]: PartialEq<<Self as T>::A> {
|
||||||
|
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Reference in New Issue
Block a user