Skip to content

Commit

Permalink
Auto merge of #45723 - sinkuu:ice_45493, r=arielb1
Browse files Browse the repository at this point in the history
Fix MIR inlining panic in generic function

MIR inlining calls `Instance::resolve` with a substs containing param, and `trans_apply_param_substs` panics. ~~This PR fixes it by making `Instance::resolve` return `None` if `substs.has_param_types()`, though I'm not sure if this is a right fix.~~

Fixes #45493.
  • Loading branch information
bors committed Nov 5, 2017
2 parents 666687a + afb52e1 commit 3b82e4c
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 1 deletion.
54 changes: 54 additions & 0 deletions src/librustc/traits/trans/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,26 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
let substituted = self.erase_regions(&substituted);
AssociatedTypeNormalizer::new(self).fold(&substituted)
}

pub fn trans_apply_param_substs_env<T>(
self,
param_substs: &Substs<'tcx>,
param_env: ty::ParamEnv<'tcx>,
value: &T,
) -> T
where
T: TransNormalize<'tcx>,
{
debug!(
"apply_param_substs_env(param_substs={:?}, value={:?}, param_env={:?})",
param_substs,
value,
param_env,
);
let substituted = value.subst(self, param_substs);
let substituted = self.erase_regions(&substituted);
AssociatedTypeNormalizerEnv::new(self, param_env).fold(&substituted)
}
}

struct AssociatedTypeNormalizer<'a, 'gcx: 'a> {
Expand Down Expand Up @@ -134,6 +154,40 @@ impl<'a, 'gcx> TypeFolder<'gcx, 'gcx> for AssociatedTypeNormalizer<'a, 'gcx> {
}
}

struct AssociatedTypeNormalizerEnv<'a, 'gcx: 'a> {
tcx: TyCtxt<'a, 'gcx, 'gcx>,
param_env: ty::ParamEnv<'gcx>,
}

impl<'a, 'gcx> AssociatedTypeNormalizerEnv<'a, 'gcx> {
fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>, param_env: ty::ParamEnv<'gcx>) -> Self {
Self { tcx, param_env }
}

fn fold<T: TypeFoldable<'gcx>>(&mut self, value: &T) -> T {
if !value.has_projections() {
value.clone()
} else {
value.fold_with(self)
}
}
}

impl<'a, 'gcx> TypeFolder<'gcx, 'gcx> for AssociatedTypeNormalizerEnv<'a, 'gcx> {
fn tcx<'c>(&'c self) -> TyCtxt<'c, 'gcx, 'gcx> {
self.tcx
}

fn fold_ty(&mut self, ty: Ty<'gcx>) -> Ty<'gcx> {
if !ty.has_projections() {
ty
} else {
debug!("AssociatedTypeNormalizerEnv: ty={:?}", ty);
self.tcx.normalize_associated_type_in_env(&ty, self.param_env)
}
}
}

// Implement DepTrackingMapConfig for `trait_cache`
pub struct TraitSelectionCache<'tcx> {
data: PhantomData<&'tcx ()>
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ impl<'a, 'b, 'tcx> Instance<'tcx> {
resolve_associated_item(tcx, &item, param_env, trait_def_id, substs)
} else {
let ty = tcx.type_of(def_id);
let item_type = tcx.trans_apply_param_substs(substs, &ty);
let item_type = tcx.trans_apply_param_substs_env(substs, param_env, &ty);

let def = match item_type.sty {
ty::TyFnDef(..) if {
Expand Down
26 changes: 26 additions & 0 deletions src/test/run-pass/mir-inlining/ice-issue-45493.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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

trait Array {
type Item;
}

fn foo<A: Array>() {
let _: *mut A::Item = std::ptr::null_mut();
}

struct Foo;
impl Array for Foo { type Item = i32; }

fn main() {
foo::<Foo>();
}

0 comments on commit 3b82e4c

Please sign in to comment.