-
Notifications
You must be signed in to change notification settings - Fork 13k
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
adding E0623 for return types - both parameters are anonymous #44124
Conversation
52b358c
to
70ff722
Compare
@@ -0,0 +1,6 @@ | |||
|
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.
missing license and newlines in the code
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.
also, shouldn't this test go with the other PR?
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.
Yeah. Was a mistake
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.
First round of suggestions.
|
||
let (main_label, label1, label2) = if let (Some(sup_arg), Some(sub_arg)) = | ||
let (spanfin1, spanfin2, main_label, label) = if let (Some(sup_arg), | ||
Some(sub_arg)) = |
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.
Nit: can we use use the flatter style here too? I really find the if let
nesting hard to read. In other words, change the if let (Some(sup_arg), Some(sub_arg)) = (...) { ... } else { false }
too:
let sup_arg = or_false!(self.find_arg_with_anonymous_region(sup, sup));
let sub_arg = or_false!(self.find_arg_with_anonymous_region(sub, sub));
...
self.is_return_type_anon(scope_def_id_sub, bregion_sub) { | ||
return false; | ||
} | ||
let (anon_arg_sup, anon_arg_sub) = (sup_arg.arg, sub_arg.arg); |
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.
If we do the or_false!
transformation above, and we don't care about the other field, we could do:
let AnonymousArgInfo { arg: anon_arg_sup, .. } = or_false!(self.find_arg_with_anonymous_region(sup, sup));
Not sure if this is a net win.
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 confused about what's happening here
format!(" with one lifetime"), | ||
format!(" into the other")) | ||
let (span_1, span_2, span_label) = | ||
if self.is_return_type_anon(scope_def_id_sup, bregion_sup, ty_fndecl_sup) |
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, this logic is sort of complex. First off, let's store self.is_return_type_anon(scope_def_id_sup, bregion_sup, ty_fndecl_sup)
into a variable:
let sup_is_ret_type = self.is_return_type_anon(scope_def_id_sup, bregion_sup, ty_fndecl_sup);
and same for sub
. Then I think I would structure the remaining logic something like this:
let sup_is_ret_type = self.is_return_type_anon(scope_def_id_sup, bregion_sup, ty_fndecl_sup);
let sub_is_ret_type = self.is_return_type_anon(scope_def_id_sub, bregion_sub, ty_fndecl_sub);
let (span_1, span_2, span_label) = match (sup_is_ret_type, sub_is_ret_type) {
(None, None) =>
(ty_sup.span, ty_sub.span, format!("this type was declared with multiple lifetimes...")),
(Some(ret_span), _) =>
(ty_sub.span, ret_span, format!("this parameter and the return type are declared with different lifetimes...")),
(_, Some(ret_span)) =>
(ty_sup.span, ret_span, format!("this parameter and the return type are declared with different lifetimes...")),
};
However, this raises the question -- what if both sub and sup appear in the return type? The existing code seems to ignore this case, but it's probably worth adding something like this:
(Some(ret_span1), Some(ret_span2)) =>
(ret_span1, ret_span2, format!("the return type is declared with different lifetimes...")),
That said, maybe better to wait until we have a test for this case, since I'm not sure off-hand how it can really arise.
@@ -91,19 +118,50 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { | |||
format!("") | |||
}; | |||
|
|||
let span_label = | |||
format!("these two types are declared with different lifetimes...",); | |||
let (var1_span, var2_span, span_label_1, span_label_2) = if |
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 restructure this in the same way I as suggested above.
if self.is_return_type_anon(scope_def_id, br, fndecl).is_some() || | ||
self.is_self_anon(is_first, scope_def_id) { | ||
return false; | ||
} } |
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.
Nit: }
on next line
@gaurikholkar ping just to keep this on your radar! |
@alexcrichton getting back at it today! |
☔ The latest upstream changes (presumably #44079) made this pull request unmergeable. Please resolve the merge conflicts. |
07cf201
to
6d3ac8e
Compare
@gaurikholkar so since I had a local checkout of your branch I went ahead and corrected a few nits in the wording of the error messages. However, it looks like now that you've made things better, the example for E0312 isn't working anymore. I'm a bit torn here --- I feel like most every example we can craft for E0312 is probably just a bug waiting to be fixed (i.e., a case where we can make a better example). But I guess in the interim we can keep shuffling it from bug to bug. Do you have any instinct for what example would still trigger E0312? Maybe something involving |
Are you referring to the you tests w.r.t self, return type and impls? Now that they trigger E0623? Also do we want that for impls? |
Sorry, I don't really understand the question. What I am saying is that the example for E0312 found in the extended error message (the one with
Probably we are not yet at that point where it's worth removing the extended error msg for E0312. I imagine we can find some kind of example that still fails. |
Hi @gaurikholkar. How it's going with this PR? Is there anything blocking you? Feel free to ping me on IRC. |
One small mismatch in a test:
|
is_first, | ||
scope_def_id); | ||
return false; | ||
if let Some(anon_ty) = self.find_anon_type(anon, &br) { |
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.
style: if let Some((_, fndecl)) = self.find_anon_type(anon, &br)
LGTM modulo nits |
The travis failure is confusing me. I checked out the branch and don't see that file in my copy. Maybe I'm doing something bone-headed... |
@nikomatsakis yeah even I couldn't find the file :( |
@bors r+ |
That kind of formatting seems like the job of other code.
0f836ae
to
73543d5
Compare
@bors r+ |
📌 Commit 73543d5 has been approved by |
@bors rollup |
When does this get merged? |
I remember discussing that we need not change the message for Impls for the case of E0621, this PR modifies that. Should it be OK? |
adding E0623 for return types - both parameters are anonymous This is a fix for rust-lang#44018 ``` error[E0621]: explicit lifetime required in the type of `self` --> $DIR/ex3-both-anon-regions-return-type-is-anon.rs:17:5 | 16 | fn foo<'a>(&self, x: &i32) -> &i32 { | ---- ---- | | | this parameter and the return type are declared with different lifetimes... 17 | x | ^ ...but data from `x` is returned here error: aborting due to previous error ``` It also works for the below case where we have self as anonymous ``` error[E0623]: lifetime mismatch --> src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs:17:19 | 16 | fn foo<'a>(&self, x: &Foo) -> &Foo { | ---- ---- | | | this parameter and the return type are declared with different lifetimes... 17 | if true { x } else { self } | ^ ...but data from `x` is returned here error: aborting due to previous error ``` r? @nikomatsakis Currently, I have enabled E0621 where return type and self are anonymous, hence WIP.
☔ The latest upstream changes (presumably #44936) made this pull request unmergeable. Please resolve the merge conflicts. |
Merged in #44936. |
When there's a lifetime mismatch between an argument with an anonymous lifetime being returned in a method with a return type that has a named lifetime, show specialized lifetime error pointing at argument with a hint to give it an explicit lifetime matching the return type. ``` error[E0621]: explicit lifetime required in the type of `other` --> file2.rs:21:21 | 17 | fn bar(&self, other: Foo) -> Foo<'a> { | ----- consider changing the type of `other` to `Foo<'a>` ... 21 | other | ^^^^^ lifetime `'a` required ``` Follow up to rust-lang#44124 and rust-lang#42669.
Handle anon lifetime arg being returned with named lifetime return type When there's a lifetime mismatch between an argument with an anonymous lifetime being returned in a method with a return type that has a named lifetime, show specialized lifetime error pointing at argument with a hint to give it an explicit lifetime matching the return type. ``` error[E0621]: explicit lifetime required in the type of `other` --> file2.rs:21:21 | 17 | fn bar(&self, other: Foo) -> Foo<'a> { | ----- consider changing the type of `other` to `Foo<'a>` ... 21 | other | ^^^^^ lifetime `'a` required ``` Follow up to rust-lang#44124 and rust-lang#42669. Fix rust-lang#44684.
This is a fix for #44018
It also works for the below case where we have self as anonymous
r? @nikomatsakis
Currently, I have enabled E0621 where return type and self are anonymous, hence WIP.