Don't list escaping bound regions in nested for<...> binders of E0308 notes - #159232
Open
Rani367 wants to merge 1 commit into
Open
Don't list escaping bound regions in nested for<...> binders of E0308 notes#159232Rani367 wants to merge 1 commit into
for<...> binders of E0308 notes#159232Rani367 wants to merge 1 commit into
Conversation
…08 notes The `for<...>` prefixes in `cmp_fn_sig` are built from the region map returned by `name_all_regions`. That map also contained regions that are bound by an enclosing binder and merely escape through the binder being named, so nested binders in expected/found notes listed lifetimes they don't bind, printing invalid types such as `&mut for<'a> fn(for<'a> fn(&'a ()))` for `&mut for<'a> fn(fn(&'a ()))`. Key the folder's map by the region's binder offset and only return the regions actually bound by the binder being named. The offset in the key also fixes a latent collision between a bound and an escaping region sharing the same bound variable index. The printed text is unaffected: the `name` closure already skips escaping regions when writing to the printer, which is why diagnostic labels were already correct.
Collaborator
|
Thanks for the pull request, and welcome! The Rust Project is excited to review your changes, and you should hear from @fee1-dead (or someone else) some time within the next two weeks. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
Why was this reviewer chosen?The reviewer was selected based on:
|
Member
|
Binders make me a bit dizzy, so... @rustbot reroll |
Contributor
|
r? types |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The expected/found notes of "one type is more general than the other" errors could print types that are not even valid syntax, repeating lifetimes from an outer binder inside nested
for<...>lists:The expected type here is actually
&mut for<'a> fn(fn(&'a ())), the inner fn pointer binds nothing. In the example from #111365 the note printedfor<'o> fn(for<'a, 'o> fn(&'a (), &'o ()))even though the inner binder only binds'a.The cause is in how
cmp_fn_sigbuilds itsfor<...>prefixes. It callsname_all_regionsand joins every region of the returned map into the list. ButRegionFolderrecords every region at or above the depth of the binder being printed, so regions that are bound by an enclosing binder and merely escape through the current one also end up in the map. The pretty printer's own text output already skips those regions (which is why the labels of these diagnostics were correct, see #102392), but the returned map kept them, andcmp_fn_sigrecurses through nested fn pointers one binder at a time, so every nestedfor<...>list picked up all the outer lifetimes.This PR keys the folder's map by the region's binder offset and filters the map that
name_all_regionsreturns down to the regions actually bound by the binder being named (offset 0). Escaping regions stay in the folder's internal map so that repeated occurrences keep getting the same name, and the emitted text is untouched. Keying by offset also fixes a latent collision where a bound region and an escaping region with the same bound variable index would share a single map entry.With this change, the two examples above print:
The
foundline oftests/ui/nll/relate_tys/placeholder-outlives-existential.rsalso loses its leaked binders and now matches the type written in the test's source.Fixes #134410
This also fixes the leaked outer lifetimes reported in #111365, but I left that issue open since it additionally asks for renaming of shadowed lifetimes (
for<'a> fn(for<'a> ...)for two distinct lifetimes both named'ain the source), which is a separate problem.