Skip to content
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

better error message when ? is applied to collect() #49391

Closed
nikomatsakis opened this issue Mar 26, 2018 · 14 comments · Fixed by #65951
Closed

better error message when ? is applied to collect() #49391

nikomatsakis opened this issue Mar 26, 2018 · 14 comments · Fixed by #65951
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` C-enhancement Category: An issue proposing an enhancement or a PR with one. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@nikomatsakis
Copy link
Contributor

This code:

fn main() -> Result<(), ()> {
    vec![Ok(2)].into_iter().collect()?;
    Ok(())
}

gives a terrible error:

error[E0284]: type annotations required: cannot resolve `<_ as std::ops::Try>::Ok == _`
 --> src/main.rs:4:5
  |
4 |     vec![Ok(2)].into_iter().collect()?;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

The solution is to do .collect::<Result<Vec<_>,_>>()? (playground)

@nikomatsakis nikomatsakis added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 26, 2018
@nikomatsakis
Copy link
Contributor Author

I think that the way to fix this is -- first and foremost -- to remove E0284, which is basically the same as E0282 but with "less good" error reporting. To do that, we want to redirect this code:

_ => {
if !self.tcx.sess.has_errors() {
let mut err = struct_span_err!(self.tcx.sess,
obligation.cause.span, E0284,
"type annotations required: \
cannot resolve `{}`",
predicate);
self.note_obligation_cause(&mut err, obligation);
err.emit();
}

so that it invokes the need_type_info fn:

pub fn need_type_info(&self, body_id: Option<hir::BodyId>, span: Span, ty: Ty<'tcx>) {

as it happens, other code from trait error reporting file already invokes need_type_info. For example, this arm lies just a small bit of code above:

ty::Predicate::WellFormed(ty) => {
// Same hacky approach as above to avoid deluging user
// with error messages.
if !ty.references_error() && !self.tcx.sess.has_errors() {
self.need_type_info(body_id, span, ty);
}
}

so I think we just need to change this hunk to work the same way.

@nikomatsakis
Copy link
Contributor Author

That said, my guess is that this won't fix the original example. To do that, we have to extend need_type_info to also make suggestions to use turbofish where appropriate. But it's a first step, and then we can go further!

@nikomatsakis nikomatsakis added the E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. label Apr 2, 2018
@balajisivaraman
Copy link

@nikomatsakis, Following from IRC, I'll pick this one up and begin working on this. Thank you for the helpful tips. :-)

@ytausky
Copy link
Contributor

ytausky commented May 24, 2018

It's been a while now; @balajisivaraman, are you still interested in this issue? Otherwise I'd like to pick it up.

@balajisivaraman
Copy link

@ytausky, Unfortunately, I've not made much progress on this. (I'm still slowly working my way through the Rustc Guide.) You can pick it up if you'd like.

@jkordish jkordish added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jun 5, 2018
@fcofdez
Copy link

fcofdez commented Aug 4, 2018

@ytausky are you still interested in this issue? If not, I would like to pick it up.

@ytausky
Copy link
Contributor

ytausky commented Aug 5, 2018

Sure, life got in between, I'm not working on this.

@phungleson
Copy link
Contributor

Hey guys I can help to look into this if no one picks this up yet.

@saleemjaffer
Copy link
Contributor

@ytausky I would like to give this a shot. I'm new to rust.

@estebank estebank added E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. and removed E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example labels Oct 18, 2019
@Mark-Simulacrum
Copy link
Member

Going to proactively close, Niko can reopen if needed.

@estebank
Copy link
Contributor

The case still repros, I was checking the wrong code.

@estebank
Copy link
Contributor

Output with #65951:

error[E0284]: type annotations needed
 --> file12.rs:2:29
  |
2 |     vec![Ok(2)].into_iter().collect()?;
  |                             ^^^^^^^
  |                             |
  |                             cannot infer type
  |                             help: consider specifying the type argument in the method call: `collect::<B>`
  |
  = note: cannot resolve `<_ as std::ops::Try>::Ok == _`

bors added a commit that referenced this issue Dec 11, 2019
Point at method call when type annotations are needed

- Point at method call instead of whole expression when type annotations are needed.
- Suggest use of turbofish on function and methods.

Fix #49391, fix #46333, fix #48089. CC #58517, #63502, #63082.

r? @nikomatsakis
@bors bors closed this as completed in 8843b28 Dec 14, 2019
@hwalinga
Copy link

Don't know if the compiler can be a bit more smarter about the error message on this case, but I stumbled upon here when I wrote (with rdr a buffered reader):

let lines: Vec<_> = rdr.lines().collect()?;

Giving the strange:

error[E0277]: the size for values of type `str` cannot be known at compilation time

From: https://stackoverflow.com/questions/67644464/why-can-you-not-use-question-mark-directly-on-collect-in-rust

@estebank
Copy link
Contributor

@hwalinga could you file a new ticket with a link to a reproduction care on the playground? A quick attempt at reproducing the StackOverflow case yielded a "type annotations needed" error and following the suggestions for it leads you in the right direction, but I might be sinning of being overly familiar with what the compiler is trying to say.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` C-enhancement Category: An issue proposing an enhancement or a PR with one. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants