Skip to content

Commit

Permalink
Rollup merge of rust-lang#105455 - lcnr:correct-reveal-in-validate, r…
Browse files Browse the repository at this point in the history
…=jackh726

use the correct `Reveal` during validation

supersedes rust-lang#105454. Deals with rust-lang#105009 (comment), not closing rust-lang#105009 as the ICE may leak into beta

The issue was the following:
- we optimize the mir, using `Reveal::All`
- some optimization relies on the hidden type of an opaque type
- we then validate using `Reveal::UserFacing` again which is not able to observe the hidden type

r? `@jackh726`
  • Loading branch information
matthiaskrgr authored Dec 9, 2022
2 parents 6111a73 + e73ef59 commit 04dac42
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 1 deletion.
6 changes: 5 additions & 1 deletion compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_index::bit_set::BitSet;
use rustc_infer::traits::Reveal;
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::visit::NonUseContext::VarDebugInfo;
use rustc_middle::mir::visit::{PlaceContext, Visitor};
Expand Down Expand Up @@ -44,8 +45,11 @@ impl<'tcx> MirPass<'tcx> for Validator {
return;
}
let def_id = body.source.def_id();
let param_env = tcx.param_env(def_id);
let mir_phase = self.mir_phase;
let param_env = match mir_phase.reveal() {
Reveal::UserFacing => tcx.param_env(def_id),
Reveal::All => tcx.param_env_reveal_all_normalized(def_id),
};

let always_live_locals = always_storage_live_locals(body);
let storage_liveness = MaybeStorageLive::new(always_live_locals)
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_middle/src/mir/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use super::{BasicBlock, Constant, Field, Local, SwitchTargets, UserTypeProjection};

use crate::mir::coverage::{CodeRegion, CoverageKind};
use crate::traits::Reveal;
use crate::ty::adjustment::PointerCast;
use crate::ty::subst::SubstsRef;
use crate::ty::{self, List, Ty};
Expand Down Expand Up @@ -100,6 +101,13 @@ impl MirPhase {
MirPhase::Runtime(RuntimePhase::Optimized) => "runtime-optimized",
}
}

pub fn reveal(&self) -> Reveal {
match *self {
MirPhase::Built | MirPhase::Analysis(_) => Reveal::UserFacing,
MirPhase::Runtime(_) => Reveal::All,
}
}
}

/// See [`MirPhase::Analysis`].
Expand Down
52 changes: 52 additions & 0 deletions src/test/ui/mir/validate/needs-reveal-all.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Regression test for #105009. the issue here was that even after the `RevealAll` pass,
// `validate` still used `Reveal::UserFacing`. This meant that it now ends up comparing
// opaque types with their revealed version, resulting in an ICE.
//
// We're using these flags to run the `RevealAll` pass while making it less likely to
// accidentally removing the assignment from `Foo<fn_ptr>` to `Foo<fn_def>`.

// compile-flags: -Zinline_mir=yes -Zmir-opt-level=0 -Zvalidate-mir
// run-pass

use std::hint::black_box;

trait Func {
type Ret: Id;
}

trait Id {
type Assoc;
}
impl Id for u32 {
type Assoc = u32;
}
impl Id for i32 {
type Assoc = i32;
}

impl<F: FnOnce() -> R, R: Id> Func for F {
type Ret = R;
}

fn bar() -> impl Copy + Id {
0u32
}

struct Foo<T: Func> {
_func: T,
value: Option<<<T as Func>::Ret as Id>::Assoc>,
}

fn main() {
let mut fn_def = black_box(Foo {
_func: bar,
value: None,
});
let fn_ptr = black_box(Foo {
_func: bar as fn() -> _,
value: None,
});

fn_def.value = fn_ptr.value;
black_box(fn_def);
}

0 comments on commit 04dac42

Please sign in to comment.