Fix MIR inlining panic in generic function
This commit is contained in:
parent
4efcc660f0
commit
afb52e1ca1
3 changed files with 81 additions and 1 deletions
|
@ -99,6 +99,26 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
|
||||||
let substituted = self.erase_regions(&substituted);
|
let substituted = self.erase_regions(&substituted);
|
||||||
AssociatedTypeNormalizer::new(self).fold(&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> {
|
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`
|
// Implement DepTrackingMapConfig for `trait_cache`
|
||||||
pub struct TraitSelectionCache<'tcx> {
|
pub struct TraitSelectionCache<'tcx> {
|
||||||
data: PhantomData<&'tcx ()>
|
data: PhantomData<&'tcx ()>
|
||||||
|
|
|
@ -144,7 +144,7 @@ impl<'a, 'b, 'tcx> Instance<'tcx> {
|
||||||
resolve_associated_item(tcx, &item, param_env, trait_def_id, substs)
|
resolve_associated_item(tcx, &item, param_env, trait_def_id, substs)
|
||||||
} else {
|
} else {
|
||||||
let ty = tcx.type_of(def_id);
|
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 {
|
let def = match item_type.sty {
|
||||||
ty::TyFnDef(..) if {
|
ty::TyFnDef(..) if {
|
||||||
|
|
26
src/test/run-pass/mir-inlining/ice-issue-45493.rs
Normal file
26
src/test/run-pass/mir-inlining/ice-issue-45493.rs
Normal file
|
@ -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>();
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue