Skip to content

Commit 47b1009

Browse files
committed
don't duplicate late-bound region names in print of Binder
1 parent b79b7d8 commit 47b1009

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
@@ -1572,7 +1572,9 @@ pub struct FmtPrinterData<'a, 'tcx> {
15721572
in_value: bool,
15731573
pub print_alloc_ids: bool,
15741574

1575+
// set of all named (non-anonymous) region names
15751576
used_region_names: FxHashSet<Symbol>,
1577+
15761578
region_index: usize,
15771579
binder_depth: usize,
15781580
printed_type_count: usize,
@@ -2139,23 +2141,31 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21392141
where
21402142
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
21412143
{
2142-
fn name_by_region_index(index: usize) -> Symbol {
2143-
match index {
2144-
0 => Symbol::intern("'r"),
2145-
1 => Symbol::intern("'s"),
2146-
i => Symbol::intern(&format!("'t{}", i - 2)),
2144+
fn name_by_region_index(
2145+
index: usize,
2146+
available_names: &mut Vec<Symbol>,
2147+
num_available: usize,
2148+
) -> Symbol {
2149+
if let Some(name) = available_names.pop() {
2150+
name
2151+
} else {
2152+
Symbol::intern(&format!("'t{}", index - num_available))
21472153
}
21482154
}
21492155

2156+
debug!("name_all_regions");
2157+
21502158
// Replace any anonymous late-bound regions with named
21512159
// variants, using new unique identifiers, so that we can
21522160
// clearly differentiate between named and unnamed regions in
21532161
// the output. We'll probably want to tweak this over time to
21542162
// decide just how much information to give.
21552163
if self.binder_depth == 0 {
2156-
self.prepare_late_bound_region_info(value);
2164+
self.prepare_region_info(value);
21572165
}
21582166

2167+
debug!("self.used_region_names: {:?}", &self.used_region_names);
2168+
21592169
let mut empty = true;
21602170
let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
21612171
let w = if empty {
@@ -2172,13 +2182,23 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21722182

21732183
define_scoped_cx!(self);
21742184

2185+
let possible_names = vec![Symbol::intern("'t"), Symbol::intern("'s"), Symbol::intern("'r")];
2186+
2187+
let mut available_names = possible_names
2188+
.into_iter()
2189+
.filter(|name| !self.used_region_names.contains(&name))
2190+
.collect::<Vec<_>>();
2191+
debug!(?available_names);
2192+
let num_available = available_names.len();
2193+
21752194
let mut region_index = self.region_index;
2176-
let mut next_name = |this: &Self| loop {
2177-
let name = name_by_region_index(region_index);
2195+
let mut next_name = |this: &Self| {
2196+
let name = name_by_region_index(region_index, &mut available_names, num_available);
2197+
debug!(?name);
21782198
region_index += 1;
2179-
if !this.used_region_names.contains(&name) {
2180-
break name;
2181-
}
2199+
assert!(!this.used_region_names.contains(&name));
2200+
2201+
name
21822202
};
21832203

21842204
// If we want to print verbosely, then print *all* binders, even if they
@@ -2199,6 +2219,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21992219
ty::BrAnon(_) | ty::BrEnv => {
22002220
start_or_continue(&mut self, "for<", ", ");
22012221
let name = next_name(&self);
2222+
debug!(?name);
22022223
do_continue(&mut self, name);
22032224
ty::BrNamed(CRATE_DEF_ID.to_def_id(), name)
22042225
}
@@ -2292,29 +2313,37 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
22922313
Ok(inner)
22932314
}
22942315

2295-
fn prepare_late_bound_region_info<T>(&mut self, value: &ty::Binder<'tcx, T>)
2316+
fn prepare_region_info<T>(&mut self, value: &ty::Binder<'tcx, T>)
22962317
where
22972318
T: TypeVisitable<'tcx>,
22982319
{
2299-
struct LateBoundRegionNameCollector<'a, 'tcx> {
2300-
used_region_names: &'a mut FxHashSet<Symbol>,
2320+
struct RegionNameCollector<'tcx> {
2321+
used_region_names: FxHashSet<Symbol>,
23012322
type_collector: SsoHashSet<Ty<'tcx>>,
23022323
}
23032324

2304-
impl<'tcx> ty::visit::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_, 'tcx> {
2325+
impl<'tcx> RegionNameCollector<'tcx> {
2326+
fn new() -> Self {
2327+
RegionNameCollector {
2328+
used_region_names: Default::default(),
2329+
type_collector: SsoHashSet::new(),
2330+
}
2331+
}
2332+
}
2333+
2334+
impl<'tcx> ty::visit::TypeVisitor<'tcx> for RegionNameCollector<'tcx> {
23052335
type BreakTy = ();
23062336

23072337
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
23082338
trace!("address: {:p}", r.0.0);
2309-
if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r {
2310-
self.used_region_names.insert(name);
2311-
} else if let ty::RePlaceholder(ty::PlaceholderRegion {
2312-
name: ty::BrNamed(_, name),
2313-
..
2314-
}) = *r
2315-
{
2339+
2340+
// Collect all named lifetimes. These allow us to prevent duplication
2341+
// of already existing lifetime names when introducing names for
2342+
// anonymous late-bound regions.
2343+
if let Some(name) = r.get_name() {
23162344
self.used_region_names.insert(name);
23172345
}
2346+
23182347
r.super_visit_with(self)
23192348
}
23202349

@@ -2330,12 +2359,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
23302359
}
23312360
}
23322361

2333-
self.used_region_names.clear();
2334-
let mut collector = LateBoundRegionNameCollector {
2335-
used_region_names: &mut self.used_region_names,
2336-
type_collector: SsoHashSet::new(),
2337-
};
2362+
let mut collector = RegionNameCollector::new();
23382363
value.visit_with(&mut collector);
2364+
self.used_region_names = collector.used_region_names;
23392365
self.region_index = 0;
23402366
}
23412367
}

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 {
@@ -1441,6 +1452,23 @@ impl<'tcx> Region<'tcx> {
14411452
*self.0.0
14421453
}
14431454

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

0 commit comments

Comments
 (0)