-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NLL diagnostics replaced nice closure errors w/ indecipherable free region errors #51027
Comments
there is also the broader issue #49397; this one is more targeted and thus separate. |
As @nikomatsakis has mentioned in the NLL triage docs, I was indeed looking at these errors, so I'm assigning this to myself. |
I'm unassigning @KiChjang as I don't think they made any progress (ping me on Zulip @KiChjang if you still want to hack on this). I think that this is highly related to what I wrote on #51168 (that is, in this comment), and that the solution I described there would be good here too. So I'm going to mark this as a sub-issue and hence deferred. |
Actualy, I'll make this the primary issue, since it has an amusing title. Subissues: |
The reason for this is indeed the closure, I think. We detect the error when analyzing the closure body, so it is hard for us to report a span that is outside the closure. I think this will be pretty tricky to fix and is maybe not that important. What we could probably do is take a different tactic: we could explain that I'm imagining:
for bonus points, we can highlight the |
OK, I've been digging a bit into the code around this issue and I have some (incomplete) thoughts. I'd like to cc @davidtwco as the work on #51188 and this are definitely entangled. I'm looking specifically at
Under MIR borrowck we get an unfortunate error like this:
We'd like to issue some kind of error more tailored to the fact that we are in a closure. But we'd also like it to fit into a broader spectrum of "region reporting errors". Some backgroundThe first thing to talk about are NLL "universal regions". A universal region (short for "universally quantified" region) is basically a lifetime parameter (we use the term region and lifetime interchangeably). So fn foo<'a>(x: &'a u32) { /* 'a here is a universal region */ } Universal regions fall into a few categories, described here: rust/src/librustc_mir/borrow_check/nll/universal_regions.rs Lines 159 to 199 in b58b721
All region errors in NLL fall into the category of two universal regions that the code requires to have an outlives relationship, but which do not. So for example: fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x } this code would error because it would require that Where error reporting takes placeError reporting takes place in this function: rust/src/librustc_mir/borrow_check/nll/region_infer/error_reporting.rs Lines 193 to 201 in b58b721
This code makes some effort to examine the constraints and to identify "interesting" ones that are likely to be the source of the error. This system is very much still Under Development. Nonetheless, that is what this chunk of code is doing: rust/src/librustc_mir/borrow_check/nll/region_infer/error_reporting.rs Lines 233 to 243 in b58b721
Later, you can see we pick a constraint and try to use it as the "frame" for how we report the error:
In this case, the constraint really arises from the assignment that sets
Looking at the region constraint graph, it seems clear that we should be selecting this as the most interesting point. However, from dumping the current behavior, it seems we're not, and I'm not sure that is, but i'm going to ignore that for now and assume it was the result. How to make a nice error and what it should sayI am imagining that we look for this scenario:
then we can
and finally report an error sorta like this:
I'm preserving the existing wording above, but note that the spans are slightly different (I also think we could improve on the wording, but let's leave that for a second). Here is where the spans would come from:
Improving the wordingI think we can do better on the wording, but we'll need a bit more information. By looking at the types of the parameters we ought to be able to figure out that the data comes from the
we could possibly keep the note on
|
cc @estebank I'd love to see your thoughts on the wording towards the end of the previous comment |
I like the last example's clarity, but I'll mull over it for a bit and see if I can come up with any improvement for it. |
Maybe...
|
(See also the examples in #51026) |
Regardless of the specific wording, it seems like we want to do a few things:
Currently we print this:
You can see we've got notes on all the right places, but the text ain't great. As I wrote before, I think that before printing the error we want to check for a case
This indicates that data that is "local" to the closure body is trying to flow out of it (I don't think that the 'main constraint' kind is that important). I would probably like to see the error read roughly like this:
I am imagining that we would check the rust/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs Line 50 in a8247dd
which would use it to add a suitable label. e.g.:
and we similarly adjust the "main" label. Note that in this form I am not giving explicit names (like |
I've submitted #52572 that addresses this issue. |
NLL diagnostics replaced nice closure errors w/ indecipherable free region errors Fixes #51027. r? @nikomatsakis
The following tests all have a common weakness around how they report errors under NLL. Under AST borrowck they would say something somewhat understandable about closures. But under NLL they don't anymore.
List:
(This list of tests is drawn from an informal paper document that I have been using to keep notes for myself as I work on this...)
Example (from
ui/borrowck/issue-45983.rs
):AST borrowck says:
NLL says:
The text was updated successfully, but these errors were encountered: