Auto merge of #119821 - oli-obk:reveal_all_const_evals, r=lcnr
Always use RevealAll for const eval queries implements what is described in https://github.com/rust-lang/rust/pull/116803#discussion_r1364089471 Using `UserFacing` for const eval does not make sense anymore, unless we significantly change things like avoiding revealing opaque types. New tests are copied from https://github.com/rust-lang/rust/pull/101478
This commit is contained in:
commit
5378c1cf07
32 changed files with 362 additions and 107 deletions
|
@ -225,17 +225,10 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
|
||||
) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> {
|
||||
// see comment in eval_to_allocation_raw_provider for what we're doing here
|
||||
if key.param_env.reveal() == Reveal::All {
|
||||
let mut key = key;
|
||||
key.param_env = key.param_env.with_user_facing();
|
||||
match tcx.eval_to_const_value_raw(key) {
|
||||
// try again with reveal all as requested
|
||||
Err(ErrorHandled::TooGeneric(_)) => {}
|
||||
// deduplicate calls
|
||||
other => return other,
|
||||
}
|
||||
}
|
||||
// Const eval always happens in Reveal::All mode in order to be able to use the hidden types of
|
||||
// opaque types. This is needed for trivial things like `size_of`, but also for using associated
|
||||
// types that are not specified in the opaque type.
|
||||
assert_eq!(key.param_env.reveal(), Reveal::All);
|
||||
|
||||
// We call `const_eval` for zero arg intrinsics, too, in order to cache their value.
|
||||
// Catch such calls and evaluate them instead of trying to load a constant's MIR.
|
||||
|
@ -265,24 +258,11 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
|
||||
) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
|
||||
// Because the constant is computed twice (once per value of `Reveal`), we are at risk of
|
||||
// reporting the same error twice here. To resolve this, we check whether we can evaluate the
|
||||
// constant in the more restrictive `Reveal::UserFacing`, which most likely already was
|
||||
// computed. For a large percentage of constants that will already have succeeded. Only
|
||||
// associated constants of generic functions will fail due to not enough monomorphization
|
||||
// information being available.
|
||||
// Const eval always happens in Reveal::All mode in order to be able to use the hidden types of
|
||||
// opaque types. This is needed for trivial things like `size_of`, but also for using associated
|
||||
// types that are not specified in the opaque type.
|
||||
|
||||
// In case we fail in the `UserFacing` variant, we just do the real computation.
|
||||
if key.param_env.reveal() == Reveal::All {
|
||||
let mut key = key;
|
||||
key.param_env = key.param_env.with_user_facing();
|
||||
match tcx.eval_to_allocation_raw(key) {
|
||||
// try again with reveal all as requested
|
||||
Err(ErrorHandled::TooGeneric(_)) => {}
|
||||
// deduplicate calls
|
||||
other => return other,
|
||||
}
|
||||
}
|
||||
assert_eq!(key.param_env.reveal(), Reveal::All);
|
||||
if cfg!(debug_assertions) {
|
||||
// Make sure we format the instance even if we do not print it.
|
||||
// This serves as a regression test against an ICE on printing.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue