When pretty printing, name placeholders as bound regions
This commit is contained in:
parent
eb0b95b55a
commit
b9ee2fb6d8
8 changed files with 118 additions and 46 deletions
|
@ -995,7 +995,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
let get_lifetimes = |sig| {
|
let get_lifetimes = |sig| {
|
||||||
use rustc_hir::def::Namespace;
|
use rustc_hir::def::Namespace;
|
||||||
let mut s = String::new();
|
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)
|
.name_all_regions(sig)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let lts: Vec<String> = reg.into_iter().map(|(_, kind)| kind.to_string()).collect();
|
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`,
|
// HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`,
|
||||||
// `region_index` and `used_region_names`.
|
// `region_index` and `used_region_names`.
|
||||||
impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||||
pub fn name_all_regions<T>(
|
pub fn name_all_regions<T>(
|
||||||
mut self,
|
mut self,
|
||||||
value: &ty::Binder<'tcx, T>,
|
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
|
where
|
||||||
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
|
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 empty = true;
|
||||||
let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
|
let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
|
||||||
write!(
|
let w = if empty {
|
||||||
cx,
|
empty = false;
|
||||||
"{}",
|
start
|
||||||
if empty {
|
} else {
|
||||||
empty = false;
|
cont
|
||||||
start
|
};
|
||||||
} else {
|
let _ = write!(cx, "{}", w);
|
||||||
cont
|
};
|
||||||
}
|
let do_continue = |cx: &mut Self, cont: Symbol| {
|
||||||
)
|
let _ = write!(cx, "{}", cont);
|
||||||
};
|
};
|
||||||
|
|
||||||
define_scoped_cx!(self);
|
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
|
// 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
|
// this is not *quite* right and changes the ordering of some output
|
||||||
// anyways.
|
// 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
|
// anon index + 1 (BrEnv takes 0) -> name
|
||||||
let mut region_map: BTreeMap<u32, Symbol> = BTreeMap::default();
|
let mut region_map: BTreeMap<u32, Symbol> = BTreeMap::default();
|
||||||
let bound_vars = value.bound_vars();
|
let bound_vars = value.bound_vars();
|
||||||
for var in bound_vars {
|
for var in bound_vars {
|
||||||
match var {
|
match var {
|
||||||
ty::BoundVariableKind::Region(ty::BrNamed(_, name)) => {
|
ty::BoundVariableKind::Region(ty::BrNamed(_, name)) => {
|
||||||
let _ = start_or_continue(&mut self, "for<", ", ");
|
start_or_continue(&mut self, "for<", ", ");
|
||||||
let _ = write!(self, "{}", name);
|
do_continue(&mut self, name);
|
||||||
}
|
}
|
||||||
ty::BoundVariableKind::Region(ty::BrAnon(i)) => {
|
ty::BoundVariableKind::Region(ty::BrAnon(i)) => {
|
||||||
let _ = start_or_continue(&mut self, "for<", ", ");
|
start_or_continue(&mut self, "for<", ", ");
|
||||||
let name = loop {
|
let name = loop {
|
||||||
let name = name_by_region_index(region_index);
|
let name = name_by_region_index(region_index);
|
||||||
region_index += 1;
|
region_index += 1;
|
||||||
|
@ -1843,11 +1903,11 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||||
break name;
|
break name;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let _ = write!(self, "{}", name);
|
do_continue(&mut self, name);
|
||||||
region_map.insert(i + 1, name);
|
region_map.insert(i + 1, name);
|
||||||
}
|
}
|
||||||
ty::BoundVariableKind::Region(ty::BrEnv) => {
|
ty::BoundVariableKind::Region(ty::BrEnv) => {
|
||||||
let _ = start_or_continue(&mut self, "for<", ", ");
|
start_or_continue(&mut self, "for<", ", ");
|
||||||
let name = loop {
|
let name = loop {
|
||||||
let name = name_by_region_index(region_index);
|
let name = name_by_region_index(region_index);
|
||||||
region_index += 1;
|
region_index += 1;
|
||||||
|
@ -1855,13 +1915,13 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||||
break name;
|
break name;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let _ = write!(self, "{}", name);
|
do_continue(&mut self, name);
|
||||||
region_map.insert(0, name);
|
region_map.insert(0, name);
|
||||||
}
|
}
|
||||||
_ => continue,
|
_ => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
start_or_continue(&mut self, "", "> ")?;
|
start_or_continue(&mut self, "", "> ");
|
||||||
|
|
||||||
self.tcx.replace_late_bound_regions(value.clone(), |br| {
|
self.tcx.replace_late_bound_regions(value.clone(), |br| {
|
||||||
let kind = match br.kind {
|
let kind = match br.kind {
|
||||||
|
@ -1881,11 +1941,12 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let new_value = self.tcx.replace_late_bound_regions(value.clone(), |br| {
|
let tcx = self.tcx;
|
||||||
let _ = start_or_continue(&mut self, "for<", ", ");
|
let mut name = |br: ty::BoundRegion| {
|
||||||
|
start_or_continue(&mut self, "for<", ", ");
|
||||||
let kind = match br.kind {
|
let kind = match br.kind {
|
||||||
ty::BrNamed(_, name) => {
|
ty::BrNamed(_, name) => {
|
||||||
let _ = write!(self, "{}", name);
|
do_continue(&mut self, name);
|
||||||
br.kind
|
br.kind
|
||||||
}
|
}
|
||||||
ty::BrAnon(_) | ty::BrEnv => {
|
ty::BrAnon(_) | ty::BrEnv => {
|
||||||
|
@ -1896,22 +1957,27 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||||
break name;
|
break name;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let _ = write!(self, "{}", name);
|
do_continue(&mut self, name);
|
||||||
ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
|
ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.tcx.mk_region(ty::ReLateBound(
|
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind }))
|
||||||
ty::INNERMOST,
|
};
|
||||||
ty::BoundRegion { var: br.var, kind },
|
let mut folder = RegionFolder {
|
||||||
))
|
tcx,
|
||||||
});
|
current_index: ty::INNERMOST,
|
||||||
start_or_continue(&mut self, "", "> ")?;
|
name: &mut name,
|
||||||
new_value
|
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.binder_depth += 1;
|
||||||
self.region_index = region_index;
|
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>
|
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>,
|
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
let old_region_index = self.region_index;
|
let old_region_index = self.region_index;
|
||||||
let (new, new_value) = self.name_all_regions(value)?;
|
let (new, new_value, _) = self.name_all_regions(value)?;
|
||||||
let mut inner = new_value.0.print(new)?;
|
let mut inner = new_value.print(new)?;
|
||||||
inner.region_index = old_region_index;
|
inner.region_index = old_region_index;
|
||||||
inner.binder_depth -= 1;
|
inner.binder_depth -= 1;
|
||||||
Ok(inner)
|
Ok(inner)
|
||||||
|
@ -1935,8 +2001,8 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||||
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
|
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
let old_region_index = self.region_index;
|
let old_region_index = self.region_index;
|
||||||
let (new, new_value) = self.name_all_regions(value)?;
|
let (new, new_value, _) = self.name_all_regions(value)?;
|
||||||
let mut inner = f(&new_value.0, new)?;
|
let mut inner = f(&new_value, new)?;
|
||||||
inner.region_index = old_region_index;
|
inner.region_index = old_region_index;
|
||||||
inner.binder_depth -= 1;
|
inner.binder_depth -= 1;
|
||||||
Ok(inner)
|
Ok(inner)
|
||||||
|
@ -1960,6 +2026,12 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||||
debug!("LateBoundRegionNameCollector::visit_region(r: {:?}, address: {:p})", r, &r);
|
debug!("LateBoundRegionNameCollector::visit_region(r: {:?}, address: {:p})", r, &r);
|
||||||
if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r {
|
if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r {
|
||||||
self.used_region_names.insert(name);
|
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)
|
r.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
|
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;
|
type Item = T;
|
||||||
//~^ ERROR the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref
|
//~^ ERROR the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,16 +14,16 @@ LL | type Item = T;
|
||||||
<&T as Deref>
|
<&T as Deref>
|
||||||
<&mut 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
|
--> $DIR/hr-associated-type-projection-1.rs:13:33
|
||||||
|
|
|
|
||||||
LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
|
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
|
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
|
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) -> _`
|
| | 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)`
|
= 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
|
--> $DIR/coherence-fn-covariant-bound-vs-static.rs:17:1
|
||||||
|
|
|
|
||||||
LL | impl Trait for for<'r> fn(fn(&'r ())) {}
|
LL | impl Trait for for<'r> fn(fn(&'r ())) {}
|
||||||
| ------------------------------------- first implementation here
|
| ------------------------------------- first implementation here
|
||||||
LL | impl<'a> Trait for fn(fn(&'a ())) {}
|
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
|
= 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(_)>;
|
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(()) -> _`
|
| found signature of `fn(()) -> _`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
|
@ -10,7 +10,7 @@ LL | F: for<'a> FnMut(<T as Trait<'a>>::Item),
|
||||||
LL | foo((), drop)
|
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(()) -> _`
|
| found signature of `fn(()) -> _`
|
||||||
|
|
||||||
error[E0277]: the size for values of type `<() as Trait<'_>>::Item` cannot be known at compilation time
|
error[E0277]: the size for values of type `<() as Trait<'_>>::Item` cannot be known at compilation time
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue