Auto merge of #45909 - sinkuu:issue-45885, r=arielb1
Normalize inlined function in MIR inliner Fixes #45885 r? @arielb1
This commit is contained in:
commit
9b53f0a662
@ -18,7 +18,7 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::transform::{MirPass, MirSource};
|
||||
use rustc::mir::visit::*;
|
||||
use rustc::ty::{self, Ty, TyCtxt, Instance};
|
||||
use rustc::ty::{self, Instance, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc::ty::subst::{Subst,Substs};
|
||||
|
||||
use std::collections::VecDeque;
|
||||
@ -77,8 +77,13 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
|
||||
let mut callsites = VecDeque::new();
|
||||
|
||||
let param_env;
|
||||
|
||||
// Only do inlining into fn bodies.
|
||||
if let MirSource::Fn(caller_id) = self.source {
|
||||
let caller_def_id = self.tcx.hir.local_def_id(caller_id);
|
||||
param_env = self.tcx.param_env(caller_def_id);
|
||||
|
||||
for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated() {
|
||||
// Don't inline calls that are in cleanup blocks.
|
||||
if bb_data.is_cleanup { continue; }
|
||||
@ -88,9 +93,6 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
if let TerminatorKind::Call {
|
||||
func: Operand::Constant(ref f), .. } = terminator.kind {
|
||||
if let ty::TyFnDef(callee_def_id, substs) = f.ty.sty {
|
||||
let caller_def_id = self.tcx.hir.local_def_id(caller_id);
|
||||
let param_env = self.tcx.param_env(caller_def_id);
|
||||
|
||||
if let Some(instance) = Instance::resolve(self.tcx,
|
||||
param_env,
|
||||
callee_def_id,
|
||||
@ -105,6 +107,8 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut local_change;
|
||||
@ -123,7 +127,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
callsite.location.span,
|
||||
callsite.callee) {
|
||||
Ok(ref callee_mir) if self.should_inline(callsite, callee_mir) => {
|
||||
callee_mir.subst(self.tcx, callsite.substs)
|
||||
subst_and_normalize(callee_mir, self.tcx, &callsite.substs, param_env)
|
||||
}
|
||||
Ok(_) => continue,
|
||||
|
||||
@ -587,6 +591,30 @@ fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
})
|
||||
}
|
||||
|
||||
fn subst_and_normalize<'a, 'tcx: 'a>(
|
||||
mir: &Mir<'tcx>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
substs: &'tcx ty::subst::Substs<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> Mir<'tcx> {
|
||||
struct Folder<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
substs: &'tcx ty::subst::Substs<'tcx>,
|
||||
}
|
||||
impl<'a, 'tcx: 'a> ty::fold::TypeFolder<'tcx, 'tcx> for Folder<'a, 'tcx> {
|
||||
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
self.tcx.trans_apply_param_substs_env(&self.substs, self.param_env, &t)
|
||||
}
|
||||
}
|
||||
let mut f = Folder { tcx, param_env, substs };
|
||||
mir.fold_with(&mut f)
|
||||
}
|
||||
|
||||
/**
|
||||
* Integrator.
|
||||
*
|
||||
|
38
src/test/run-pass/mir-inlining/ice-issue-45885.rs
Normal file
38
src/test/run-pass/mir-inlining/ice-issue-45885.rs
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags:-Zmir-opt-level=2
|
||||
|
||||
pub enum Enum {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
trait SliceIndex {
|
||||
type Output;
|
||||
fn get(&self) -> &Self::Output;
|
||||
}
|
||||
|
||||
impl SliceIndex for usize {
|
||||
type Output = Enum;
|
||||
#[inline(never)]
|
||||
fn get(&self) -> &Enum {
|
||||
&Enum::A
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn index<T: SliceIndex>(t: &T) -> &T::Output {
|
||||
t.get()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
match *index(&0) { Enum::A => true, _ => false };
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user