Skip to content

Commit 456f4e8

Browse files
committed
don't duplicate late-bound region names in print of Binder
1 parent 72f4923 commit 456f4e8

File tree

2 files changed

+81
-27
lines changed

2 files changed

+81
-27
lines changed

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

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,7 +1562,9 @@ pub struct FmtPrinterData<'a, 'tcx> {
15621562
in_value: bool,
15631563
pub print_alloc_ids: bool,
15641564

1565+
// set of all named (non-anonymous) region names
15651566
used_region_names: FxHashSet<Symbol>,
1567+
15661568
region_index: usize,
15671569
binder_depth: usize,
15681570
printed_type_count: usize,
@@ -2118,23 +2120,31 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21182120
where
21192121
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
21202122
{
2121-
fn name_by_region_index(index: usize) -> Symbol {
2122-
match index {
2123-
0 => Symbol::intern("'r"),
2124-
1 => Symbol::intern("'s"),
2125-
i => Symbol::intern(&format!("'t{}", i - 2)),
2123+
fn name_by_region_index(
2124+
index: usize,
2125+
available_names: &mut Vec<Symbol>,
2126+
num_available: usize,
2127+
) -> Symbol {
2128+
if let Some(name) = available_names.pop() {
2129+
name
2130+
} else {
2131+
Symbol::intern(&format!("'t{}", index - num_available))
21262132
}
21272133
}
21282134

2135+
debug!("name_all_regions");
2136+
21292137
// Replace any anonymous late-bound regions with named
21302138
// variants, using new unique identifiers, so that we can
21312139
// clearly differentiate between named and unnamed regions in
21322140
// the output. We'll probably want to tweak this over time to
21332141
// decide just how much information to give.
21342142
if self.binder_depth == 0 {
2135-
self.prepare_late_bound_region_info(value);
2143+
self.prepare_region_info(value);
21362144
}
21372145

2146+
debug!("self.used_region_names: {:?}", &self.used_region_names);
2147+
21382148
let mut empty = true;
21392149
let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
21402150
let w = if empty {
@@ -2151,13 +2161,23 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21512161

21522162
define_scoped_cx!(self);
21532163

2164+
let possible_names = vec![Symbol::intern("'t"), Symbol::intern("'s"), Symbol::intern("'r")];
2165+
2166+
let mut available_names = possible_names
2167+
.into_iter()
2168+
.filter(|name| !self.used_region_names.contains(&name))
2169+
.collect::<Vec<_>>();
2170+
debug!(?available_names);
2171+
let num_available = available_names.len();
2172+
21542173
let mut region_index = self.region_index;
2155-
let mut next_name = |this: &Self| loop {
2156-
let name = name_by_region_index(region_index);
2174+
let mut next_name = |this: &Self| {
2175+
let name = name_by_region_index(region_index, &mut available_names, num_available);
2176+
debug!(?name);
21572177
region_index += 1;
2158-
if !this.used_region_names.contains(&name) {
2159-
break name;
2160-
}
2178+
assert!(!this.used_region_names.contains(&name));
2179+
2180+
name
21612181
};
21622182

21632183
// If we want to print verbosely, then print *all* binders, even if they
@@ -2178,6 +2198,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21782198
ty::BrAnon(_) | ty::BrEnv => {
21792199
start_or_continue(&mut self, "for<", ", ");
21802200
let name = next_name(&self);
2201+
debug!(?name);
21812202
do_continue(&mut self, name);
21822203
ty::BrNamed(CRATE_DEF_ID.to_def_id(), name)
21832204
}
@@ -2271,29 +2292,37 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
22712292
Ok(inner)
22722293
}
22732294

2274-
fn prepare_late_bound_region_info<T>(&mut self, value: &ty::Binder<'tcx, T>)
2295+
fn prepare_region_info<T>(&mut self, value: &ty::Binder<'tcx, T>)
22752296
where
22762297
T: TypeVisitable<'tcx>,
22772298
{
2278-
struct LateBoundRegionNameCollector<'a, 'tcx> {
2279-
used_region_names: &'a mut FxHashSet<Symbol>,
2299+
struct RegionNameCollector<'tcx> {
2300+
used_region_names: FxHashSet<Symbol>,
22802301
type_collector: SsoHashSet<Ty<'tcx>>,
22812302
}
22822303

2283-
impl<'tcx> ty::visit::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_, 'tcx> {
2304+
impl<'tcx> RegionNameCollector<'tcx> {
2305+
fn new() -> Self {
2306+
RegionNameCollector {
2307+
used_region_names: Default::default(),
2308+
type_collector: SsoHashSet::new(),
2309+
}
2310+
}
2311+
}
2312+
2313+
impl<'tcx> ty::visit::TypeVisitor<'tcx> for RegionNameCollector<'tcx> {
22842314
type BreakTy = ();
22852315

22862316
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
22872317
trace!("address: {:p}", r.0.0);
2288-
if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r {
2289-
self.used_region_names.insert(name);
2290-
} else if let ty::RePlaceholder(ty::PlaceholderRegion {
2291-
name: ty::BrNamed(_, name),
2292-
..
2293-
}) = *r
2294-
{
2318+
2319+
// Collect all named lifetimes. These allow us to prevent duplication
2320+
// of already existing lifetime names when introducing names for
2321+
// anonymous late-bound regions.
2322+
if let Some(name) = r.get_name() {
22952323
self.used_region_names.insert(name);
22962324
}
2325+
22972326
r.super_visit_with(self)
22982327
}
22992328

@@ -2309,12 +2338,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
23092338
}
23102339
}
23112340

2312-
self.used_region_names.clear();
2313-
let mut collector = LateBoundRegionNameCollector {
2314-
used_region_names: &mut self.used_region_names,
2315-
type_collector: SsoHashSet::new(),
2316-
};
2341+
let mut collector = RegionNameCollector::new();
23172342
value.visit_with(&mut collector);
2343+
self.used_region_names = collector.used_region_names;
23182344
self.region_index = 0;
23192345
}
23202346
}

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,17 @@ impl BoundRegionKind {
8585
_ => false,
8686
}
8787
}
88+
89+
pub fn get_name(&self) -> Option<Symbol> {
90+
if self.is_named() {
91+
match *self {
92+
BoundRegionKind::BrNamed(_, name) => return Some(name),
93+
_ => unreachable!(),
94+
}
95+
}
96+
97+
None
98+
}
8899
}
89100

90101
pub trait Article {
@@ -1445,6 +1456,23 @@ impl<'tcx> Region<'tcx> {
14451456
*self.0.0
14461457
}
14471458

1459+
pub fn get_name(self) -> Option<Symbol> {
1460+
if self.has_name() {
1461+
let name = match *self {
1462+
ty::ReEarlyBound(ebr) => Some(ebr.name),
1463+
ty::ReLateBound(_, br) => br.kind.get_name(),
1464+
ty::ReFree(fr) => fr.bound_region.get_name(),
1465+
ty::ReStatic => Some(Symbol::intern("static")),
1466+
ty::RePlaceholder(placeholder) => placeholder.name.get_name(),
1467+
_ => None,
1468+
};
1469+
1470+
return name;
1471+
}
1472+
1473+
None
1474+
}
1475+
14481476
/// Is this region named by the user?
14491477
pub fn has_name(self) -> bool {
14501478
match *self {

0 commit comments

Comments
 (0)