Skip to content

Commit 8024983

Browse files
committed
Auto merge of #87246 - rust-lang:placeholder-pretty, r=nikomatsakis
When pretty printing, name placeholders as bound regions Split from #85499 When we see a placeholder that we are going to print, treat it as a bound var (and add it to a `for<...>`
2 parents 602150f + b9ee2fb commit 8024983

File tree

8 files changed

+118
-46
lines changed

8 files changed

+118
-46
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
995995
let get_lifetimes = |sig| {
996996
use rustc_hir::def::Namespace;
997997
let mut s = String::new();
998-
let (_, (sig, reg)) = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS)
998+
let (_, sig, reg) = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS)
999999
.name_all_regions(sig)
10001000
.unwrap();
10011001
let lts: Vec<String> = reg.into_iter().map(|(_, kind)| kind.to_string()).collect();

compiler/rustc_middle/src/ty/print/pretty.rs

+107-35
Original file line numberDiff line numberDiff line change
@@ -1776,13 +1776,73 @@ impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
17761776
}
17771777
}
17781778

1779+
/// Folds through bound vars and placeholders, naming them
1780+
struct RegionFolder<'a, 'tcx> {
1781+
tcx: TyCtxt<'tcx>,
1782+
current_index: ty::DebruijnIndex,
1783+
region_map: BTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
1784+
name: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
1785+
}
1786+
1787+
impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
1788+
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
1789+
self.tcx
1790+
}
1791+
1792+
fn fold_binder<T: TypeFoldable<'tcx>>(
1793+
&mut self,
1794+
t: ty::Binder<'tcx, T>,
1795+
) -> ty::Binder<'tcx, T> {
1796+
self.current_index.shift_in(1);
1797+
let t = t.super_fold_with(self);
1798+
self.current_index.shift_out(1);
1799+
t
1800+
}
1801+
1802+
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
1803+
match *t.kind() {
1804+
_ if t.has_vars_bound_at_or_above(self.current_index) || t.has_placeholders() => {
1805+
return t.super_fold_with(self);
1806+
}
1807+
_ => {}
1808+
}
1809+
t
1810+
}
1811+
1812+
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
1813+
let name = &mut self.name;
1814+
let region = match *r {
1815+
ty::ReLateBound(_, br) => self.region_map.entry(br).or_insert_with(|| name(br)),
1816+
ty::RePlaceholder(ty::PlaceholderRegion { name: kind, .. }) => {
1817+
// If this is an anonymous placeholder, don't rename. Otherwise, in some
1818+
// async fns, we get a `for<'r> Send` bound
1819+
match kind {
1820+
ty::BrAnon(_) | ty::BrEnv => r,
1821+
_ => {
1822+
// Index doesn't matter, since this is just for naming and these never get bound
1823+
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind };
1824+
self.region_map.entry(br).or_insert_with(|| name(br))
1825+
}
1826+
}
1827+
}
1828+
_ => return r,
1829+
};
1830+
if let ty::ReLateBound(debruijn1, br) = *region {
1831+
assert_eq!(debruijn1, ty::INNERMOST);
1832+
self.tcx.mk_region(ty::ReLateBound(self.current_index, br))
1833+
} else {
1834+
region
1835+
}
1836+
}
1837+
}
1838+
17791839
// HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`,
17801840
// `region_index` and `used_region_names`.
17811841
impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
17821842
pub fn name_all_regions<T>(
17831843
mut self,
17841844
value: &ty::Binder<'tcx, T>,
1785-
) -> Result<(Self, (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)), fmt::Error>
1845+
) -> Result<(Self, T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>), fmt::Error>
17861846
where
17871847
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
17881848
{
@@ -1805,16 +1865,16 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
18051865

18061866
let mut empty = true;
18071867
let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
1808-
write!(
1809-
cx,
1810-
"{}",
1811-
if empty {
1812-
empty = false;
1813-
start
1814-
} else {
1815-
cont
1816-
}
1817-
)
1868+
let w = if empty {
1869+
empty = false;
1870+
start
1871+
} else {
1872+
cont
1873+
};
1874+
let _ = write!(cx, "{}", w);
1875+
};
1876+
let do_continue = |cx: &mut Self, cont: Symbol| {
1877+
let _ = write!(cx, "{}", cont);
18181878
};
18191879

