about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorsinkuu <sinkuu@sinkuu.xyz>2017-11-05 22:57:53 +0900
committersinkuu <sinkuu@sinkuu.xyz>2017-11-05 22:57:53 +0900
commitafb52e1ca1c8b787a056d382ebd2288a53bdd1a5 (patch)
treebd60929c1e4275e8614c2fbdadfa492305f5303c /src
parent4efcc660f09ce3e83d194889f6d1161bf865f788 (diff)
downloadrust-afb52e1ca1c8b787a056d382ebd2288a53bdd1a5.tar.gz
rust-afb52e1ca1c8b787a056d382ebd2288a53bdd1a5.zip
Fix MIR inlining panic in generic function
Diffstat (limited to 'src')
-rw-r--r--src/librustc/traits/trans/mod.rs54
-rw-r--r--src/librustc/ty/instance.rs2
-rw-r--r--src/test/run-pass/mir-inlining/ice-issue-45493.rs26
3 files changed, 81 insertions, 1 deletions
diff --git a/src/librustc/traits/trans/mod.rs b/src/librustc/traits/trans/mod.rs
index 761e7259204..73fdbfe8831 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<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> {
@@ -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 ()>
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index 253bee167c4..6ea953c3f73 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 00000000000..bd178f0e5bd
--- /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 <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>();
+}