Skip to content

Commit f97c411

Browse files
committed
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.
2 parents ccfaaa7 + 063f882 commit f97c411

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2101
-318
lines changed

src/librustc/infer/mod.rs

+18
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,24 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
624624
value.trans_normalize(&infcx)
625625
})
626626
}
627+
628+
pub fn normalize_associated_type_in_env<T>(
629+
self, value: &T, env: &'a ty::ParameterEnvironment<'tcx>
630+
) -> T
631+
where T: TransNormalize<'tcx>
632+
{
633+
debug!("normalize_associated_type_in_env(t={:?})", value);
634+
635+
let value = self.erase_regions(value);
636+
637+
if !value.has_projection_types() {
638+
return value;
639+
}
640+
641+
self.infer_ctxt(None, Some(env.clone()), ProjectionMode::Any).enter(|infcx| {
642+
value.trans_normalize(&infcx)
643+
})
644+
}
627645
}
628646

629647
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {

src/librustc/middle/cstore.rs

+2
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ pub trait CrateStore<'tcx> {
163163
-> ty::TypeScheme<'tcx>;
164164
fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>>;
165165
fn item_name(&self, def: DefId) -> ast::Name;
166+
fn opt_item_name(&self, def: DefId) -> Option<ast::Name>;
166167
fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
167168
-> ty::GenericPredicates<'tcx>;
168169
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
@@ -345,6 +346,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
345346
bug!("visible_parent_map")
346347
}
347348
fn item_name(&self, def: DefId) -> ast::Name { bug!("item_name") }
349+
fn opt_item_name(&self, def: DefId) -> Option<ast::Name> { bug!("opt_item_name") }
348350
fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
349351
-> ty::GenericPredicates<'tcx> { bug!("item_predicates") }
350352
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)

src/librustc/mir/repr.rs

+34-9
Original file line numberDiff line numberDiff line change
@@ -330,11 +330,19 @@ pub enum TerminatorKind<'tcx> {
330330

331331
/// Drop the Lvalue
332332
Drop {
333-
value: Lvalue<'tcx>,
333+
location: Lvalue<'tcx>,
334334
target: BasicBlock,
335335
unwind: Option<BasicBlock>
336336
},
337337

338+
/// Drop the Lvalue and assign the new value over it
339+
DropAndReplace {
340+
location: Lvalue<'tcx>,
341+
value: Operand<'tcx>,
342+
target: BasicBlock,
343+
unwind: Option<BasicBlock>,
344+
},
345+
338346
/// Block ends with a call of a converging function
339347
Call {
340348
/// The function that’s being called
@@ -373,8 +381,14 @@ impl<'tcx> TerminatorKind<'tcx> {
373381
slice::ref_slice(t).into_cow(),
374382
Call { destination: None, cleanup: Some(ref c), .. } => slice::ref_slice(c).into_cow(),
375383
Call { destination: None, cleanup: None, .. } => (&[]).into_cow(),
376-
Drop { target, unwind: Some(unwind), .. } => vec![target, unwind].into_cow(),
377-
Drop { ref target, .. } => slice::ref_slice(target).into_cow(),
384+
DropAndReplace { target, unwind: Some(unwind), .. } |
385+
Drop { target, unwind: Some(unwind), .. } => {
386+
vec![target, unwind].into_cow()
387+
}
388+
DropAndReplace { ref target, unwind: None, .. } |
389+
Drop { ref target, unwind: None, .. } => {
390+
slice::ref_slice(target).into_cow()
391+
}
378392
}
379393
}
380394

@@ -393,8 +407,12 @@ impl<'tcx> TerminatorKind<'tcx> {
393407
Call { destination: Some((_, ref mut t)), cleanup: None, .. } => vec![t],
394408
Call { destination: None, cleanup: Some(ref mut c), .. } => vec![c],
395409
Call { destination: None, cleanup: None, .. } => vec![],
410+
DropAndReplace { ref mut target, unwind: Some(ref mut unwind), .. } |
396411
Drop { ref mut target, unwind: Some(ref mut unwind), .. } => vec![target, unwind],
397-
Drop { ref mut target, .. } => vec![target]
412+
DropAndReplace { ref mut target, unwind: None, .. } |
413+
Drop { ref mut target, unwind: None, .. } => {
414+
vec![target]
415+
}
398416
}
399417
}
400418
}
@@ -461,7 +479,9 @@ impl<'tcx> TerminatorKind<'tcx> {
461479
SwitchInt { discr: ref lv, .. } => write!(fmt, "switchInt({:?})", lv),
462480
Return => write!(fmt, "return"),
463481
Resume => write!(fmt, "resume"),
464-
Drop { ref value, .. } => write!(fmt, "drop({:?})", value),
482+
Drop { ref location, .. } => write!(fmt, "drop({:?})", location),
483+
DropAndReplace { ref location, ref value, .. } =>
484+
write!(fmt, "replace({:?} <- {:?})", location, value),
465485
Call { ref func, ref args, ref destination, .. } => {
466486
if let Some((ref destination, _)) = *destination {
467487
write!(fmt, "{:?} = ", destination)?;
@@ -506,8 +526,12 @@ impl<'tcx> TerminatorKind<'tcx> {
506526
Call { destination: Some(_), cleanup: None, .. } => vec!["return".into_cow()],
507527
Call { destination: None, cleanup: Some(_), .. } => vec!["unwind".into_cow()],
508528
Call { destination: None, cleanup: None, .. } => vec![],
529+
DropAndReplace { unwind: None, .. } |
509530
Drop { unwind: None, .. } => vec!["return".into_cow()],
510-
Drop { .. } => vec!["return".into_cow(), "unwind".into_cow()],
531+
DropAndReplace { unwind: Some(_), .. } |
532+
Drop { unwind: Some(_), .. } => {
533+
vec!["return".into_cow(), "unwind".into_cow()]
534+
}
511535
}
512536
}
513537
}
@@ -918,7 +942,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
918942
ppaux::parameterized(fmt, substs, variant_def.did,
919943
ppaux::Ns::Value, &[],
920944
|tcx| {
921-
tcx.lookup_item_type(variant_def.did).generics
945+
Some(tcx.lookup_item_type(variant_def.did).generics)
922946
})?;
923947

924948
match variant_def.kind() {
@@ -1010,8 +1034,9 @@ impl<'tcx> Debug for Literal<'tcx> {
10101034
use self::Literal::*;
10111035
match *self {
10121036
Item { def_id, substs } => {
1013-
ppaux::parameterized(fmt, substs, def_id, ppaux::Ns::Value, &[],
1014-
|tcx| tcx.lookup_item_type(def_id).generics)
1037+
ppaux::parameterized(
1038+
fmt, substs, def_id, ppaux::Ns::Value, &[],
1039+
|tcx| Some(tcx.lookup_item_type(def_id).generics))
10151040
}
10161041
Value { ref value } => {
10171042
write!(fmt, "const ")?;

src/librustc/mir/visit.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -394,10 +394,20 @@ macro_rules! make_mir_visitor {
394394
TerminatorKind::Return => {
395395
}
396396

397-
TerminatorKind::Drop { ref $($mutability)* value,
397+
TerminatorKind::Drop { ref $($mutability)* location,
398398
target,
399399
unwind } => {
400-
self.visit_lvalue(value, LvalueContext::Drop);
400+
self.visit_lvalue(location, LvalueContext::Drop);
401+
self.visit_branch(block, target);
402+
unwind.map(|t| self.visit_branch(block, t));
403+
}
404+
405+
TerminatorKind::DropAndReplace { ref $($mutability)* location,
406+
ref $($mutability)* value,
407+
target,
408+
unwind } => {
409+
self.visit_lvalue(location, LvalueContext::Drop);
410+
self.visit_operand(value);
401411
self.visit_branch(block, target);
402412
unwind.map(|t| self.visit_branch(block, t));
403413
}

src/librustc/ty/item_path.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use middle::cstore::LOCAL_CRATE;
1313
use hir::def_id::{DefId, CRATE_DEF_INDEX};
1414
use ty::{self, Ty, TyCtxt};
1515
use syntax::ast;
16+
use syntax::parse::token;
1617

1718
use std::cell::Cell;
1819

@@ -138,7 +139,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
138139
}
139140
}
140141

141-
cur_path.push(self.sess.cstore.item_name(cur_def));
142+
cur_path.push(self.sess.cstore.opt_item_name(cur_def).unwrap_or_else(||
143+
token::intern("<unnamed>")));
142144
match visible_parent_map.get(&cur_def) {
143145
Some(&def) => cur_def = def,
144146
None => return false,

src/librustc/ty/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -2503,6 +2503,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
25032503
|| self.sess.cstore.item_type(self.global_tcx(), did))
25042504
}
25052505

2506+
pub fn opt_lookup_item_type(self, did: DefId) -> Option<TypeScheme<'gcx>> {
2507+
if let Some(scheme) = self.tcache.borrow_mut().get(&did) {
2508+
return Some(scheme.clone());
2509+
}
2510+
2511+
if did.krate == LOCAL_CRATE {
2512+
None
2513+
} else {
2514+
Some(self.sess.cstore.item_type(self.global_tcx(), did))
2515+
}
2516+
}
2517+
25062518
/// Given the did of a trait, returns its canonical trait ref.
25072519
pub fn lookup_trait_def(self, did: DefId) -> &'gcx TraitDef<'gcx> {
25082520
lookup_locally_or_in_crate_store(

src/librustc/util/ppaux.rs

+23-21
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,12 @@ pub enum Ns {
6969
Value
7070
}
7171

72-
fn number_of_supplied_defaults<'a, 'gcx, 'tcx, GG>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
73-
substs: &subst::Substs,
74-
space: subst::ParamSpace,
75-
get_generics: GG)
76-
-> usize
77-
where GG: FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> ty::Generics<'tcx>
72+
fn number_of_supplied_defaults<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
73+
substs: &subst::Substs,
74+
space: subst::ParamSpace,
75+
generics: ty::Generics<'tcx>)
76+
-> usize
7877
{
79-
let generics = get_generics(tcx);
80-
8178
let has_self = substs.self_ty().is_some();
8279
let ty_params = generics.types.get_slice(space);
8380
let tps = substs.types.get_slice(space);
@@ -115,7 +112,8 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
115112
projections: &[ty::ProjectionPredicate],
116113
get_generics: GG)
117114
-> fmt::Result
118-
where GG: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> ty::Generics<'tcx>
115+
where GG: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>)
116+
-> Option<ty::Generics<'tcx>>
119117
{
120118
if let (Ns::Value, Some(self_ty)) = (ns, substs.self_ty()) {
121119
write!(f, "<{} as ", self_ty)?;
@@ -176,13 +174,12 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
176174
let num_supplied_defaults = if verbose {
177175
0
178176
} else {
179-
// It is important to execute this conditionally, only if -Z
180-
// verbose is false. Otherwise, debug logs can sometimes cause
181-
// ICEs trying to fetch the generics early in the pipeline. This
182-
// is kind of a hacky workaround in that -Z verbose is required to
183-
// avoid those ICEs.
184177
ty::tls::with(|tcx| {
185-
number_of_supplied_defaults(tcx, substs, subst::TypeSpace, get_generics)
178+
if let Some(generics) = get_generics(tcx) {
179+
number_of_supplied_defaults(tcx, substs, subst::TypeSpace, generics)
180+
} else {
181+
0
182+
}
186183
})
187184
};
188185

@@ -312,7 +309,7 @@ impl<'tcx> fmt::Display for TraitAndProjections<'tcx> {
312309
trait_ref.def_id,
313310
Ns::Type,
314311
projection_bounds,
315-
|tcx| tcx.lookup_trait_def(trait_ref.def_id).generics.clone())
312+
|tcx| Some(tcx.lookup_trait_def(trait_ref.def_id).generics.clone()))
316313
}
317314
}
318315

@@ -814,7 +811,7 @@ impl fmt::Display for ty::Binder<ty::OutlivesPredicate<ty::Region, ty::Region>>
814811
impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
815812
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
816813
parameterized(f, self.substs, self.def_id, Ns::Type, &[],
817-
|tcx| tcx.lookup_trait_def(self.def_id).generics.clone())
814+
|tcx| Some(tcx.lookup_trait_def(self.def_id).generics.clone()))
818815
}
819816
}
820817

@@ -866,8 +863,9 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
866863
}
867864

868865
write!(f, "{} {{", bare_fn.sig.0)?;
869-
parameterized(f, substs, def_id, Ns::Value, &[],
870-
|tcx| tcx.lookup_item_type(def_id).generics)?;
866+
parameterized(
867+
f, substs, def_id, Ns::Value, &[],
868+
|tcx| tcx.opt_lookup_item_type(def_id).map(|t| t.generics))?;
871869
write!(f, "}}")
872870
}
873871
TyFnPtr(ref bare_fn) => {
@@ -890,8 +888,12 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
890888
!tcx.tcache.borrow().contains_key(&def.did) {
891889
write!(f, "{}<..>", tcx.item_path_str(def.did))
892890
} else {
893-
parameterized(f, substs, def.did, Ns::Type, &[],
894-
|tcx| tcx.lookup_item_type(def.did).generics)
891+
parameterized(
892+
f, substs, def.did, Ns::Type, &[],
893+
|tcx| {
894+
tcx.opt_lookup_item_type(def.did).
895+
map(|t| t.generics)
896+
})
895897
}
896898
})
897899
}

src/librustc_borrowck/borrowck/mir/dataflow/mod.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,12 @@ impl<'a, 'tcx: 'a, O> DataflowAnalysis<'a, 'tcx, O>
200200

