about summary refs log tree commit diff
diff options
context:
space:
mode:
authorjackh726 <jack.huey@umassmed.edu>2021-07-18 03:18:05 -0400
committerjackh726 <jack.huey@umassmed.edu>2021-07-18 03:35:54 -0400
commitb9ee2fb6d8ca9d70a173ae710f5073d5bf27eff6 (patch)
tree0ee882e5cecc79e04f65688bf2fb24b34081b101
parenteb0b95b55a0b38d91e834dd30902b67627ed2eb0 (diff)
downloadrust-b9ee2fb6d8ca9d70a173ae710f5073d5bf27eff6.tar.gz
rust-b9ee2fb6d8ca9d70a173ae710f5073d5bf27eff6.zip
When pretty printing, name placeholders as bound regions
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs142
-rw-r--r--src/test/ui/associated-types/hr-associated-type-projection-1.rs2
-rw-r--r--src/test/ui/associated-types/hr-associated-type-projection-1.stderr8
-rw-r--r--src/test/ui/closures/issue-41366.stderr2
-rw-r--r--src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr4
-rw-r--r--src/test/ui/issues/issue-43623.stderr2
-rw-r--r--src/test/ui/issues/issue-60283.stderr2
8 files changed, 118 insertions, 46 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index e3a79fe2653..75b1d78dac4 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -995,7 +995,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         let get_lifetimes = |sig| {
             use rustc_hir::def::Namespace;
             let mut s = String::new();
-            let (_, (sig, reg)) = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS)
+            let (_, sig, reg) = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS)
                 .name_all_regions(sig)
                 .unwrap();
             let lts: Vec<String> = reg.into_iter().map(|(_, kind)| kind.to_string()).collect();
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 6dfbd28f776..b5733bd2edc 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1776,13 +1776,73 @@ impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
     }
 }
 
+/// Folds through bound vars and placeholders, naming them
+struct RegionFolder<'a, 'tcx> {
+    tcx: TyCtxt<'tcx>,
+    current_index: ty::DebruijnIndex,
+    region_map: BTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
+    name: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
+}
+
+impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+
+    fn fold_binder<T: TypeFoldable<'tcx>>(
+        &mut self,
+        t: ty::Binder<'tcx, T>,
+    ) -> ty::Binder<'tcx, T> {
+        self.current_index.shift_in(1);
+        let t = t.super_fold_with(self);
+        self.current_index.shift_out(1);
+        t
+    }
+
+    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+        match *t.kind() {
+            _ if t.has_vars_bound_at_or_above(self.current_index) || t.has_placeholders() => {
+                return t.super_fold_with(self);
+            }
+            _ => {}
+        }
+        t
+    }
+
+    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
+        let name = &mut self.name;
+        let region = match *r {
+            ty::ReLateBound(_, br) => self.region_map.entry(br).or_insert_with(|| name(br)),
+            ty::RePlaceholder(ty::PlaceholderRegion { name: kind, .. }) => {
+                // If this is an anonymous placeholder, don't rename. Otherwise, in some
+                // async fns, we get a `for<'r> Send` bound
+                match kind {
+                    ty::BrAnon(_) | ty::BrEnv => r,
+                    _ => {
+                        // Index doesn't matter, since this is just for naming and these never get bound
+                        let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind };
+                        self.region_map.entry(br).or_insert_with(|| name(br))
+                    }
+                }
+            }
+            _ => return r,
+        };
+        if let ty::ReLateBound(debruijn1, br) = *region {
+            assert_eq!(debruijn1, ty::INNERMOST);
+            self.tcx.mk_region(ty::ReLateBound(self.current_index, br))
+        } else {
+            region
+        }
+    }
+}
+
 // HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`,
 // `region_index` and `used_region_names`.
 impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
     pub fn name_all_regions<T>(
         mut self,
         value: &ty::Binder<'tcx, T>,
-    ) -> Result<(Self, (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)), fmt::Error>
+    ) -> Result<(Self, T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>), fmt::Error>
     where
         T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
     {
@@ -1805,16 +1865,16 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
 
         let mut empty = true;
         let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
-            write!(
-                cx,
-                "{}",
-                if empty {
-                    empty = false;
-                    start
-                } else {
-                    cont
-                }
-            )
+            let w = if empty {
+                empty = false;
+                start
+            } else {
+                cont
+            };
+            let _ = write!(cx, "{}", w);
+        };
+        let do_continue = |cx: &mut Self, cont: Symbol| {
+            let _ = write!(cx, "{}", cont);
         };
 
         define_scoped_cx!(self);
@@ -1824,18 +1884,18 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
         // aren't named. Eventually, we might just want this as the default, but
         // this is not *quite* right and changes the ordering of some output
         // anyways.
-        let new_value = if self.tcx().sess.verbose() {
+        let (new_value, map) = if self.tcx().sess.verbose() {
             // anon index + 1 (BrEnv takes 0) -> name
             let mut region_map: BTreeMap<u32, Symbol> = BTreeMap::default();
             let bound_vars = value.bound_vars();
             for var in bound_vars {
                 match var {
                     ty::BoundVariableKind::Region(ty::BrNamed(_, name)) => {
-                        let _ = start_or_continue(&mut self, "for<", ", ");
-                        let _ = write!(self, "{}", name);
+                        start_or_continue(&mut self, "for<", ", ");
+                        do_continue(&mut self, name);
                     }
                     ty::BoundVariableKind::Region(ty::BrAnon(i)) => {
-                        let _ = start_or_continue(&mut self, "for<", ", ");
+                        start_or_continue(&mut self, "for<", ", ");
                         let name = loop {
                             let name = name_by_region_index(region_index);
                             region_index += 1;
@@ -1843,11 +1903,11 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
                                 break name;
                             }
                         };
-                        let _ = write!(self, "{}", name);
+                        do_continue(&mut self, name);
                         region_map.insert(i + 1, name);
                     }
                     ty::BoundVariableKind::Region(ty::BrEnv) => {
-                        let _ = start_or_continue(&mut self, "for<", ", ");
+                        start_or_continue(&mut self, "for<", ", ");
                         let name = loop {
                             let name = name_by_region_index(region_index);
                             region_index += 1;
@@ -1855,13 +1915,13 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
                                 break name;
                             }
                         };
-                        let _ = write!(self, "{}", name);
+                        do_continue(&mut self, name);
                         region_map.insert(0, name);
                     }
                     _ => continue,
                 }
             }
-            start_or_continue(&mut self, "", "> ")?;
+            start_or_continue(&mut self, "", "> ");
 
             self.tcx.replace_late_bound_regions(value.clone(), |br| {
                 let kind = match br.kind {
@@ -1881,11 +1941,12 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
                 ))
             })
         } else {
-            let new_value = self.tcx.replace_late_bound_regions(value.clone(), |br| {
-                let _ = start_or_continue(&mut self, "for<", ", ");
+            let tcx = self.tcx;
+            let mut name = |br: ty::BoundRegion| {
+                start_or_continue(&mut self, "for<", ", ");
                 let kind = match br.kind {
                     ty::BrNamed(_, name) => {
-                        let _ = write!(self, "{}", name);
+                        do_continue(&mut self, name);
                         br.kind
                     }
                     ty::BrAnon(_) | ty::BrEnv => {
@@ -1896,22 +1957,27 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
                                 break name;
                             }
                         };
-                        let _ = write!(self, "{}", name);
+                        do_continue(&mut self, name);
                         ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
                     }
                 };
-                self.tcx.mk_region(ty::ReLateBound(
-                    ty::INNERMOST,
-                    ty::BoundRegion { var: br.var, kind },
-                ))
-            });
-            start_or_continue(&mut self, "", "> ")?;
-            new_value
+                tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind }))
+            };
+            let mut folder = RegionFolder {
+                tcx,
+                current_index: ty::INNERMOST,
+                name: &mut name,
+                region_map: BTreeMap::new(),
+            };
+            let new_value = value.clone().skip_binder().fold_with(&mut folder);
+            let region_map = folder.region_map;
+            start_or_continue(&mut self, "", "> ");
+            (new_value, region_map)
         };
 
         self.binder_depth += 1;
         self.region_index = region_index;
-        Ok((self, new_value))
+        Ok((self, new_value, map))
     }
 
     pub fn pretty_in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, fmt::Error>
@@ -1919,8 +1985,8 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
         T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
     {
         let old_region_index = self.region_index;
-        let (new, new_value) = self.name_all_regions(value)?;
-        let mut inner = new_value.0.print(new)?;
+        let (new, new_value, _) = self.name_all_regions(value)?;
+        let mut inner = new_value.print(new)?;
         inner.region_index = old_region_index;
         inner.binder_depth -= 1;
         Ok(inner)
@@ -1935,8 +2001,8 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
         T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
     {
         let old_region_index = self.region_index;
-        let (new, new_value) = self.name_all_regions(value)?;
-        let mut inner = f(&new_value.0, new)?;
+        let (new, new_value, _) = self.name_all_regions(value)?;
+        let mut inner = f(&new_value, new)?;
         inner.region_index = old_region_index;
         inner.binder_depth -= 1;
         Ok(inner)
@@ -1960,6 +2026,12 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
                 debug!("LateBoundRegionNameCollector::visit_region(r: {:?}, address: {:p})", r, &r);
                 if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r {
                     self.used_region_names.insert(name);
+                } else if let ty::RePlaceholder(ty::PlaceholderRegion {
+                    name: ty::BrNamed(_, name),
+                    ..
+                }) = *r
+                {
+                    self.used_region_names.insert(name);
                 }
                 r.super_visit_with(self)
             }
diff --git a/src/test/ui/associated-types/hr-associated-type-projection-1.rs b/src/test/ui/associated-types/hr-associated-type-projection-1.rs
index 1270cd6706a..bad736b64c0 100644
--- a/src/test/ui/associated-types/hr-associated-type-projection-1.rs
+++ b/src/test/ui/associated-types/hr-associated-type-projection-1.rs
@@ -11,7 +11,7 @@ where
 }
 
 impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
-    //~^ ERROR the trait bound `<T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
+    //~^ ERROR the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
     type Item = T;
     //~^ ERROR the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref
 }
diff --git a/src/test/ui/associated-types/hr-associated-type-projection-1.stderr b/src/test/ui/associated-types/hr-associated-type-projection-1.stderr
index cf4ec0babfc..49fad4e1b1c 100644
--- a/src/test/ui/associated-types/hr-associated-type-projection-1.stderr
+++ b/src/test/ui/associated-types/hr-associated-type-projection-1.stderr
@@ -14,16 +14,16 @@ LL |     type Item = T;
              <&T as Deref>
              <&mut T as Deref>
 
-error[E0277]: the trait bound `<T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
+error[E0277]: the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
   --> $DIR/hr-associated-type-projection-1.rs:13:33
    |
 LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
-   |                                 ^^^^^^^^^^^^^^^^^ the trait `Deref` is not implemented for `<T as UnsafeCopy<'b, T>>::Item`
+   |                                 ^^^^^^^^^^^^^^^^^ the trait `for<'b> Deref` is not implemented for `<T as UnsafeCopy<'b, T>>::Item`
    |
 help: consider further restricting the associated type
    |
-LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T where <T as UnsafeCopy<'b, T>>::Item: Deref {
-   |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T where for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref {
+   |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/closures/issue-41366.stderr b/src/test/ui/closures/issue-41366.stderr
index 72ef5b3b962..ffe0bce6f0f 100644
--- a/src/test/ui/closures/issue-41366.stderr
+++ b/src/test/ui/closures/issue-41366.stderr
@@ -5,7 +5,7 @@ LL |     (&|_| ()) as &dyn for<'x> Fn(<u32 as T<'x>>::V);
    |     ^^------^
    |     | |
    |     | found signature of `fn(u16) -> _`
-   |     expected signature of `fn(<u32 as T<'x>>::V) -> _`
+   |     expected signature of `for<'x> fn(<u32 as T<'x>>::V) -> _`
    |
    = note: required for the cast to the object type `dyn for<'x> Fn(<u32 as T<'x>>::V)`
 
diff --git a/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr b/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr
index 7dabd97b94e..cfcef9699f3 100644
--- a/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr
+++ b/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr
@@ -1,10 +1,10 @@
-error[E0119]: conflicting implementations of trait `Trait` for type `for<'r> fn(fn(&'r ()))`
+error[E0119]: conflicting implementations of trait `Trait` for type `for<'r> fn(for<'r> fn(&'r ()))`
   --> $DIR/coherence-fn-covariant-bound-vs-static.rs:17:1
    |
 LL | impl Trait for for<'r> fn(fn(&'r ())) {}
    | ------------------------------------- first implementation here
 LL | impl<'a> Trait for fn(fn(&'a ())) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'r> fn(fn(&'r ()))`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'r> fn(for<'r> fn(&'r ()))`
    |
    = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
 
diff --git a/src/test/ui/issues/issue-43623.stderr b/src/test/ui/issues/issue-43623.stderr
index 80aca482b3d..4bc5eb03e92 100644
--- a/src/test/ui/issues/issue-43623.stderr
+++ b/src/test/ui/issues/issue-43623.stderr
@@ -10,7 +10,7 @@ LL | {
 LL |     break_me::<Type, fn(_)>;
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    |     |
-   |     expected signature of `fn(<Type as Trait<'b>>::Assoc) -> _`
+   |     expected signature of `for<'b> fn(<Type as Trait<'b>>::Assoc) -> _`
    |     found signature of `fn(()) -> _`
 
 error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-60283.stderr b/src/test/ui/issues/issue-60283.stderr
index 650570b6471..149562f8fb3 100644
--- a/src/test/ui/issues/issue-60283.stderr
+++ b/src/test/ui/issues/issue-60283.stderr
@@ -10,7 +10,7 @@ LL |     F: for<'a> FnMut(<T as Trait<'a>>::Item),
 LL |     foo((), drop)
    |             ^^^^
    |             |
-   |             expected signature of `fn(<() as Trait<'a>>::Item) -> _`
+   |             expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
    |             found signature of `fn(()) -> _`
 
 error[E0277]: the size for values of type `<() as Trait<'_>>::Item` cannot be known at compilation time