-
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
Start of implementation of proposal for E0308 #37388
Conversation
c5fc79a
to
06386ce
Compare
if let Some(impl_infos) = self.tcx.inherent_impls.borrow().get(&found) { | ||
let mut methods = Vec::new(); | ||
for impl_ in impl_infos { | ||
methods.append(&mut self.tcx |
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.
use .extend
and remove the .collect()
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 am sure that this can be replaced with flat_map, isn't it? This will reduce allocations, I think. Or just with nested for loop.
@@ -527,7 +527,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { | |||
{ | |||
let expected_found = match values { | |||
None => None, | |||
Some(values) => match self.values_str(&values) { | |||
Some(ref values) => match self.values_str(&values) { |
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.
Could somebody explain me why ref
is added?
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.
To avoid moving values
says rustc.
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.
Oh. I understood. We can write self.values_str(values)
because values is reference or am I wrong?
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.
No, I think you're right. I didn't focus on this point when I wrote it. Thanks! :)
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.
@GuillaumeGomez Will you fix this before merge?
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.
Of course I will. This is far from merge anyway. I opened in order to allow @jonathandturner to follow.
cc me |
@@ -565,19 +565,29 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { | |||
// look for expected with found id | |||
self.tcx.populate_inherent_implementations_for_type_if_necessary(found); | |||
if let Some(impl_infos) = self.tcx.inherent_impls.borrow().get(&found) { | |||
let mut methods = Vec::new(); |
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.
Can you write like this:
let methods = impl_infos.iter()
.flat_map(|impl_| {
self.tcx
.impl_or_trait_items(*impl_)
.iter()
.map(|&did| (None, did, self.tcx.impl_or_trait_item(did)))
.filter(|&(_, _, ref x)| {
self.matches_return_type(x, &expected_ty)
})
});
I didn't test it, so it may be impossible.
self.matches_return_type(item, &item_ty) | ||
}) | ||
} | ||
}; |
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.
You should've replaced the original code to a call to impl_or_trait_item
- since they're equivalent ;).
We now have for the following code: fn main() {
let x: usize = String::new();
} the following error output:
A few things remain to be done but this is a good start:
What remains to be done:
|
I don't like Also, |
@@ -1234,6 +1234,7 @@ impl String { | |||
/// assert_eq!(a.len(), 3); | |||
/// ``` | |||
#[inline] | |||
#[cfg_attr(not(stage0), safe_suggestion)] |
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.
Which reminds me that this line should be removed.
☔ The latest upstream changes (presumably #11994) made this pull request unmergeable. Please resolve the merge conflicts. |
d261e3f
to
7f53f51
Compare
7f53f51
to
824292b
Compare
Can you post some examples of what the output currently looks like for the new errors? |
Cool :) Looks good so far. |
There's a |
.map(|probe| probe.to_unadjusted_pick()) | ||
.collect(); | ||
|
||
if ret.len() < 1 { |
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.
Now that PickResult
is already a Result<Vec<->, ->
, I don't think we need that Option
.
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.
You're absolutely right!
if suggestions.len() > 0 { | ||
Some(format!("here are some functions which \ | ||
might fulfill your needs:\n - {}", | ||
self.get_best_match(&suggestions))) |
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 was wondering if we should call these methods and show them like:
- .len()
- .capacity()
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 actually a better idea than the current output so big 👍 .
@@ -0,0 +1,47 @@ | |||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT |
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.
Can we use ui tests instead so we know what the result will look like?
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.
Sure.
8087837
to
d311d6c
Compare
@jonathandturner: I moved the new test into ui, let me know if you like the new output. |
6d14755
to
a9defa8
Compare
Sorry for the delay, been a busy last few days! I'll try to finish up the review now. I just wanted to revisit the method check code one last time with a fresh pair of eyes. =) BTW, you wrote this earlier:
But I'm not sure what you were responding to? Was it this comment of mine:
If so, I'm surprised that you think this would only be applicable to rustc! I think maybe what you mean is that it would be helpful for making suggestions from the standard library, but not for detecting cases of safe-conversions that occur in user code? If so, I am not sure I agree, though I suppose that may be possible. Presuming that end-users follow Rust's naming conventions, relying on |
@GuillaumeGomez ok, so I've been spending some time re-reading the PR, and I feel like I'm not ready for it to land. I think we want to change the approach somewhat. There are two main concerns. Concern 1: This makes some reasonable deep changes to the method selection code. In general, I don't think we should be changing the method lookup code quite so much to accommodate selections. I think a better approach would be to factor out into two phases:
I expect this would be more of a "surface edit" to the method lookup code, basically, only tweaking how we generate candidates. Does that make sense? If not, I can try to prototype to show you what I mean. Concern 2: I remain uncomfortable with the code that suggests the user add a Here is an example interaction with your branch showing you what I mean (though it's the same example I gave before):
The other concern is that the final In general, I'd prefer to factor out this "suggest a |
@nikomatsakis: For your second concern, I think I'll just make this change in another PR, it'll get easier for everyone and I'll try to make something better. However, the only real problem with the current code is for the For your first concern, well, I'm a bit lost.
As far as I understood it, you said: "finding candidates without looking for candidates". So I certainly completely misunderstood and I really need more information. Also, a step actually correspond to only one candidate. Such a thing doesn't seem suitable for this case, right? Or maybe do you prefer to return multiple steps at once?
Well, since we have methods' information, I guess this part doesn't need much comment and comprehension. 😉
Now I'm completely lost. Why would we need to run another method lookup since we already have a list of candidates? So I think most of my questions come from my lack of knowledge but if you could bring a little more information, it'd wonderful! Meanwhile, I'll remove the |
☔ The latest upstream changes (presumably #37670) made this pull request unmergeable. Please resolve the merge conflicts. |
@GuillaumeGomez sorry for dropping off the radar last week. I've not forgotten you =) will try to get you my idea tomorrow. |
Ok! :) |
We now do two phases. First, we gather up the list of candidates with suitable return types and extract their names. Then we filter those to see which are applicable and we return that. It might be nice to do the "filter by return type" as a second step, but this is ok for now.
@GuillaumeGomez see my most recent commits for my proposed approach. The key point is that we do not change any code in the 'non-error' path (or at least, that's the goal). |
@GuillaumeGomez (I pushed the commits to your branch) |
@nikomatsakis - do you have a screenshot showing what your version looks like? |
@jonathandturner I did not change the appearance of the error messages at all, just the way they are gathered up. I tested it on the one or two UI tests and it seemed to generate the same output. I also agree we can improve the formatting though! |
@nikomatsakis: Really nice! This is way more elegant like this. I'm all for just keeping your code and merge it as is (in condition that it succeeds tests). Do you want to rebase or do I? |
@GuillaumeGomez ok. Perhaps you can rebase, and also remove the code that overlaps with #37658 ? |
@nikomatsakis: Sure. Give me a bit of time to take care of it. :) |
@GuillaumeGomez ok -- I think I'll close this PR for now to clear my queue, feel free to re-open. =) |
r? @jonathandturner
cc @eddyb