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<...>`
This commit is contained in:
commit
8024983ea7
8 changed files with 118 additions and 46 deletions
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)`
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue