From 239df7be3772b8ec0687d10df878d46fbe89d921 Mon Sep 17 00:00:00 2001
From: scalexm <alexandre@scalexm.fr>
Date: Thu, 1 Nov 2018 14:32:32 +0100
Subject: [PATCH] Bypass ppaux for `Outlives` predicates

---
 src/librustc/traits/structural_impls.rs       | 38 +++++++++++++++++--
 src/librustc/util/ppaux.rs                    |  4 +-
 .../chalk_context/program_clauses.rs          |  2 +-
 src/test/ui/chalkify/lower_env2.stderr        |  6 +--
 src/test/ui/chalkify/lower_env3.stderr        |  4 +-
 src/test/ui/chalkify/lower_impl.stderr        |  2 +-
 src/test/ui/chalkify/lower_struct.stderr      |  4 +-
 .../chalkify/lower_trait_where_clause.stderr  |  6 +--
 8 files changed, 48 insertions(+), 18 deletions(-)

diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index 66d9c6711bb..3fed2f2e3dc 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -442,11 +442,41 @@ impl<'tcx> fmt::Display for traits::WhereClause<'tcx> {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         use traits::WhereClause::*;
 
+        // Bypass ppaux because it does not print out anonymous regions.
+        fn write_region_name<'tcx>(
+            r: ty::Region<'tcx>,
+            fmt: &mut fmt::Formatter<'_>
+        ) -> fmt::Result {
+            match r {
+                ty::ReLateBound(index, br) => match br {
+                    ty::BoundRegion::BrNamed(_, name) => write!(fmt, "{}", name),
+                    ty::BoundRegion::BrAnon(var) => {
+                        if *index == ty::INNERMOST {
+                            write!(fmt, "'^{}", var)
+                        } else {
+                            write!(fmt, "'^{}_{}", index.index(), var)
+                        }
+                    }
+                    _ => write!(fmt, "'_"),
+                }
+
+                _ => write!(fmt, "{}", r),
+            }
+        }
+
         match self {
             Implemented(trait_ref) => write!(fmt, "Implemented({})", trait_ref),
             ProjectionEq(projection) => write!(fmt, "ProjectionEq({})", projection),
-            RegionOutlives(predicate) => write!(fmt, "RegionOutlives({})", predicate),
-            TypeOutlives(predicate) => write!(fmt, "TypeOutlives({})", predicate),
+            RegionOutlives(predicate) => {
+                write!(fmt, "RegionOutlives({}: ", predicate.0)?;
+                write_region_name(predicate.1, fmt)?;
+                write!(fmt, ")")
+            }
+            TypeOutlives(predicate) => {
+                write!(fmt, "TypeOutlives({}: ", predicate.0)?;
+                write_region_name(predicate.1, fmt)?;
+                write!(fmt, ")")
+            }
         }
     }
 }
@@ -567,7 +597,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector {
                     match bound_ty.kind {
                         ty::BoundTyKind::Param(name) => name,
                         ty::BoundTyKind::Anon => Symbol::intern(
-                            &format!("?{}", bound_ty.var.as_u32())
+                            &format!("^{}", bound_ty.var.as_u32())
                         ).as_interned_str(),
                     }
                 );
@@ -591,7 +621,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector {
 
                     ty::BoundRegion::BrAnon(var) => {
                         self.regions.insert(Symbol::intern(
-                            &format!("?'{}", var)
+                            &format!("'^{}", var)
                         ).as_interned_str());
                     }
 
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 5ec4f55b142..e44c0c05bb1 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -1114,9 +1114,9 @@ define_print! {
                     match bound_ty.kind {
                         ty::BoundTyKind::Anon => {
                             if bound_ty.index == ty::INNERMOST {
-                                write!(f, "?{}", bound_ty.var.index())
+                                write!(f, "^{}", bound_ty.var.index())
                             } else {
-                                write!(f, "?{}_{}", bound_ty.index.index(), bound_ty.var.index())
+                                write!(f, "^{}_{}", bound_ty.index.index(), bound_ty.var.index())
                             }
                         }
 
diff --git a/src/librustc_traits/chalk_context/program_clauses.rs b/src/librustc_traits/chalk_context/program_clauses.rs
index 20d23a5bd28..31f97b72e19 100644
--- a/src/librustc_traits/chalk_context/program_clauses.rs
+++ b/src/librustc_traits/chalk_context/program_clauses.rs
@@ -191,7 +191,7 @@ fn program_clauses_for_tuple<'tcx>(
             .map(|i| ty::BoundTy::new(ty::INNERMOST, ty::BoundVar::from(i)))
             .map(|t| tcx.mk_ty(ty::Bound(t)))
     );
-    
+
     let tuple_ty = tcx.mk_ty(ty::Tuple(type_list));
 
     let sized_trait = match tcx.lang_items().sized_trait() {
diff --git a/src/test/ui/chalkify/lower_env2.stderr b/src/test/ui/chalkify/lower_env2.stderr
index aaf6eda641d..74833ef064f 100644
--- a/src/test/ui/chalkify/lower_env2.stderr
+++ b/src/test/ui/chalkify/lower_env2.stderr
@@ -5,8 +5,8 @@ LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: forall<'a, T> { FromEnv(T: Foo) :- FromEnv(S<'a, T>). }
-   = note: forall<'a, T> { TypeOutlives(T : 'a) :- FromEnv(S<'a, T>). }
-   = note: forall<'a, T> { WellFormed(S<'a, T>) :- Implemented(T: Foo), TypeOutlives(T : 'a). }
+   = note: forall<'a, T> { TypeOutlives(T: 'a) :- FromEnv(S<'a, T>). }
+   = note: forall<'a, T> { WellFormed(S<'a, T>) :- Implemented(T: Foo), TypeOutlives(T: 'a). }
 
 error: program clause dump
   --> $DIR/lower_env2.rs:21:1
@@ -15,7 +15,7 @@ LL | #[rustc_dump_env_program_clauses] //~ ERROR program clause dump
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: forall<'a, T> { FromEnv(T: Foo) :- FromEnv(S<'a, T>). }
-   = note: forall<'a, T> { TypeOutlives(T : 'a) :- FromEnv(S<'a, T>). }
+   = note: forall<'a, T> { TypeOutlives(T: 'a) :- FromEnv(S<'a, T>). }
    = note: forall<Self> { Implemented(Self: Foo) :- FromEnv(Self: Foo). }
    = note: forall<Self> { Implemented(Self: std::marker::Sized) :- FromEnv(Self: std::marker::Sized). }
 
diff --git a/src/test/ui/chalkify/lower_env3.stderr b/src/test/ui/chalkify/lower_env3.stderr
index 7c59b9046f5..eef6405f8f8 100644
--- a/src/test/ui/chalkify/lower_env3.stderr
+++ b/src/test/ui/chalkify/lower_env3.stderr
@@ -4,7 +4,7 @@ error: program clause dump
 LL |     #[rustc_dump_env_program_clauses] //~ ERROR program clause dump
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: forall<?'0, ?1> { TypeOutlives(?1 : ) :- FromEnv(&?1). }
+   = note: forall<'^0, ^1> { TypeOutlives(^1: '^0) :- FromEnv(&^1). }
    = note: forall<Self> { Implemented(Self: Foo) :- FromEnv(Self: Foo). }
 
 error: program clause dump
@@ -13,7 +13,7 @@ error: program clause dump
 LL |     #[rustc_dump_env_program_clauses] //~ ERROR program clause dump
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: forall<?'0, ?1> { TypeOutlives(?1 : ) :- FromEnv(&?1). }
+   = note: forall<'^0, ^1> { TypeOutlives(^1: '^0) :- FromEnv(&^1). }
    = note: forall<Self> { FromEnv(Self: std::marker::Sized) :- FromEnv(Self: std::clone::Clone). }
    = note: forall<Self> { Implemented(Self: std::clone::Clone) :- FromEnv(Self: std::clone::Clone). }
    = note: forall<Self> { Implemented(Self: std::marker::Sized) :- FromEnv(Self: std::marker::Sized). }
diff --git a/src/test/ui/chalkify/lower_impl.stderr b/src/test/ui/chalkify/lower_impl.stderr
index ed84fe4eb26..92a209f673d 100644
--- a/src/test/ui/chalkify/lower_impl.stderr
+++ b/src/test/ui/chalkify/lower_impl.stderr
@@ -4,7 +4,7 @@ error: program clause dump
 LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: forall<T> { Implemented(T: Foo) :- ProjectionEq(<T as std::iter::Iterator>::Item == i32), TypeOutlives(T : 'static), Implemented(T: std::iter::Iterator), Implemented(T: std::marker::Sized). }
+   = note: forall<T> { Implemented(T: Foo) :- ProjectionEq(<T as std::iter::Iterator>::Item == i32), TypeOutlives(T: 'static), Implemented(T: std::iter::Iterator), Implemented(T: std::marker::Sized). }
 
 error: program clause dump
   --> $DIR/lower_impl.rs:23:5
diff --git a/src/test/ui/chalkify/lower_struct.stderr b/src/test/ui/chalkify/lower_struct.stderr
index a12ee52a086..a0dd9369700 100644
--- a/src/test/ui/chalkify/lower_struct.stderr
+++ b/src/test/ui/chalkify/lower_struct.stderr
@@ -6,8 +6,8 @@ LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
    |
    = note: forall<'a, T> { FromEnv(T: std::marker::Sized) :- FromEnv(Foo<'a, T>). }
    = note: forall<'a, T> { FromEnv(std::boxed::Box<T>: std::clone::Clone) :- FromEnv(Foo<'a, T>). }
-   = note: forall<'a, T> { TypeOutlives(T : 'a) :- FromEnv(Foo<'a, T>). }
-   = note: forall<'a, T> { WellFormed(Foo<'a, T>) :- Implemented(T: std::marker::Sized), Implemented(std::boxed::Box<T>: std::clone::Clone), TypeOutlives(T : 'a). }
+   = note: forall<'a, T> { TypeOutlives(T: 'a) :- FromEnv(Foo<'a, T>). }
+   = note: forall<'a, T> { WellFormed(Foo<'a, T>) :- Implemented(T: std::marker::Sized), Implemented(std::boxed::Box<T>: std::clone::Clone), TypeOutlives(T: 'a). }
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/chalkify/lower_trait_where_clause.stderr b/src/test/ui/chalkify/lower_trait_where_clause.stderr
index f4f3effaaae..f04f53f2496 100644
--- a/src/test/ui/chalkify/lower_trait_where_clause.stderr
+++ b/src/test/ui/chalkify/lower_trait_where_clause.stderr
@@ -6,9 +6,9 @@ LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
    |
    = note: forall<'a, 'b, Self, T, U> { FromEnv(T: std::borrow::Borrow<U>) :- FromEnv(Self: Foo<'a, 'b, T, U>). }
    = note: forall<'a, 'b, Self, T, U> { Implemented(Self: Foo<'a, 'b, T, U>) :- FromEnv(Self: Foo<'a, 'b, T, U>). }
-   = note: forall<'a, 'b, Self, T, U> { RegionOutlives('a : 'b) :- FromEnv(Self: Foo<'a, 'b, T, U>). }
-   = note: forall<'a, 'b, Self, T, U> { TypeOutlives(U : 'b) :- FromEnv(Self: Foo<'a, 'b, T, U>). }
-   = note: forall<'a, 'b, Self, T, U> { WellFormed(Self: Foo<'a, 'b, T, U>) :- Implemented(Self: Foo<'a, 'b, T, U>), WellFormed(T: std::borrow::Borrow<U>), TypeOutlives(U : 'b), RegionOutlives('a : 'b), WellFormed(std::boxed::Box<T>). }
+   = note: forall<'a, 'b, Self, T, U> { RegionOutlives('a: 'b) :- FromEnv(Self: Foo<'a, 'b, T, U>). }
+   = note: forall<'a, 'b, Self, T, U> { TypeOutlives(U: 'b) :- FromEnv(Self: Foo<'a, 'b, T, U>). }
+   = note: forall<'a, 'b, Self, T, U> { WellFormed(Self: Foo<'a, 'b, T, U>) :- Implemented(Self: Foo<'a, 'b, T, U>), WellFormed(T: std::borrow::Borrow<U>), TypeOutlives(U: 'b), RegionOutlives('a: 'b), WellFormed(std::boxed::Box<T>). }
    = note: forall<'a, 'b, Self, T, U> { WellFormed(std::boxed::Box<T>) :- FromEnv(Self: Foo<'a, 'b, T, U>). }
 
 error: aborting due to previous error