diff options
| author | sinkuu <sinkuu@sinkuu.xyz> | 2017-11-05 22:57:53 +0900 |
|---|---|---|
| committer | sinkuu <sinkuu@sinkuu.xyz> | 2017-11-05 22:57:53 +0900 |
| commit | afb52e1ca1c8b787a056d382ebd2288a53bdd1a5 (patch) | |
| tree | bd60929c1e4275e8614c2fbdadfa492305f5303c /src | |
| parent | 4efcc660f09ce3e83d194889f6d1161bf865f788 (diff) | |
| download | rust-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.rs | 54 | ||||
| -rw-r--r-- | src/librustc/ty/instance.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/mir-inlining/ice-issue-45493.rs | 26 |
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>(); +} |
