Skip to content

Commit 3c96c30

Browse files
committed
Normalize inlined function in MIR inliner
1 parent d5ff0e6 commit 3c96c30

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;
@@ -121,7 +125,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
121125
callsite.location.span,
122126
callsite.callee) {
123127
Ok(ref callee_mir) if self.should_inline(callsite, callee_mir) => {
124-
callee_mir.subst(self.tcx, callsite.substs)
128+
subst_and_normalize(callee_mir, self.tcx, &callsite.substs, param_env)
125129
}
126130
Ok(_) => continue,
127131

@@ -570,6 +574,30 @@ fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
570574
})
571575
}
572576

577+
fn subst_and_normalize<'a, 'tcx: 'a>(
578+
mir: &Mir<'tcx>,
579+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
580+
substs: &'tcx ty::subst::Substs<'tcx>,
581+
param_env: ty::ParamEnv<'tcx>,
582+
) -> Mir<'tcx> {
583+
struct Folder<'a, 'tcx: 'a> {
584+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
585+
param_env: ty::ParamEnv<'tcx>,
586+
substs: &'tcx ty::subst::Substs<'tcx>,
587+
}
588+
impl<'a, 'tcx: 'a> ty::fold::TypeFolder<'tcx, 'tcx> for Folder<'a, 'tcx> {
589+
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
590+
self.tcx
591+
}
592+
593+
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
594+
self.tcx.trans_apply_param_substs_env(&self.substs, self.param_env, &t)
595+
}
596+
}
597+
let mut f = Folder { tcx, param_env, substs };
598+
mir.fold_with(&mut f)
599+
}
600+
573601
/**
574602
* Integrator.
575603
*
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)