]> git.lizzy.rs Git - rust.git/commitdiff
Modify `repr()` so that when `-Z verbose` is used, at least, it does not
authorNiko Matsakis <niko@alum.mit.edu>
Wed, 11 Feb 2015 15:29:46 +0000 (10:29 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Thu, 12 Feb 2015 18:29:51 +0000 (13:29 -0500)
fetch trait definitions. This allows is to be used early in the compiler
without triggering ICEs. Also make -Z verbose less horrifyingly ugly.

src/librustc/util/ppaux.rs

index 397d27db3b96171dfdb08a033460f341f1688ad5..0363978bada2530db3160b99b0f9ffa8443771aa 100644 (file)
@@ -395,8 +395,8 @@ fn infer_ty_to_string(cx: &ctxt, ty: ty::InferTy) -> String {
         }
         ty_enum(did, substs) | ty_struct(did, substs) => {
             let base = ty::item_path_str(cx, did);
-            let generics = ty::lookup_item_type(cx, did).generics;
-            parameterized(cx, &base, substs, &generics, did, &[])
+            parameterized(cx, &base, substs, did, &[],
+                          || ty::lookup_item_type(cx, did).generics)
         }
         ty_trait(ref data) => {
             data.user_string(cx)
@@ -444,23 +444,40 @@ pub fn explicit_self_category_to_str(category: &ty::ExplicitSelfCategory)
     }
 }
 
-pub fn parameterized<'tcx>(cx: &ctxt<'tcx>,
-                           base: &str,
-                           substs: &subst::Substs<'tcx>,
-                           generics: &ty::Generics<'tcx>,
-                           did: ast::DefId,
-                           projections: &[ty::ProjectionPredicate<'tcx>])
-                           -> String
+pub fn parameterized<'tcx,GG>(cx: &ctxt<'tcx>,
+                              base: &str,
+                              substs: &subst::Substs<'tcx>,
+                              did: ast::DefId,
+                              projections: &[ty::ProjectionPredicate<'tcx>],
+                              get_generics: GG)
+                              -> String
+    where GG : FnOnce() -> ty::Generics<'tcx>
 {
     if cx.sess.verbose() {
-        if substs.is_noop() {
-            return format!("{}", base);
-        } else {
-            return format!("{}<{},{}>",
-                           base,
-                           substs.regions.repr(cx),
-                           substs.types.repr(cx));
+        let mut strings = vec![];
+        match substs.regions {
+            subst::ErasedRegions => {
+                strings.push(format!(".."));
+            }
+            subst::NonerasedRegions(ref regions) => {
+                for region in regions.iter() {
+                    strings.push(region.repr(cx));
+                }
+            }
         }
+        for ty in substs.types.iter() {
+            strings.push(ty.repr(cx));
+        }
+        for projection in projections.iter() {
+            strings.push(format!("{}={}",
+                                 projection.projection_ty.item_name.user_string(cx),
+                                 projection.ty.user_string(cx)));
+        }
+        return if strings.is_empty() {
+            format!("{}", base)
+        } else {
+            format!("{}<{}>", base, strings.connect(","))
+        };
     }
 
     let mut strs = Vec::new();
@@ -484,6 +501,13 @@ pub fn parameterized<'tcx>(cx: &ctxt<'tcx>,
         }
     }
 
+    // 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.
+    let generics = get_generics();
+
     let tps = substs.types.get_slice(subst::TypeSpace);
     let ty_params = generics.types.get_slice(subst::TypeSpace);
     let has_defaults = ty_params.last().map_or(false, |def| def.default.is_some());
@@ -645,13 +669,12 @@ impl<'tcx> UserString<'tcx> for TraitAndProjections<'tcx> {
     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
         let &(ref trait_ref, ref projection_bounds) = self;
         let base = ty::item_path_str(tcx, trait_ref.def_id);
-        let trait_def = ty::lookup_trait_def(tcx, trait_ref.def_id);
         parameterized(tcx,
                       &base,
                       trait_ref.substs,
-                      &trait_def.generics,
                       trait_ref.def_id,
-                      &projection_bounds[])
+                      &projection_bounds[],
+                      || ty::lookup_trait_def(tcx, trait_ref.def_id).generics.clone())
     }
 }
 
@@ -687,10 +710,9 @@ fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
 }
 
 impl<'tcx> Repr<'tcx> for ty::TypeParameterDef<'tcx> {
-    fn repr(&self, tcx: &ctxt<'tcx>) -> String {
-        format!("TypeParameterDef({:?}, {}, {:?}/{})",
+    fn repr(&self, _tcx: &ctxt<'tcx>) -> String {
+        format!("TypeParameterDef({:?}, {:?}/{})",
                 self.def_id,
-                self.bounds.repr(tcx),
                 self.space,
                 self.index)
     }
@@ -781,11 +803,8 @@ fn repr(&self, tcx: &ctxt<'tcx>) -> String {
         // to enumerate the `for<...>` etc because the debruijn index
         // tells you everything you need to know.
         let base = ty::item_path_str(tcx, self.def_id);
-        let trait_def = ty::lookup_trait_def(tcx, self.def_id);
-        format!("TraitRef({}, {})",
-                self.substs.self_ty().repr(tcx),
-                parameterized(tcx, &base, self.substs,
-                              &trait_def.generics, self.def_id, &[]))
+        parameterized(tcx, &base, self.substs, self.def_id, &[],
+                      || ty::lookup_trait_def(tcx, self.def_id).generics.clone())
     }
 }
 
@@ -987,16 +1006,22 @@ fn repr(&self, tcx: &ctxt<'tcx>) -> String {
 
 impl<'tcx> Repr<'tcx> for ty::Generics<'tcx> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
-        format!("Generics(types: {}, regions: {}, predicates: {})",
+        format!("Generics(types: {}, regions: {})",
                 self.types.repr(tcx),
-                self.regions.repr(tcx),
+                self.regions.repr(tcx))
+    }
+}
+
+impl<'tcx> Repr<'tcx> for ty::GenericPredicates<'tcx> {
+    fn repr(&self, tcx: &ctxt<'tcx>) -> String {
+        format!("GenericPredicates(predicates: {})",
                 self.predicates.repr(tcx))
     }
 }
 
-impl<'tcx> Repr<'tcx> for ty::GenericBounds<'tcx> {
+impl<'tcx> Repr<'tcx> for ty::InstantiatedPredicates<'tcx> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
-        format!("GenericBounds({})",
+        format!("InstantiatedPredicates({})",
                 self.predicates.repr(tcx))
     }
 }
@@ -1249,9 +1274,8 @@ fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
 impl<'tcx> UserString<'tcx> for ty::TraitRef<'tcx> {
     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
         let path_str = ty::item_path_str(tcx, self.def_id);
-        let trait_def = ty::lookup_trait_def(tcx, self.def_id);
-        parameterized(tcx, &path_str, self.substs,
-                      &trait_def.generics, self.def_id, &[])
+        parameterized(tcx, &path_str, self.substs, self.def_id, &[],
+                      || ty::lookup_trait_def(tcx, self.def_id).generics.clone())
     }
 }