-
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 #52572
Conversation
As of submission, this PR produces the following error (or equivalent):
It fixes the following tests mentioned in the issue:
|
src/librustc/mir/tcx.rs
Outdated
} | ||
}, | ||
ProjectionElem::Deref => { | ||
if recurse { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure about adding this parameter (recurse
) - without it, a handful of unrelated tests start throwing duplicate errors with shorter spans, but without considering the place within the deref I don't get some of the tests that currently work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. So the behavior when recurse
is true seems mostly correct to me -- that is, if you have a variable that is captured "by reference" (and not "by value"), then x
would be desugared to *self.x
. However, I think we would only then want to recurse through a single deref. Maybe this is the cause of the other tests behaving strangely?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just checked and it seems like only doing a single deref still exhibits this behaviour.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed a fix for this.
self.get_argument_index_for_region(tcx, fr) | ||
.map(|index| self.get_argument_name_and_span_for_region(mir, index)) | ||
}) | ||
.unwrap_or_else(|| span_bug!(mir.span, "can't find var name for free region {:?}", fr)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit nervous about this case. Based on the other code I see, it seems like it is possible for the region to appear in the closure output, for example. I'll try to build your branch and produce an example though because it's hard for me to predict in advance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most recent pushed commit introduces changes that ICE due to this in some tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another commit now stops those ICEs by falling back to previous error handling.
(Some(upvar_name), upvar_span) | ||
} | ||
|
||
/// Get argument index for a region. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would word this as:
Search the argument types for one that references fr
(which should be a free region). Returns Some(_)
with the index of the input if one is found.
NB: In the case of a clsoure, the index
is indexing into the signature as seen by the user--- in particular, index 0 is not the implicit self
parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed a commit that addresses this.
Some(upvar_index) | ||
} | ||
|
||
/// Get upvar name and span for a region. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say something like:
Given the index of an upvar, finds its name (if any) and the span from where it was declared.
Question: Why does this return an Option
? From what I can tell, it is always Some
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had it return an Option
so that the types where the same in the and_then
sections of the function above. I'll change this to use a .map(...)
in that function rather than change the return type of this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed a commit that addresses this.
.unwrap_or_else(|| span_bug!(mir.span, "can't find var name for free region {:?}", fr)) | ||
} | ||
|
||
/// Get upvar index for a region. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say something like:
Search the upvars (if any) to find one that references fr
. Return its index.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed a commit that addresses this.
Some(argument_index) | ||
} | ||
|
||
/// Get argument name and span for a region. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would reword this similar to the fn for upvars.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed a commit that addresses this.
@@ -224,30 +235,75 @@ impl<'tcx> RegionInferenceContext<'tcx> { | |||
|
|||
// Get a span | |||
let (category, span) = categorized_path.first().unwrap(); | |||
|
|||
match category { | |||
ConstraintCategory::AssignmentToUpvar => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is interesting. Looking for an assignment to an upvar is not quite taking the approach I expected, but it also makes sense. I guess though that this code won't fire for something like:
fn foo(x: &mut Vec<&u32>) {
bar(|y| x.push(y));
}
fn bar(_: impl FnOnce(&u32)) { }
Right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems ok, though I can think we can address this case via a similar set of errors, if we generalize the conditions somewhat away from assignment and more into looking at the kinds of regions involved. (Or maybe this is just another sort of case to specialize)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is similar to the issue-7573.rs
case that isn't yet handled. I messed around with making another variant for ConstraintCategory
that would go through to the report_closure_error
branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed with most recent commit.
@bors r+ |
📌 Commit 58eee34fcc9e3642942690b979d78a7002ddaf7b has been approved by |
☔ The latest upstream changes (presumably #52359) made this pull request unmergeable. Please resolve the merge conflicts. |
…dle function call case.
@bors r+ |
📌 Commit c64db00 has been approved by |
@bors p=1 |
Giving high priority, as improving this case is a EP2 blocker. |
NLL diagnostics replaced nice closure errors w/ indecipherable free region errors Fixes #51027. r? @nikomatsakis
☀️ Test successful - status-appveyor, status-travis |
Fixes #51027.
r? @nikomatsakis