Rust: Extend `rustc_on_unimplemented` to allow pointing at enclosing function/closure

Created on 10 Jun 2019  路  5Comments  路  Source: rust-lang/rust

We should extend rustc_on_unimplemented to be able to point at the enclosing scope. With that capability, we could turn the following:

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
  --> src/lib.rs:28:31
   |
28 |                     let end = parse_range_u32(end)?;
   |                               ^^^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `std::ops::RangeInclusive<u32>`
   |
   = help: the trait `std::ops::Try` is not implemented for `std::ops::RangeInclusive<u32>`
   = note: required by `std::ops::Try::from_error`

into something along the lines of

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
  --> src/lib.rs:28:31
   |
24 |          .map(|range_spec| {
   |               -
   | ______________|
... |
28 ||                     let end = parse_range_u32(end)?;
   ||                               ^^^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `std::ops::RangeInclusive<u32>`
... |
48 ||         })
   ||         - this function should return `Result` or `Option` to accept `?`
   ||_________|
   |
   = help: the trait `std::ops::Try` is not implemented for `std::ops::RangeInclusive<u32>`
   = note: required by `std::ops::Try::from_error`

This has caused confusion in the wild.

A-diagnostics E-medium F-on_unimplemented P-low T-compiler

All 5 comments

@estebank Can I pick this up? I don't have much of an idea about this, but would like to get involved

@sam09 of course! I can take a look at https://github.com/rust-lang/rust/pull/54946 and https://github.com/rust-lang/rust/pull/47613 for some changes made to this code, the currently up to date documentation for the feature. You will probably have to take a look at fn report_selection_error and find a way to get the enclosing scope to the current item. This part will likely be hard given that this function only deals with obligations, doesn't have access to the originating item. The most likely successful course of action would be to extend the obligation itself to keep some information (most likely just a span) of the enclosing scope. The you could extend rustc_on_unimplemented to be something like

#[rustc_on_unimplemented(
   on(all(
       any(from_method="from_error", from_method="from_ok"),
       from_desugaring="QuestionMark"),
      message="the `?` operator can only be used in a \
               function that returns `Result` or `Option` \
               (or another type that implements `{Try}`)",
      label="cannot use the `?` operator in a function that returns `{Self}`",
      enclosing_scope="this should return `Result` or `Option`"), // <--- This is new
   on(all(from_method="into_result", from_desugaring="QuestionMark"),
      message="the `?` operator can only be applied to values \
               that implement `{Try}`",
      label="the `?` operator cannot be applied to type `{Self}`")
)]
#[doc(alias = "?")]
pub trait Try 

@sam09 would you mind me picking this up?

@Areredify @estebank
Apologies for not following up. I have been super busy with some things at work.
@Areredify Please go ahead. I haven't found any time to work on this 馃槃

@estebank I implemented it, but I don't know how to compile it, since I changed both libstd(added an annotation to the Try trait) and the compiler.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nikomatsakis picture nikomatsakis  路  210Comments

GuillaumeGomez picture GuillaumeGomez  路  300Comments

nikomatsakis picture nikomatsakis  路  340Comments

withoutboats picture withoutboats  路  213Comments

withoutboats picture withoutboats  路  211Comments