Auto merge of #33622 - arielb1:elaborate-drops, r=nikomatsakis
[MIR] non-zeroing drop This enables non-zeroing drop through stack flags for MIR. Fixes #30380. Fixes #5016.
This commit is contained in:
commit
f97c411548
42 changed files with 2100 additions and 317 deletions
|
|
@ -624,6 +624,24 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
|
|||
value.trans_normalize(&infcx)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn normalize_associated_type_in_env<T>(
|
||||
self, value: &T, env: &'a ty::ParameterEnvironment<'tcx>
|
||||
) -> T
|
||||
where T: TransNormalize<'tcx>
|
||||
{
|
||||
debug!("normalize_associated_type_in_env(t={:?})", value);
|
||||
|
||||
let value = self.erase_regions(value);
|
||||
|
||||
if !value.has_projection_types() {
|
||||
return value;
|
||||
}
|
||||
|
||||
self.infer_ctxt(None, Some(env.clone()), ProjectionMode::Any).enter(|infcx| {
|
||||
value.trans_normalize(&infcx)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ pub trait CrateStore<'tcx> {
|
|||
-> ty::TypeScheme<'tcx>;
|
||||
fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>>;
|
||||
fn item_name(&self, def: DefId) -> ast::Name;
|
||||
fn opt_item_name(&self, def: DefId) -> Option<ast::Name>;
|
||||
fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
-> ty::GenericPredicates<'tcx>;
|
||||
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
|
|
@ -345,6 +346,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
|
|||
bug!("visible_parent_map")
|
||||
}
|
||||
fn item_name(&self, def: DefId) -> ast::Name { bug!("item_name") }
|
||||
fn opt_item_name(&self, def: DefId) -> Option<ast::Name> { bug!("opt_item_name") }
|
||||
fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
-> ty::GenericPredicates<'tcx> { bug!("item_predicates") }
|
||||
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
|
|
|
|||
|
|
@ -330,11 +330,19 @@ pub enum TerminatorKind<'tcx> {
|
|||
|
||||
/// Drop the Lvalue
|
||||
Drop {
|
||||
value: Lvalue<'tcx>,
|
||||
location: Lvalue<'tcx>,
|
||||
target: BasicBlock,
|
||||
unwind: Option<BasicBlock>
|
||||
},
|
||||
|
||||
/// Drop the Lvalue and assign the new value over it
|
||||
DropAndReplace {
|
||||
location: Lvalue<'tcx>,
|
||||
value: Operand<'tcx>,
|
||||
target: BasicBlock,
|
||||
unwind: Option<BasicBlock>,
|
||||
},
|
||||
|
||||
/// Block ends with a call of a converging function
|
||||
Call {
|
||||
/// The function that’s being called
|
||||
|
|
@ -373,8 +381,14 @@ impl<'tcx> TerminatorKind<'tcx> {
|
|||
slice::ref_slice(t).into_cow(),
|
||||
Call { destination: None, cleanup: Some(ref c), .. } => slice::ref_slice(c).into_cow(),
|
||||
Call { destination: None, cleanup: None, .. } => (&[]).into_cow(),
|
||||
Drop { target, unwind: Some(unwind), .. } => vec![target, unwind].into_cow(),
|
||||
Drop { ref target, .. } => slice::ref_slice(target).into_cow(),
|
||||
DropAndReplace { target, unwind: Some(unwind), .. } |
|
||||
Drop { target, unwind: Some(unwind), .. } => {
|
||||
vec![target, unwind].into_cow()
|
||||
}
|
||||
DropAndReplace { ref target, unwind: None, .. } |
|
||||
Drop { ref target, unwind: None, .. } => {
|
||||
slice::ref_slice(target).into_cow()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -393,8 +407,12 @@ impl<'tcx> TerminatorKind<'tcx> {
|
|||
Call { destination: Some((_, ref mut t)), cleanup: None, .. } => vec![t],
|
||||
Call { destination: None, cleanup: Some(ref mut c), .. } => vec![c],
|
||||
Call { destination: None, cleanup: None, .. } => vec![],
|
||||
DropAndReplace { ref mut target, unwind: Some(ref mut unwind), .. } |
|
||||
Drop { ref mut target, unwind: Some(ref mut unwind), .. } => vec![target, unwind],
|
||||
Drop { ref mut target, .. } => vec![target]
|
||||
DropAndReplace { ref mut target, unwind: None, .. } |
|
||||
Drop { ref mut target, unwind: None, .. } => {
|
||||
vec![target]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -461,7 +479,9 @@ impl<'tcx> TerminatorKind<'tcx> {
|
|||
SwitchInt { discr: ref lv, .. } => write!(fmt, "switchInt({:?})", lv),
|
||||
Return => write!(fmt, "return"),
|
||||
Resume => write!(fmt, "resume"),
|
||||
Drop { ref value, .. } => write!(fmt, "drop({:?})", value),
|
||||
Drop { ref location, .. } => write!(fmt, "drop({:?})", location),
|
||||
DropAndReplace { ref location, ref value, .. } =>
|
||||
write!(fmt, "replace({:?} <- {:?})", location, value),
|
||||
Call { ref func, ref args, ref destination, .. } => {
|
||||
if let Some((ref destination, _)) = *destination {
|
||||
write!(fmt, "{:?} = ", destination)?;
|
||||
|
|
@ -506,8 +526,12 @@ impl<'tcx> TerminatorKind<'tcx> {
|
|||
Call { destination: Some(_), cleanup: None, .. } => vec!["return".into_cow()],
|
||||
Call { destination: None, cleanup: Some(_), .. } => vec!["unwind".into_cow()],
|
||||
Call { destination: None, cleanup: None, .. } => vec![],
|
||||
DropAndReplace { unwind: None, .. } |
|
||||
Drop { unwind: None, .. } => vec!["return".into_cow()],
|
||||
Drop { .. } => vec!["return".into_cow(), "unwind".into_cow()],
|
||||
DropAndReplace { unwind: Some(_), .. } |
|
||||
Drop { unwind: Some(_), .. } => {
|
||||
vec!["return".into_cow(), "unwind".into_cow()]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -918,7 +942,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
|
|||
ppaux::parameterized(fmt, substs, variant_def.did,
|
||||
ppaux::Ns::Value, &[],
|
||||
|tcx| {
|
||||
tcx.lookup_item_type(variant_def.did).generics
|
||||
Some(tcx.lookup_item_type(variant_def.did).generics)
|
||||
})?;
|
||||
|
||||
match variant_def.kind() {
|
||||
|
|
@ -1010,8 +1034,9 @@ impl<'tcx> Debug for Literal<'tcx> {
|
|||
use self::Literal::*;
|
||||
match *self {
|
||||
Item { def_id, substs } => {
|
||||
ppaux::parameterized(fmt, substs, def_id, ppaux::Ns::Value, &[],
|
||||
|tcx| tcx.lookup_item_type(def_id).generics)
|
||||
ppaux::parameterized(
|
||||
fmt, substs, def_id, ppaux::Ns::Value, &[],
|
||||
|tcx| Some(tcx.lookup_item_type(def_id).generics))
|
||||
}
|
||||
Value { ref value } => {
|
||||
write!(fmt, "const ")?;
|
||||
|
|
|
|||
|
|
@ -394,10 +394,20 @@ macro_rules! make_mir_visitor {
|
|||
TerminatorKind::Return => {
|
||||
}
|
||||
|
||||
TerminatorKind::Drop { ref $($mutability)* value,
|
||||
TerminatorKind::Drop { ref $($mutability)* location,
|
||||
target,
|
||||
unwind } => {
|
||||
self.visit_lvalue(value, LvalueContext::Drop);
|
||||
self.visit_lvalue(location, LvalueContext::Drop);
|
||||
self.visit_branch(block, target);
|
||||
unwind.map(|t| self.visit_branch(block, t));
|
||||
}
|
||||
|
||||
TerminatorKind::DropAndReplace { ref $($mutability)* location,
|
||||
ref $($mutability)* value,
|
||||
target,
|
||||
unwind } => {
|
||||
self.visit_lvalue(location, LvalueContext::Drop);
|
||||
self.visit_operand(value);
|
||||
self.visit_branch(block, target);
|
||||
unwind.map(|t| self.visit_branch(block, t));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use middle::cstore::LOCAL_CRATE;
|
|||
use hir::def_id::{DefId, CRATE_DEF_INDEX};
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use syntax::ast;
|
||||
use syntax::parse::token;
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
|
|
@ -138,7 +139,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
cur_path.push(self.sess.cstore.item_name(cur_def));
|
||||
cur_path.push(self.sess.cstore.opt_item_name(cur_def).unwrap_or_else(||
|
||||
token::intern("<unnamed>")));
|
||||
match visible_parent_map.get(&cur_def) {
|
||||
Some(&def) => cur_def = def,
|
||||
None => return false,
|
||||
|
|
|
|||
|
|
@ -2503,6 +2503,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
|| self.sess.cstore.item_type(self.global_tcx(), did))
|
||||
}
|
||||
|
||||
pub fn opt_lookup_item_type(self, did: DefId) -> Option<TypeScheme<'gcx>> {
|
||||
if let Some(scheme) = self.tcache.borrow_mut().get(&did) {
|
||||
return Some(scheme.clone());
|
||||
}
|
||||
|
||||
if did.krate == LOCAL_CRATE {
|
||||
None
|
||||
} else {
|
||||
Some(self.sess.cstore.item_type(self.global_tcx(), did))
|
||||
}
|
||||
}
|
||||
|
||||
/// Given the did of a trait, returns its canonical trait ref.
|
||||
pub fn lookup_trait_def(self, did: DefId) -> &'gcx TraitDef<'gcx> {
|
||||
lookup_locally_or_in_crate_store(
|
||||
|
|
|
|||
|
|
@ -69,15 +69,12 @@ pub enum Ns {
|
|||
Value
|
||||
}
|
||||
|
||||
fn number_of_supplied_defaults<'a, 'gcx, 'tcx, GG>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
substs: &subst::Substs,
|
||||
space: subst::ParamSpace,
|
||||
get_generics: GG)
|
||||
-> usize
|
||||
where GG: FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> ty::Generics<'tcx>
|
||||
fn number_of_supplied_defaults<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
substs: &subst::Substs,
|
||||
space: subst::ParamSpace,
|
||||
generics: ty::Generics<'tcx>)
|
||||
-> usize
|
||||
{
|
||||
let generics = get_generics(tcx);
|
||||
|
||||
let has_self = substs.self_ty().is_some();
|
||||
let ty_params = generics.types.get_slice(space);
|
||||
let tps = substs.types.get_slice(space);
|
||||
|
|
@ -115,7 +112,8 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
|
|||
projections: &[ty::ProjectionPredicate],
|
||||
get_generics: GG)
|
||||
-> fmt::Result
|
||||
where GG: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> ty::Generics<'tcx>
|
||||
where GG: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>)
|
||||
-> Option<ty::Generics<'tcx>>
|
||||
{
|
||||
if let (Ns::Value, Some(self_ty)) = (ns, substs.self_ty()) {
|
||||
write!(f, "<{} as ", self_ty)?;
|
||||
|
|
@ -176,13 +174,12 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
|
|||
let num_supplied_defaults = if verbose {
|
||||
0
|
||||
} else {
|
||||
// It is important to execute this conditionally, only if -Z
|
||||
// verbose is false. Otherwise, debug logs can sometimes cause
|
||||
// ICEs trying to fetch the generics early in the pipeline. This
|
||||
// is kind of a hacky workaround in that -Z verbose is required to
|
||||
// avoid those ICEs.
|
||||
ty::tls::with(|tcx| {
|
||||
number_of_supplied_defaults(tcx, substs, subst::TypeSpace, get_generics)
|
||||
if let Some(generics) = get_generics(tcx) {
|
||||
number_of_supplied_defaults(tcx, substs, subst::TypeSpace, generics)
|
||||
} else {
|
||||
0
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
|
|
@ -312,7 +309,7 @@ impl<'tcx> fmt::Display for TraitAndProjections<'tcx> {
|
|||
trait_ref.def_id,
|
||||
Ns::Type,
|
||||
projection_bounds,
|
||||
|tcx| tcx.lookup_trait_def(trait_ref.def_id).generics.clone())
|
||||
|tcx| Some(tcx.lookup_trait_def(trait_ref.def_id).generics.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -814,7 +811,7 @@ impl fmt::Display for ty::Binder<ty::OutlivesPredicate<ty::Region, ty::Region>>
|
|||
impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
parameterized(f, self.substs, self.def_id, Ns::Type, &[],
|
||||
|tcx| tcx.lookup_trait_def(self.def_id).generics.clone())
|
||||
|tcx| Some(tcx.lookup_trait_def(self.def_id).generics.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -866,8 +863,9 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
|
|||
}
|
||||
|
||||
write!(f, "{} {{", bare_fn.sig.0)?;
|
||||
parameterized(f, substs, def_id, Ns::Value, &[],
|
||||
|tcx| tcx.lookup_item_type(def_id).generics)?;
|
||||
parameterized(
|
||||
f, substs, def_id, Ns::Value, &[],
|
||||
|tcx| tcx.opt_lookup_item_type(def_id).map(|t| t.generics))?;
|
||||
write!(f, "}}")
|
||||
}
|
||||
TyFnPtr(ref bare_fn) => {
|
||||
|
|
@ -890,8 +888,12 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
|
|||
!tcx.tcache.borrow().contains_key(&def.did) {
|
||||
write!(f, "{}<..>", tcx.item_path_str(def.did))
|
||||
} else {
|
||||
parameterized(f, substs, def.did, Ns::Type, &[],
|
||||
|tcx| tcx.lookup_item_type(def.did).generics)
|
||||
parameterized(
|
||||
f, substs, def.did, Ns::Type, &[],
|
||||
|tcx| {
|
||||
tcx.opt_lookup_item_type(def.did).
|
||||
map(|t| t.generics)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue