Skip to content

Commit bdb399d

Browse files
Fix ICE when attempting to get closure generics.
1 parent aef5ca5 commit bdb399d

File tree

3 files changed

+38
-21
lines changed

3 files changed

+38
-21
lines changed

Diff for: src/librustc/mir/mod.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1142,8 +1142,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
11421142
AggregateKind::Adt(adt_def, variant, substs, _) => {
11431143
let variant_def = &adt_def.variants[variant];
11441144

1145-
ppaux::parameterized(fmt, substs, variant_def.did,
1146-
ppaux::Ns::Value, &[])?;
1145+
ppaux::parameterized(fmt, substs, variant_def.did, &[])?;
11471146

11481147
match variant_def.ctor_kind {
11491148
CtorKind::Const => Ok(()),
@@ -1238,7 +1237,7 @@ impl<'tcx> Debug for Literal<'tcx> {
12381237
use self::Literal::*;
12391238
match *self {
12401239
Item { def_id, substs } => {
1241-
ppaux::parameterized(fmt, substs, def_id, ppaux::Ns::Value, &[])
1240+
ppaux::parameterized(fmt, substs, def_id, &[])
12421241
}
12431242
Value { ref value } => {
12441243
write!(fmt, "const ")?;

Diff for: src/librustc/util/ppaux.rs

+35-17
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
use hir::def_id::DefId;
12+
use hir::map::definitions::DefPathData;
1213
use ty::subst::{self, Subst};
1314
use ty::{BrAnon, BrEnv, BrFresh, BrNamed};
1415
use ty::{TyBool, TyChar, TyAdt};
@@ -56,17 +57,9 @@ fn fn_sig(f: &mut fmt::Formatter,
5657
Ok(())
5758
}
5859

59-
/// Namespace of the path given to parameterized to print.
60-
#[derive(Copy, Clone, PartialEq, Debug)]
61-
pub enum Ns {
62-
Type,
63-
Value
64-
}
65-
6660
pub fn parameterized(f: &mut fmt::Formatter,
6761
substs: &subst::Substs,
6862
did: DefId,
69-
ns: Ns,
7063
projections: &[ty::ProjectionPredicate])
7164
-> fmt::Result {
7265
let mut verbose = false;
@@ -75,16 +68,42 @@ pub fn parameterized(f: &mut fmt::Formatter,
7568
let mut num_regions = 0;
7669
let mut num_types = 0;
7770
let mut item_name = None;
71+
let mut is_value_path = false;
7872
let fn_trait_kind = ty::tls::with(|tcx| {
79-
let mut generics = tcx.lookup_generics(did);
73+
// Unfortunately, some kinds of items (e.g., closures) don't have
74+
// generics. So walk back up the find the closest parent that DOES
75+
// have them.
76+
let mut item_def_id = did;
77+
loop {
78+
let key = tcx.def_key(item_def_id);
79+
match key.disambiguated_data.data {
80+
DefPathData::TypeNs(_) => {
81+
break;
82+
}
83+
DefPathData::ValueNs(_) | DefPathData::EnumVariant(_) => {
84+
is_value_path = true;
85+
break;
86+
}
87+
_ => {
88+
// if we're making a symbol for something, there ought
89+
// to be a value or type-def or something in there
90+
// *somewhere*
91+
item_def_id.index = key.parent.unwrap_or_else(|| {
92+
bug!("finding type for {:?}, encountered def-id {:?} with no \
93+
parent", did, item_def_id);
94+
});
95+
}
96+
}
97+
}
98+
let mut generics = tcx.lookup_generics(item_def_id);
8099
let mut path_def_id = did;
81100
verbose = tcx.sess.verbose();
82101
has_self = generics.has_self;
83102

84103
let mut child_types = 0;
85104
if let Some(def_id) = generics.parent {
86105
// Methods.
87-
assert_eq!(ns, Ns::Value);
106+
assert!(is_value_path);
88107
child_types = generics.types.len();
89108
generics = tcx.lookup_generics(def_id);
90109
num_regions = generics.regions.len();
@@ -97,7 +116,7 @@ pub fn parameterized(f: &mut fmt::Formatter,
97116
item_name = Some(tcx.item_name(did));
98117
path_def_id = def_id;
99118
} else {
100-
if ns == Ns::Value {
119+
if is_value_path {
101120
// Functions.
102121
assert_eq!(has_self, false);
103122
} else {
@@ -192,7 +211,7 @@ pub fn parameterized(f: &mut fmt::Formatter,
192211
start_or_continue(f, "", ">")?;
193212

194213
// For values, also print their name and type parameters.
195-
if ns == Ns::Value {
214+
if is_value_path {
196215
empty.set(true);
197216

198217
if has_self {
@@ -298,7 +317,6 @@ impl<'tcx> fmt::Display for TraitAndProjections<'tcx> {
298317
let TraitAndProjections(ref trait_ref, ref projection_bounds) = *self;
299318
parameterized(f, trait_ref.substs,
300319
trait_ref.def_id,
301-
Ns::Type,
302320
projection_bounds)
303321
}
304322
}
@@ -398,7 +416,7 @@ impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> {
398416
let trait_ref = tcx.lift(&ty::Binder(*self))
399417
.expect("could not lift TraitRef for printing")
400418
.with_self_ty(tcx, dummy_self).0;
401-
parameterized(f, trait_ref.substs, trait_ref.def_id, Ns::Type, &[])
419+
parameterized(f, trait_ref.substs, trait_ref.def_id, &[])
402420
})
403421
}
404422
}
@@ -798,7 +816,7 @@ impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<&'tcx ty::Region,
798816

799817
impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
800818
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
801-
parameterized(f, self.substs, self.def_id, Ns::Type, &[])
819+
parameterized(f, self.substs, self.def_id, &[])
802820
}
803821
}
804822

@@ -851,7 +869,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
851869
}
852870

853871
write!(f, "{} {{", bare_fn.sig.0)?;
854-
parameterized(f, substs, def_id, Ns::Value, &[])?;
872+
parameterized(f, substs, def_id, &[])?;
855873
write!(f, "}}")
856874
}
857875
TyFnPtr(ref bare_fn) => {
@@ -874,7 +892,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
874892
!tcx.tcache.borrow().contains_key(&def.did) {
875893
write!(f, "{}<..>", tcx.item_path_str(def.did))
876894
} else {
877-
parameterized(f, substs, def.did, Ns::Type, &[])
895+
parameterized(f, substs, def.did, &[])
878896
}
879897
})
880898
}

Diff for: src/librustc_trans/monomorphize.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub struct Instance<'tcx> {
2626

2727
impl<'tcx> fmt::Display for Instance<'tcx> {
2828
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29-
ppaux::parameterized(f, &self.substs, self.def, ppaux::Ns::Value, &[])
29+
ppaux::parameterized(f, &self.substs, self.def, &[])
3030
}
3131
}
3232

0 commit comments

Comments
 (0)