18201880
define_scoped_cx!(self);
@@ -1824,44 +1884,44 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
18241884
// aren't named. Eventually, we might just want this as the default, but
18251885
// this is not *quite* right and changes the ordering of some output
18261886
// anyways.
1827-
let new_value = if self.tcx().sess.verbose() {
1887+
let (new_value, map) = if self.tcx().sess.verbose() {
18281888
// anon index + 1 (BrEnv takes 0) -> name
18291889
let mut region_map: BTreeMap<u32, Symbol> = BTreeMap::default();
18301890
let bound_vars = value.bound_vars();
18311891
for var in bound_vars {
18321892
match var {
18331893
ty::BoundVariableKind::Region(ty::BrNamed(_, name)) => {
1834-
let _ = start_or_continue(&mut self, "for<", ", ");
1835-
let _ = write!(self, "{}", name);
1894+
start_or_continue(&mut self, "for<", ", ");
1895+
do_continue(&mut self, name);
18361896
}
18371897
ty::BoundVariableKind::Region(ty::BrAnon(i)) => {
1838-
let _ = start_or_continue(&mut self, "for<", ", ");
1898+
start_or_continue(&mut self, "for<", ", ");
18391899
let name = loop {
18401900
let name = name_by_region_index(region_index);
18411901
region_index += 1;
18421902
if !self.used_region_names.contains(&name) {
18431903
break name;
18441904
}
18451905
};
1846-
let _ = write!(self, "{}", name);
1906+
do_continue(&mut self, name);
18471907
region_map.insert(i + 1, name);
18481908
}
18491909
ty::BoundVariableKind::Region(ty::BrEnv) => {
1850-
let _ = start_or_continue(&mut self, "for<", ", ");
1910+
start_or_continue(&mut self, "for<", ", ");
18511911
let name = loop {
18521912
let name = name_by_region_index(region_index);
18531913
region_index += 1;
18541914
if !self.used_region_names.contains(&name) {
18551915
break name;
18561916
}
18571917
};
1858-
let _ = write!(self, "{}", name);
1918+
do_continue(&mut self, name);
18591919
region_map.insert(0, name);
18601920
}
18611921
_ => continue,
18621922
}
18631923
}
1864-
start_or_continue(&mut self, "", "> ")?;
1924+
start_or_continue(&mut self, "", "> ");
18651925

18661926
self.tcx.replace_late_bound_regions(value.clone(), |br| {
18671927
let kind = match br.kind {
@@ -1881,11 +1941,12 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
18811941
))
18821942
})
18831943
} else {
1884-
let new_value = self.tcx.replace_late_bound_regions(value.clone(), |br| {
1885-
let _ = start_or_continue(&mut self, "for<", ", ");
1944+
let tcx = self.tcx;
1945+
let mut name = |br: ty::BoundRegion| {
1946+
start_or_continue(&mut self, "for<", ", ");
18861947
let kind = match br.kind {
18871948
ty::BrNamed(_, name) => {
1888-
let _ = write!(self, "{}", name);
1949+
do_continue(&mut self, name);
18891950
br.kind
18901951
}
18911952
ty::BrAnon(_) | ty::BrEnv => {
@@ -1896,31 +1957,36 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
18961957
break name;
18971958
}
18981959
};
1899-
let _ = write!(self, "{}", name);
1960+
do_continue(&mut self, name);
19001961
ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
19011962
}
19021963
};
1903-
self.tcx.mk_region(ty::ReLateBound(
1904-
ty::INNERMOST,
1905-
ty::BoundRegion { var: br.var, kind },
1906-
))
1907-
});
1908-
start_or_continue(&mut self, "", "> ")?;
1909-
new_value
1964+
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind }))
1965+
};
1966+
let mut folder = RegionFolder {
1967+
tcx,
1968+
current_index: ty::INNERMOST,
1969+
name: &mut name,
1970+
region_map: BTreeMap::new(),
1971+
};
1972+
let new_value = value.clone().skip_binder().fold_with(&mut folder);
1973+
let region_map = folder.region_map;
1974+
start_or_continue(&mut self, "", "> ");
1975+
(new_value, region_map)
19101976
};
19111977

19121978
self.binder_depth += 1;
19131979
self.region_index = region_index;
1914-
Ok((self, new_value))
1980+
Ok((self, new_value, map))
19151981
}
19161982

19171983
pub fn pretty_in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, fmt::Error>
19181984
where
19191985
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
19201986
{
19211987
let old_region_index = self.region_index;
1922-
let (new, new_value) = self.name_all_regions(value)?;
1923-
let mut inner = new_value.0.print(new)?;
1988+
let (new, new_value, _) = self.name_all_regions(value)?;
1989+
let mut inner = new_value.print(new)?;
19241990
inner.region_index = old_region_index;
19251991
inner.binder_depth -= 1;
19261992
Ok(inner)
@@ -1935,8 +2001,8 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
19352001
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
19362002
{
19372003
let old_region_index = self.region_index;
1938-
let (new, new_value) = self.name_all_regions(value)?;
1939-
let mut inner = f(&new_value.0, new)?;
2004+
let (new, new_value, _) = self.name_all_regions(value)?;
2005+
let mut inner = f(&new_value, new)?;
19402006
inner.region_index = old_region_index;
19412007
inner.binder_depth -= 1;
19422008
Ok(inner)
@@ -1960,6 +2026,12 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
19602026
debug!("LateBoundRegionNameCollector::visit_region(r: {:?}, address: {:p})", r, &r);
19612027
if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r {
19622028
self.used_region_names.insert(name);
2029+
} else if let ty::RePlaceholder(ty::PlaceholderRegion {
2030+
name: ty::BrNamed(_, name),
2031+
..
2032+
}) = *r
2033+
{
2034+
self.used_region_names.insert(name);
19632035
}
19642036
r.super_visit_with(self)
19652037
}

src/test/ui/associated-types/hr-associated-type-projection-1.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ where
1111
}
1212

1313
impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
14-
//~^ ERROR the trait bound `<T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
14+
//~^ ERROR the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
1515
type Item = T;
1616
//~^ ERROR the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref
1717
}

src/test/ui/associated-types/hr-associated-type-projection-1.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ LL | type Item = T;
1414
<&T as Deref>
1515
<&mut T as Deref>
1616

17-
error[E0277]: the trait bound `<T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
17+
error[E0277]: the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
1818
--> $DIR/hr-associated-type-projection-1.rs:13:33
1919
|
2020
LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
21-
| ^^^^^^^^^^^^^^^^^ the trait `Deref` is not implemented for `<T as UnsafeCopy<'b, T>>::Item`
21+
| ^^^^^^^^^^^^^^^^^ the trait `for<'b> Deref` is not implemented for `<T as UnsafeCopy<'b, T>>::Item`
2222
|
2323
help: consider further restricting the associated type
2424
|
25-
LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T where <T as UnsafeCopy<'b, T>>::Item: Deref {
26-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
25+
LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T where for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref {
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2727

2828
error: aborting due to 2 previous errors
2929

src/test/ui/closures/issue-41366.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | (&|_| ()) as &dyn for<'x> Fn(<u32 as T<'x>>::V);
55
| ^^------^
66
| | |
77
| | found signature of `fn(u16) -> _`
8-
| expected signature of `fn(<u32 as T<'x>>::V) -> _`
8+
| expected signature of `for<'x> fn(<u32 as T<'x>>::V) -> _`
99
|
1010
= note: required for the cast to the object type `dyn for<'x> Fn(<u32 as T<'x>>::V)`
1111

src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error[E0119]: conflicting implementations of trait `Trait` for type `for<'r> fn(fn(&'r ()))`
1+
error[E0119]: conflicting implementations of trait `Trait` for type `for<'r> fn(for<'r> fn(&'r ()))`
22
--> $DIR/coherence-fn-covariant-bound-vs-static.rs:17:1
33
|
44
LL | impl Trait for for<'r> fn(fn(&'r ())) {}
55
| ------------------------------------- first implementation here
66
LL | impl<'a> Trait for fn(fn(&'a ())) {}
7-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'r> fn(fn(&'r ()))`
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'r> fn(for<'r> fn(&'r ()))`
88
|
99
= note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
1010

src/test/ui/issues/issue-43623.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ LL | {
1010
LL | break_me::<Type, fn(_)>;
1111
| ^^^^^^^^^^^^^^^^^^^^^^^
1212
| |
13-
| expected signature of `fn(<Type as Trait<'b>>::Assoc) -> _`
13+
| expected signature of `for<'b> fn(<Type as Trait<'b>>::Assoc) -> _`
1414
| found signature of `fn(()) -> _`
1515

1616
error: aborting due to previous error

src/test/ui/issues/issue-60283.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ LL | F: for<'a> FnMut(<T as Trait<'a>>::Item),
1010
LL | foo((), drop)
1111
| ^^^^
1212
| |
13-
| expected signature of `fn(<() as Trait<'a>>::Item) -> _`
13+
| expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
1414
| found signature of `fn(()) -> _`
1515

1616
error[E0277]: the size for values of type `<() as Trait<'_>>::Item` cannot be known at compilation time

0 commit comments

Comments
 (0)