Skip to content

Spans disagree with each other on what the correct lifetime might be for the return type #106517

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

Open
nagisa opened this issue Jan 6, 2023 · 3 comments
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@nagisa
Copy link
Member

nagisa commented Jan 6, 2023

From one of our tests:

fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }

produces the following error:

error[E0106]: missing lifetime specifier
 --> src/lib.rs:1:62
  |
1 | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }
  |                     ------------------------------------     ^ expected named lifetime parameter
  |
  = help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from
help: consider introducing a named lifetime parameter
  |
1 | fn parse_type<'a>(iter: Box<dyn Iterator<Item=&'a str>+'static>) -> &'a str { iter.next() }
  |              ++++                              ++                    ++

error[E0308]: mismatched types
 --> src/lib.rs:1:69
  |
1 | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }
  |                                                              ----   ^^^^^^^^^^^ expected `&str`, found enum `Option`
  |                                                              |
  |                                                              expected `&'static str` because of return type
  |
  = note: expected reference `&'static str`
                  found enum `Option<&str>`

Note how in the mismatched types error we’re seing two spans disagreeing with each other on what the lifetime of &str ought to be. This can come across as pretty weird.

@nagisa nagisa added A-diagnostics Area: Messages for errors, warnings, and lints D-papercut Diagnostics: An error or lint that needs small tweaks. labels Jan 6, 2023
@yanchen4791
Copy link
Contributor

@rustbot claim

@yanchen4791
Copy link
Contributor

yanchen4791 commented Jan 26, 2023

After some investigations into the issue, I'd like to explain the reasons of spans disagreeing with each other, and potential solutions and side effects if any.

  1. It should be understandable that two distinct error checking passes might reveal different problems and their origins in the same code, and disagree on what should be the correct code due to their varying perspectives. In this example, there are two problems about the return type: missing lifetime specifier, and mismatched types. For the latter case, the error messages just stated the fact that what is the return type with its lifetime inferred from the function declaration statement (&'static str), and what is the return type from the implementation (Option<&str>). But for the former case, the message just stated that the return type needs additional lifetime specifier to fix the lifetime problem. I think it is not hard for the user to fix these two problems one after other. But it is difficult for the compiler to consolidate the messages generated from these two passes and give a one good suggestion, and we should not consider doing so.

  2. About two spans disagreeing with each other in mismatched types error, one span prints &str, while others print &'static str. We can make them consistent but need to be carefully designed. Here are some considerations:

    What form to use -- &str or &'static str?

    We can consistently use the long form -- &'static str. From MIR of this case, the return type is &'static str (since the region kind is ty::ReStatic). The reason in the span which prints &str, is because the method on purposely omitted the lifetime portion in order to explains the source of a type err in a short, human readable way (See comments on impl<'tcx> fmt::Display for TypeError<'tcx> of compiler/rustc_middle/src/ty/error.rs). Is it desirable to add the lifetime back (not just 'static)? It will make the spans consistently using &'static str based on the type MIR giving, but it could have a broad effect to all kinds of TypeError messages.

    Or. we can use the short form &str for all &strs with ty:ReStatic kind. But will this create confusing with the case of &str with lifetime elided? In addition, this could have even broader effect to error messages of all kinds.

@yanchen4791
Copy link
Contributor

The outputs after the code changed to using the long form for all type error notes are:

error[E0106]: missing lifetime specifier
 --> main.rs:1:62
  |
1 | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }
  |                     ------------------------------------     ^ expected named lifetime parameter
  |
  = help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from
help: consider introducing a named lifetime parameter
  |
1 | fn parse_type<'a>(iter: Box<dyn Iterator<Item=&'a str>+'static>) -> &'a str { iter.next() }
  |              ++++                              ++                    ++

error[E0308]: mismatched types
 --> main.rs:1:69
  |
1 | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }
  |                                                              ----   ^^^^^^^^^^^ expected `&'static str`, found enum `Option`
  |                                                              |
  |                                                              expected `&'static str` because of return type
  |
  = note: expected reference `&'static str`
                  found enum `Option<&str>`

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0106, E0308.
For more information about an error, try `rustc --explain E0106`.

@Noratrieb Noratrieb added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Feb 24, 2023
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 D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants