From afb52e1ca1c8b787a056d382ebd2288a53bdd1a5 Mon Sep 17 00:00:00 2001 From: sinkuu Date: Sun, 5 Nov 2017 22:57:53 +0900 Subject: [PATCH] Fix MIR inlining panic in generic function --- src/librustc/traits/trans/mod.rs | 54 +++++++++++++++++++ src/librustc/ty/instance.rs | 2 +- .../run-pass/mir-inlining/ice-issue-45493.rs | 26 +++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/mir-inlining/ice-issue-45493.rs diff --git a/src/librustc/traits/trans/mod.rs b/src/librustc/traits/trans/mod.rs index 761e7259204bf..73fdbfe8831e3 100644 --- a/src/librustc/traits/trans/mod.rs +++ b/src/librustc/traits/trans/mod.rs @@ -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( + 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> { @@ -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>(&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 ()> diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 253bee167c482..6ea953c3f7375 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -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 { diff --git a/src/test/run-pass/mir-inlining/ice-issue-45493.rs b/src/test/run-pass/mir-inlining/ice-issue-45493.rs new file mode 100644 index 0000000000000..bd178f0e5bdaf --- /dev/null +++ b/src/test/run-pass/mir-inlining/ice-issue-45493.rs @@ -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 or the MIT license +// , 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() { + let _: *mut A::Item = std::ptr::null_mut(); +} + +struct Foo; +impl Array for Foo { type Item = i32; } + +fn main() { + foo::(); +}