Rollup merge of #102514 - b-naber:binder-print-fixes, r=jackh726
Don't repeat lifetime names from outer binder in print Fixes https://github.com/rust-lang/rust/issues/102392 Fixes https://github.com/rust-lang/rust/issues/102414 r? ```@lcnr```
This commit is contained in:
commit
5ba30a680c
10 changed files with 114 additions and 19 deletions
|
@ -2055,7 +2055,14 @@ struct RegionFolder<'a, 'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
current_index: ty::DebruijnIndex,
|
current_index: ty::DebruijnIndex,
|
||||||
region_map: BTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
|
region_map: BTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
|
||||||
name: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
|
name: &'a mut (
|
||||||
|
dyn FnMut(
|
||||||
|
Option<ty::DebruijnIndex>, // Debruijn index of the folded late-bound region
|
||||||
|
ty::DebruijnIndex, // Index corresponding to binder level
|
||||||
|
ty::BoundRegion,
|
||||||
|
) -> ty::Region<'tcx>
|
||||||
|
+ 'a
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||||
|
@ -2086,7 +2093,9 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
let name = &mut self.name;
|
let name = &mut self.name;
|
||||||
let region = match *r {
|
let region = match *r {
|
||||||
ty::ReLateBound(_, br) => *self.region_map.entry(br).or_insert_with(|| name(br)),
|
ty::ReLateBound(db, br) if db >= self.current_index => {
|
||||||
|
*self.region_map.entry(br).or_insert_with(|| name(Some(db), self.current_index, br))
|
||||||
|
}
|
||||||
ty::RePlaceholder(ty::PlaceholderRegion { name: kind, .. }) => {
|
ty::RePlaceholder(ty::PlaceholderRegion { name: kind, .. }) => {
|
||||||
// If this is an anonymous placeholder, don't rename. Otherwise, in some
|
// If this is an anonymous placeholder, don't rename. Otherwise, in some
|
||||||
// async fns, we get a `for<'r> Send` bound
|
// async fns, we get a `for<'r> Send` bound
|
||||||
|
@ -2095,7 +2104,10 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||||
_ => {
|
_ => {
|
||||||
// Index doesn't matter, since this is just for naming and these never get bound
|
// 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 };
|
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind };
|
||||||
*self.region_map.entry(br).or_insert_with(|| name(br))
|
*self
|
||||||
|
.region_map
|
||||||
|
.entry(br)
|
||||||
|
.or_insert_with(|| name(None, self.current_index, br))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2234,24 +2246,63 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let mut name = |br: ty::BoundRegion| {
|
|
||||||
start_or_continue(&mut self, "for<", ", ");
|
// Closure used in `RegionFolder` to create names for anonymous late-bound
|
||||||
let kind = match br.kind {
|
// regions. We use two `DebruijnIndex`es (one for the currently folded
|
||||||
|
// late-bound region and the other for the binder level) to determine
|
||||||
|
// whether a name has already been created for the currently folded region,
|
||||||
|
// see issue #102392.
|
||||||
|
let mut name = |lifetime_idx: Option<ty::DebruijnIndex>,
|
||||||
|
binder_level_idx: ty::DebruijnIndex,
|
||||||
|
br: ty::BoundRegion| {
|
||||||
|
let (name, kind) = match br.kind {
|
||||||
ty::BrAnon(_) | ty::BrEnv => {
|
ty::BrAnon(_) | ty::BrEnv => {
|
||||||
let name = next_name(&self);
|
let name = next_name(&self);
|
||||||
do_continue(&mut self, name);
|
|
||||||
ty::BrNamed(CRATE_DEF_ID.to_def_id(), name)
|
if let Some(lt_idx) = lifetime_idx {
|
||||||
|
if lt_idx > binder_level_idx {
|
||||||
|
let kind = ty::BrNamed(CRATE_DEF_ID.to_def_id(), name);
|
||||||
|
return tcx.mk_region(ty::ReLateBound(
|
||||||
|
ty::INNERMOST,
|
||||||
|
ty::BoundRegion { var: br.var, kind },
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(name, ty::BrNamed(CRATE_DEF_ID.to_def_id(), name))
|
||||||
}
|
}
|
||||||
ty::BrNamed(def_id, kw::UnderscoreLifetime) => {
|
ty::BrNamed(def_id, kw::UnderscoreLifetime) => {
|
||||||
let name = next_name(&self);
|
let name = next_name(&self);
|
||||||
do_continue(&mut self, name);
|
|
||||||
ty::BrNamed(def_id, name)
|
if let Some(lt_idx) = lifetime_idx {
|
||||||
|
if lt_idx > binder_level_idx {
|
||||||
|
let kind = ty::BrNamed(def_id, name);
|
||||||
|
return tcx.mk_region(ty::ReLateBound(
|
||||||
|
ty::INNERMOST,
|
||||||
|
ty::BoundRegion { var: br.var, kind },
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(name, ty::BrNamed(def_id, name))
|
||||||
}
|
}
|
||||||
ty::BrNamed(_, name) => {
|
ty::BrNamed(_, name) => {
|
||||||
do_continue(&mut self, name);
|
if let Some(lt_idx) = lifetime_idx {
|
||||||
br.kind
|
if lt_idx > binder_level_idx {
|
||||||
|
let kind = br.kind;
|
||||||
|
return tcx.mk_region(ty::ReLateBound(
|
||||||
|
ty::INNERMOST,
|
||||||
|
ty::BoundRegion { var: br.var, kind },
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(name, br.kind)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
start_or_continue(&mut self, "for<", ", ");
|
||||||
|
do_continue(&mut self, name);
|
||||||
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind }))
|
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind }))
|
||||||
};
|
};
|
||||||
let mut folder = RegionFolder {
|
let mut folder = RegionFolder {
|
||||||
|
|
|
@ -18,7 +18,7 @@ LL | async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
|
||||||
| ___________________________________________________________________^
|
| ___________________________________________________________________^
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_^
|
| |_^
|
||||||
= note: required because it captures the following types: `ResumeTy`, `impl for<'a, 'b, 'c> Future<Output = ()>`, `()`
|
= note: required because it captures the following types: `ResumeTy`, `impl Future<Output = ()>`, `()`
|
||||||
note: required because it's used within this `async` block
|
note: required because it's used within this `async` block
|
||||||
--> $DIR/issue-70935-complex-spans.rs:16:16
|
--> $DIR/issue-70935-complex-spans.rs:16:16
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
error[E0119]: conflicting implementations of trait `Trait` for type `for<'r> fn(for<'r> fn(&'r ()))`
|
error[E0119]: conflicting implementations of trait `Trait` for type `for<'r> fn(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(for<'r> fn(&'r ()))`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'r> fn(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
src/test/ui/lifetimes/nested-binder-print.rs
Normal file
10
src/test/ui/lifetimes/nested-binder-print.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
struct TwoLt<'a, 'b>(&'a (), &'b ());
|
||||||
|
type Foo<'a> = fn(TwoLt<'_, 'a>);
|
||||||
|
|
||||||
|
fn foo() {
|
||||||
|
let y: for<'a> fn(Foo<'a>);
|
||||||
|
let x: u32 = y;
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
14
src/test/ui/lifetimes/nested-binder-print.stderr
Normal file
14
src/test/ui/lifetimes/nested-binder-print.stderr
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/nested-binder-print.rs:6:18
|
||||||
|
|
|
||||||
|
LL | let x: u32 = y;
|
||||||
|
| --- ^ expected `u32`, found fn pointer
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
||||||
|
= note: expected type `u32`
|
||||||
|
found fn pointer `for<'a> fn(for<'b> fn(TwoLt<'b, 'a>))`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
|
@ -4,7 +4,7 @@ error: higher-ranked lifetime error
|
||||||
LL | foo(&10);
|
LL | foo(&10);
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: could not prove `for<'b, 'a> &'b (): 'a`
|
= note: could not prove `for<'b> &'b (): 'a`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
6
src/test/ui/regions/issue-102392.rs
Normal file
6
src/test/ui/regions/issue-102392.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
fn g(f: for<'a> fn(fn(&str, &'a str))) -> bool {
|
||||||
|
f
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
14
src/test/ui/regions/issue-102392.stderr
Normal file
14
src/test/ui/regions/issue-102392.stderr
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-102392.rs:2:5
|
||||||
|
|
|
||||||
|
LL | fn g(f: for<'a> fn(fn(&str, &'a str))) -> bool {
|
||||||
|
| ---- expected `bool` because of return type
|
||||||
|
LL | f
|
||||||
|
| ^ expected `bool`, found fn pointer
|
||||||
|
|
|
||||||
|
= note: expected type `bool`
|
||||||
|
found fn pointer `for<'a> fn(for<'b> fn(&'b str, &'a str))`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0277]: the trait bound `for<'b> for<'b> fn(&'b ()): Foo` is not satisfied
|
error[E0277]: the trait bound `for<'b> fn(&'b ()): Foo` is not satisfied
|
||||||
--> $DIR/higher-ranked-fn-type.rs:20:5
|
--> $DIR/higher-ranked-fn-type.rs:20:5
|
||||||
|
|
|
|
||||||
LL | called()
|
LL | called()
|
||||||
| ^^^^^^ the trait `for<'b> Foo` is not implemented for `for<'b> fn(&'b ())`
|
| ^^^^^^ the trait `for<'b> Foo` is not implemented for `fn(&'b ())`
|
||||||
|
|
|
|
||||||
note: required by a bound in `called`
|
note: required by a bound in `called`
|
||||||
--> $DIR/higher-ranked-fn-type.rs:12:25
|
--> $DIR/higher-ranked-fn-type.rs:12:25
|
||||||
|
|
|
@ -18,7 +18,7 @@ where
|
||||||
(for<'a> fn(&'a ())): Foo,
|
(for<'a> fn(&'a ())): Foo,
|
||||||
{
|
{
|
||||||
called()
|
called()
|
||||||
//[quiet]~^ ERROR the trait bound `for<'b> for<'b> fn(&'b ()): Foo` is not satisfied
|
//[quiet]~^ ERROR the trait bound `for<'b> fn(&'b ()): Foo` is not satisfied
|
||||||
//[verbose]~^^ ERROR the trait bound `for<'b> fn(&ReLateBound(
|
//[verbose]~^^ ERROR the trait bound `for<'b> fn(&ReLateBound(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue