Skip to content

Commit 9b53f0a

Browse files
committed
Auto merge of #45909 - sinkuu:issue-45885, r=arielb1
Normalize inlined function in MIR inliner Fixes #45885 r? @arielb1
2 parents 212d74f + 3c96c30 commit 9b53f0a

File tree

2 files changed

+71
-5
lines changed

2 files changed

+71
-5
lines changed

src/librustc_mir/transform/inline.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec};
1818
use rustc::mir::*;
1919
use rustc::mir::transform::{MirPass, MirSource};
2020
use rustc::mir::visit::*;
21-
use rustc::ty::{self, Ty, TyCtxt, Instance};
21+
use rustc::ty::{self, Instance, Ty, TyCtxt, TypeFoldable};
2222
use rustc::ty::subst::{Subst,Substs};
2323

2424
use std::collections::VecDeque;
@@ -77,8 +77,13 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
7777

7878
let mut callsites = VecDeque::new();
7979

80+
let param_env;
81+
8082
// Only do inlining into fn bodies.
8183
if let MirSource::Fn(caller_id) = self.source {
84+
let caller_def_id = self.tcx.hir.local_def_id(caller_id);
85+
param_env = self.tcx.param_env(caller_def_id);
86+
8287
for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated() {
8388
// Don't inline calls that are in cleanup blocks.
8489
if bb_data.is_cleanup { continue; }
@@ -88,9 +93,6 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
8893
if let TerminatorKind::Call {
8994
func: Operand::Constant(ref f), .. } = terminator.kind {
9095
if let ty::TyFnDef(callee_def_id, substs) = f.ty.sty {
91-
let caller_def_id = self.tcx.hir.local_def_id(caller_id);
92-
let param_env = self.tcx.param_env(caller_def_id);
93-
9496
if let Some(instance) = Instance::resolve(self.tcx,
9597
param_env,
9698
callee_def_id,
@@ -105,6 +107,8 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
105107
}
106108
}
107109
}
110+
} else {
111+
return;
108112
}
109113

110114
let mut local_change;
@@ -123,7 +127,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
123127
callsite.location.span,
124128
callsite.callee) {
125129
Ok(ref callee_mir) if self.should_inline(callsite, callee_mir) => {
126-
callee_mir.subst(self.tcx, callsite.substs)
130+
subst_and_normalize(callee_mir, self.tcx, &callsite.substs, param_env)
127131
}
128132
Ok(_) => continue,
129133

@@ -587,6 +591,30 @@ fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
587591
})
588592
}
589593

594+
fn subst_and_normalize<'a, 'tcx: 'a>(
595+
mir: &Mir<'tcx>,
596+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
597+
substs: &'tcx ty::subst::Substs<'tcx>,
598+
param_env: ty::ParamEnv<'tcx>,
599+
) -> Mir<'tcx> {
600+
struct Folder<'a, 'tcx: 'a> {
601+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
602+
param_env: ty::ParamEnv<'tcx>,
603+
substs: &'tcx ty::subst::Substs<'tcx>,
604+
}
605+
impl<'a, 'tcx: 'a> ty::fold::TypeFolder<'tcx, 'tcx> for Folder<'a, 'tcx> {
606+
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
607+
self.tcx
608+
}
609+
610+
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
611+
self.tcx.trans_apply_param_substs_env(&self.substs, self.param_env, &t)
612+
}
613+
}
614+
let mut f = Folder { tcx, param_env, substs };
615+
mir.fold_with(&mut f)
616+
}
617+
590618
/**
591619
* Integrator.
592620
*
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags:-Zmir-opt-level=2
12+
13+
pub enum Enum {
14+
A,
15+
B,
16+
}
17+
18+
trait SliceIndex {
19+
type Output;
20+
fn get(&self) -> &Self::Output;
21+
}
22+
23+
impl SliceIndex for usize {
24+
type Output = Enum;
25+
#[inline(never)]
26+
fn get(&self) -> &Enum {
27+
&Enum::A
28+
}
29+
}
30+
31+
#[inline(always)]
32+
fn index<T: SliceIndex>(t: &T) -> &T::Output {
33+
t.get()
34+
}
35+
36+
fn main() {
37+
match *index(&0) { Enum::A => true, _ => false };
38+
}

0 commit comments

Comments
 (0)