Skip to content

Commit 5ba30a6

Browse files
authored
Rollup merge of #102514 - b-naber:binder-print-fixes, r=jackh726
Don't repeat lifetime names from outer binder in print Fixes #102392 Fixes #102414 r? ```@lcnr```
2 parents bf37054 + 048e637 commit 5ba30a6

10 files changed

+114
-19
lines changed

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

+63-12
Original file line numberDiff line numberDiff line change
@@ -2055,7 +2055,14 @@ struct RegionFolder<'a, 'tcx> {
20552055
tcx: TyCtxt<'tcx>,
20562056
current_index: ty::DebruijnIndex,
20572057
region_map: BTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
2058-
name: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
2058+
name: &'a mut (
2059+
dyn FnMut(
2060+
Option<ty::DebruijnIndex>, // Debruijn index of the folded late-bound region
2061+
ty::DebruijnIndex, // Index corresponding to binder level
2062+
ty::BoundRegion,
2063+
) -> ty::Region<'tcx>
2064+
+ 'a
2065+
),
20592066
}
20602067

20612068
impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
@@ -2086,7 +2093,9 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
20862093
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
20872094
let name = &mut self.name;
20882095
let region = match *r {
2089-
ty::ReLateBound(_, br) => *self.region_map.entry(br).or_insert_with(|| name(br)),
2096+
ty::ReLateBound(db, br) if db >= self.current_index => {
2097+
*self.region_map.entry(br).or_insert_with(|| name(Some(db), self.current_index, br))
2098+
}
20902099
ty::RePlaceholder(ty::PlaceholderRegion { name: kind, .. }) => {
20912100
// If this is an anonymous placeholder, don't rename. Otherwise, in some
20922101
// async fns, we get a `for<'r> Send` bound
@@ -2095,7 +2104,10 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
20952104
_ => {
20962105
// Index doesn't matter, since this is just for naming and these never get bound
20972106
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind };
2098-
*self.region_map.entry(br).or_insert_with(|| name(br))
2107+
*self
2108+
.region_map
2109+
.entry(br)
2110+
.or_insert_with(|| name(None, self.current_index, br))
20992111
}
21002112
}
21012113
}
@@ -2234,24 +2246,63 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
22342246
})
22352247
} else {
22362248
let tcx = self.tcx;
2237-
let mut name = |br: ty::BoundRegion| {
2238-
start_or_continue(&mut self, "for<", ", ");
2239-
let kind = match br.kind {
2249+
2250+
// Closure used in `RegionFolder` to create names for anonymous late-bound
2251+
// regions. We use two `DebruijnIndex`es (one for the currently folded
2252+
// late-bound region and the other for the binder level) to determine
2253+
// whether a name has already been created for the currently folded region,
2254+
// see issue #102392.
2255+
let mut name = |lifetime_idx: Option<ty::DebruijnIndex>,
2256+
binder_level_idx: ty::DebruijnIndex,
2257+
br: ty::BoundRegion| {
2258+
let (name, kind) = match br.kind {
22402259
ty::BrAnon(_) | ty::BrEnv => {
22412260
let name = next_name(&self);
2242-
do_continue(&mut self, name);
2243-
ty::BrNamed(CRATE_DEF_ID.to_def_id(), name)
2261+
2262+
if let Some(lt_idx) = lifetime_idx {
2263+
if lt_idx > binder_level_idx {
2264+
let kind = ty::BrNamed(CRATE_DEF_ID.to_def_id(), name);
2265+
return tcx.mk_region(ty::ReLateBound(
2266+
ty::INNERMOST,
2267+
ty::BoundRegion { var: br.var, kind },
2268+
));
2269+
}
2270+
}
2271+
2272+
(name, ty::BrNamed(CRATE_DEF_ID.to_def_id(), name))
22442273
}
22452274
ty::BrNamed(def_id, kw::UnderscoreLifetime) => {
22462275
let name = next_name(&self);
2247-
do_continue(&mut self, name);
2248-
ty::BrNamed(def_id, name)
2276+
2277+
if let Some(lt_idx) = lifetime_idx {
2278+
if lt_idx > binder_level_idx {
2279+
let kind = ty::BrNamed(def_id, name);
2280+
return tcx.mk_region(ty::ReLateBound(
2281+
ty::INNERMOST,
2282+
ty::BoundRegion { var: br.var, kind },
2283+
));
2284+
}
2285+
}
2286+
2287+
(name, ty::BrNamed(def_id, name))
22492288
}
22502289
ty::BrNamed(_, name) => {
2251-
do_continue(&mut self, name);
2252-
br.kind
2290+
if let Some(lt_idx) = lifetime_idx {
2291+
if lt_idx > binder_level_idx {
2292+
let kind = br.kind;
2293+
return tcx.mk_region(ty::ReLateBound(
2294+
ty::INNERMOST,
2295+
ty::BoundRegion { var: br.var, kind },
2296+
));
2297+
}
2298+
}
2299+
2300+
(name, br.kind)
22532301
}
22542302
};
2303+
2304+
start_or_continue(&mut self, "for<", ", ");
2305+
do_continue(&mut self, name);
22552306
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind }))
22562307
};
22572308
let mut folder = RegionFolder {

src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ LL | async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
1818
| ___________________________________________________________________^
1919
LL | | }
2020
| |_^
21-
= note: required because it captures the following types: `ResumeTy`, `impl for<'a, 'b, 'c> Future<Output = ()>`, `()`
21+
= note: required because it captures the following types: `ResumeTy`, `impl Future<Output = ()>`, `()`
2222
note: required because it's used within this `async` block
2323
--> $DIR/issue-70935-complex-spans.rs:16:16
2424
|

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(for<'r> fn(&'r ()))`
1+
error[E0119]: conflicting implementations of trait `Trait` for type `for<'r> fn(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(for<'r> fn(&'r ()))`
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'r> fn(fn(&'r ()))`
88
|
99
= note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
1010

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
struct TwoLt<'a, 'b>(&'a (), &'b ());
2+
type Foo<'a> = fn(TwoLt<'_, 'a>);
3+
4+
fn foo() {
5+
let y: for<'a> fn(Foo<'a>);
6+
let x: u32 = y;
7+
//~^ ERROR mismatched types
8+
}
9+
10+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/nested-binder-print.rs:6:18
3+
|
4+
LL | let x: u32 = y;
5+
| --- ^ expected `u32`, found fn pointer
6+
| |
7+
| expected due to this
8+
|
9+
= note: expected type `u32`
10+
found fn pointer `for<'a> fn(for<'b> fn(TwoLt<'b, 'a>))`
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0308`.

src/test/ui/lifetimes/re-empty-in-error.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error: higher-ranked lifetime error
44
LL | foo(&10);
55
| ^^^^^^^^
66
|
7-
= note: could not prove `for<'b, 'a> &'b (): 'a`
7+
= note: could not prove `for<'b> &'b (): 'a`
88

99
error: aborting due to previous error
1010

src/test/ui/regions/issue-102392.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fn g(f: for<'a> fn(fn(&str, &'a str))) -> bool {
2+
f
3+
//~^ ERROR mismatched types
4+
}
5+
6+
fn main() {}
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-102392.rs:2:5
3+
|
4+
LL | fn g(f: for<'a> fn(fn(&str, &'a str))) -> bool {
5+
| ---- expected `bool` because of return type
6+
LL | f
7+
| ^ expected `bool`, found fn pointer
8+
|
9+
= note: expected type `bool`
10+
found fn pointer `for<'a> fn(for<'b> fn(&'b str, &'a str))`
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0308`.

src/test/ui/where-clauses/higher-ranked-fn-type.quiet.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0277]: the trait bound `for<'b> for<'b> fn(&'b ()): Foo` is not satisfied
1+
error[E0277]: the trait bound `for<'b> fn(&'b ()): Foo` is not satisfied
22
--> $DIR/higher-ranked-fn-type.rs:20:5
33
|
44
LL | called()
5-
| ^^^^^^ the trait `for<'b> Foo` is not implemented for `for<'b> fn(&'b ())`
5+
| ^^^^^^ the trait `for<'b> Foo` is not implemented for `fn(&'b ())`
66
|
77
note: required by a bound in `called`
88
--> $DIR/higher-ranked-fn-type.rs:12:25

src/test/ui/where-clauses/higher-ranked-fn-type.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ where
1818
(for<'a> fn(&'a ())): Foo,
1919
{
2020
called()
21-
//[quiet]~^ ERROR the trait bound `for<'b> for<'b> fn(&'b ()): Foo` is not satisfied
21+
//[quiet]~^ ERROR the trait bound `for<'b> fn(&'b ()): Foo` is not satisfied
2222
//[verbose]~^^ ERROR the trait bound `for<'b> fn(&ReLateBound(
2323
}
2424

0 commit comments

Comments
 (0)