Skip to content

Fix ICE when attempting to print closure generics #37459

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 31, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1142,8 +1142,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
AggregateKind::Adt(adt_def, variant, substs, _) => {
let variant_def = &adt_def.variants[variant];

ppaux::parameterized(fmt, substs, variant_def.did,
ppaux::Ns::Value, &[])?;
ppaux::parameterized(fmt, substs, variant_def.did, &[])?;

match variant_def.ctor_kind {
CtorKind::Const => Ok(()),
Expand Down Expand Up @@ -1238,7 +1237,7 @@ impl<'tcx> Debug for Literal<'tcx> {
use self::Literal::*;
match *self {
Item { def_id, substs } => {
ppaux::parameterized(fmt, substs, def_id, ppaux::Ns::Value, &[])
ppaux::parameterized(fmt, substs, def_id, &[])
}
Value { ref value } => {
write!(fmt, "const ")?;
Expand Down
52 changes: 35 additions & 17 deletions src/librustc/util/ppaux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// except according to those terms.

use hir::def_id::DefId;
use hir::map::definitions::DefPathData;
use ty::subst::{self, Subst};
use ty::{BrAnon, BrEnv, BrFresh, BrNamed};
use ty::{TyBool, TyChar, TyAdt};
Expand Down Expand Up @@ -56,17 +57,9 @@ fn fn_sig(f: &mut fmt::Formatter,
Ok(())
}

/// Namespace of the path given to parameterized to print.
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Ns {
Type,
Value
}

pub fn parameterized(f: &mut fmt::Formatter,
substs: &subst::Substs,
did: DefId,
ns: Ns,
projections: &[ty::ProjectionPredicate])
-> fmt::Result {
let mut verbose = false;
Expand All @@ -75,16 +68,42 @@ pub fn parameterized(f: &mut fmt::Formatter,
let mut num_regions = 0;
let mut num_types = 0;
let mut item_name = None;
let mut is_value_path = false;
let fn_trait_kind = ty::tls::with(|tcx| {
let mut generics = tcx.lookup_generics(did);
// Unfortunately, some kinds of items (e.g., closures) don't have
// generics. So walk back up the find the closest parent that DOES
// have them.
let mut item_def_id = did;
loop {
let key = tcx.def_key(item_def_id);
match key.disambiguated_data.data {
DefPathData::TypeNs(_) => {
break;
}
DefPathData::ValueNs(_) | DefPathData::EnumVariant(_) => {
is_value_path = true;
break;
}
_ => {
// if we're making a symbol for something, there ought
// to be a value or type-def or something in there
// *somewhere*
item_def_id.index = key.parent.unwrap_or_else(|| {
bug!("finding type for {:?}, encountered def-id {:?} with no \
parent", did, item_def_id);
});
}
}
}
let mut generics = tcx.lookup_generics(item_def_id);
let mut path_def_id = did;
verbose = tcx.sess.verbose();
has_self = generics.has_self;

let mut child_types = 0;
if let Some(def_id) = generics.parent {
// Methods.
assert_eq!(ns, Ns::Value);
assert!(is_value_path);
child_types = generics.types.len();
generics = tcx.lookup_generics(def_id);
num_regions = generics.regions.len();
Expand All @@ -97,7 +116,7 @@ pub fn parameterized(f: &mut fmt::Formatter,
item_name = Some(tcx.item_name(did));
path_def_id = def_id;
} else {
if ns == Ns::Value {
if is_value_path {
// Functions.
assert_eq!(has_self, false);
} else {
Expand Down Expand Up @@ -192,7 +211,7 @@ pub fn parameterized(f: &mut fmt::Formatter,
start_or_continue(f, "", ">")?;

// For values, also print their name and type parameters.
if ns == Ns::Value {
if is_value_path {
empty.set(true);

if has_self {
Expand Down Expand Up @@ -298,7 +317,6 @@ impl<'tcx> fmt::Display for TraitAndProjections<'tcx> {
let TraitAndProjections(ref trait_ref, ref projection_bounds) = *self;
parameterized(f, trait_ref.substs,
trait_ref.def_id,
Ns::Type,
projection_bounds)
}
}
Expand Down Expand Up @@ -398,7 +416,7 @@ impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> {
let trait_ref = tcx.lift(&ty::Binder(*self))
.expect("could not lift TraitRef for printing")
.with_self_ty(tcx, dummy_self).0;
parameterized(f, trait_ref.substs, trait_ref.def_id, Ns::Type, &[])
parameterized(f, trait_ref.substs, trait_ref.def_id, &[])
})
}
}
Expand Down Expand Up @@ -798,7 +816,7 @@ impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<&'tcx 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, &[])
parameterized(f, self.substs, self.def_id, &[])
}
}

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

write!(f, "{} {{", bare_fn.sig.0)?;
parameterized(f, substs, def_id, Ns::Value, &[])?;
parameterized(f, substs, def_id, &[])?;
write!(f, "}}")
}
TyFnPtr(ref bare_fn) => {
Expand All @@ -874,7 +892,7 @@ 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, &[])
parameterized(f, substs, def.did, &[])
}
})
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/monomorphize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub struct Instance<'tcx> {

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

Expand Down