201201
pub struct DataflowResults<O>(DataflowState<O>) where O: BitDenotation;
202202

203+
impl<O: BitDenotation> DataflowResults<O> {
204+
pub fn sets(&self) -> &AllSets<O::Idx> {
205+
&self.0.sets
206+
}
207+
}
208+
203209
// FIXME: This type shouldn't be public, but the graphviz::MirWithFlowState trait
204210
// references it in a method signature. Look into using `pub(crate)` to address this.
205211
pub struct DataflowState<O: BitDenotation>
@@ -444,10 +450,17 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D>
444450
repr::TerminatorKind::Return |
445451
repr::TerminatorKind::Resume => {}
446452
repr::TerminatorKind::Goto { ref target } |
447-
repr::TerminatorKind::Drop { ref target, value: _, unwind: None } => {
453+
repr::TerminatorKind::Drop { ref target, location: _, unwind: None } |
454+
455+
repr::TerminatorKind::DropAndReplace {
456+
ref target, value: _, location: _, unwind: None
457+
} => {
448458
self.propagate_bits_into_entry_set_for(in_out, changed, target);
449459
}
450-
repr::TerminatorKind::Drop { ref target, value: _, unwind: Some(ref unwind) } => {
460+
repr::TerminatorKind::Drop { ref target, location: _, unwind: Some(ref unwind) } |
461+
repr::TerminatorKind::DropAndReplace {
462+
ref target, value: _, location: _, unwind: Some(ref unwind)
463+
} => {
451464
self.propagate_bits_into_entry_set_for(in_out, changed, target);
452465
self.propagate_bits_into_entry_set_for(in_out, changed, unwind);
453466
}

0 commit comments

Comments
 (0)