Skip to content

Commit

Permalink
Auto merge of rust-lang#77306 - lcnr:inline-ok, r=eddyb
Browse files Browse the repository at this point in the history
normalize substs while inlining

fixes rust-lang#68347 or more precisely, this fixes the same ICE in rust analyser as veloren is pinned to a specific nightly
and had an error with the current one.

I didn't look into creating an MVCE here as that seems fairly annoying, will spend a few minutes doing so rn. (failed)

r? `@eddyb` cc `@bjorn3`
  • Loading branch information
bors committed Oct 18, 2020
2 parents 834821e + ac893b8 commit 4d247ad
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 7 deletions.
10 changes: 7 additions & 3 deletions compiler/rustc_mir/src/transform/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,13 @@ impl Inliner<'tcx> {
let terminator = bb_data.terminator();
if let TerminatorKind::Call { func: ref op, .. } = terminator.kind {
if let ty::FnDef(callee_def_id, substs) = *op.ty(caller_body, self.tcx).kind() {
let instance = Instance::resolve(self.tcx, self.param_env, callee_def_id, substs)
.ok()
.flatten()?;
// To resolve an instance its substs have to be fully normalized, so
// we do this here.
let normalized_substs = self.tcx.normalize_erasing_regions(self.param_env, substs);
let instance =
Instance::resolve(self.tcx, self.param_env, callee_def_id, normalized_substs)
.ok()
.flatten()?;

if let InstanceDef::Virtual(..) = instance.def {
return None;
Expand Down
11 changes: 7 additions & 4 deletions compiler/rustc_trait_selection/src/traits/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ use rustc_middle::ty::{self, TyCtxt};
/// (necessarily) resolve all nested obligations on the impl. Note
/// that type check should guarantee to us that all nested
/// obligations *could be* resolved if we wanted to.
///
/// Assumes that this is run after the entire crate has been successfully type-checked.
/// This also expects that `trait_ref` is fully normalized.
pub fn codegen_fulfill_obligation<'tcx>(
ty: TyCtxt<'tcx>,
tcx: TyCtxt<'tcx>,
(param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>),
) -> Result<ImplSource<'tcx, ()>, ErrorReported> {
// Remove any references to regions; this helps improve caching.
let trait_ref = ty.erase_regions(&trait_ref);

let trait_ref = tcx.erase_regions(&trait_ref);
// We expect the input to be fully normalized.
debug_assert_eq!(trait_ref, tcx.normalize_erasing_regions(param_env, trait_ref));
debug!(
"codegen_fulfill_obligation(trait_ref={:?}, def_id={:?})",
(param_env, trait_ref),
Expand All @@ -33,7 +36,7 @@ pub fn codegen_fulfill_obligation<'tcx>(

// Do the initial selection for the obligation. This yields the
// shallow result we are looking for -- that is, what specific impl.
ty.infer_ctxt().enter(|infcx| {
tcx.infer_ctxt().enter(|infcx| {
let mut selcx = SelectionContext::new(&infcx);

let obligation_cause = ObligationCause::dummy();
Expand Down
28 changes: 28 additions & 0 deletions src/test/ui/mir/mir-inlining/ice-issue-68347.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// run-pass
// compile-flags:-Zmir-opt-level=2
pub fn main() {
let _x: fn() = handle_debug_column;
}

fn handle_debug_column() {
let sampler = sample_columns();

let foo = || {
sampler.get(17);
};
foo();
}

fn sample_columns() -> impl Sampler {
ColumnGen {}
}

struct ColumnGen {}

trait Sampler {
fn get(&self, index: i32);
}

impl Sampler for ColumnGen {
fn get(&self, _index: i32) {}
}
17 changes: 17 additions & 0 deletions src/test/ui/mir/mir-inlining/ice-issue-77306-1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// run-pass
// compile-flags:-Zmir-opt-level=2

// Previously ICEd because we did not normalize during inlining,
// see https://github.com/rust-lang/rust/pull/77306 for more discussion.

pub fn write() {
create()()
}

pub fn create() -> impl FnOnce() {
|| ()
}

fn main() {
write();
}
32 changes: 32 additions & 0 deletions src/test/ui/mir/mir-inlining/ice-issue-77306-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// run-pass
// compile-flags:-Zmir-opt-level=2

struct Cursor {}
struct TokenTree {}

impl Iterator for Cursor {
type Item = TokenTree;

fn next(&mut self) -> Option<TokenTree> {
None
}
}

fn tokenstream_probably_equal_for_proc_macro() {
fn break_tokens(_tree: TokenTree) -> impl Iterator<Item = TokenTree> {
let token_trees: Vec<TokenTree> = vec![];
token_trees.into_iter()
}

let c1 = Cursor {};
let c2 = Cursor {};

let mut t1 = c1.flat_map(break_tokens);
let mut t2 = c2.flat_map(break_tokens);

for (_t1, _t2) in t1.by_ref().zip(t2.by_ref()) {}
}

fn main() {
tokenstream_probably_equal_for_proc_macro();
}

0 comments on commit 4d247ad

Please sign in to comment.