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

Mismatched lifetime in trait function declaration is not detected #48812

Open
glandium opened this issue Mar 7, 2018 · 2 comments
Open

Mismatched lifetime in trait function declaration is not detected #48812

glandium opened this issue Mar 7, 2018 · 2 comments
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-papercut Diagnostics: An error or lint that needs small tweaks. NLL-fixed-by-NLL Bugs fixed, but only when NLL is enabled. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@glandium
Copy link
Contributor

glandium commented Mar 7, 2018

Consider the following code:

pub trait FromStr<'a>: Sized {
    type Err;
    fn from_str(s: &'a str) -> Result<Self, Self::Err>;
}

struct Foo<'a>(&'a str);

impl<'a> FromStr<'a> for Foo<'a> {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(Foo(s))
    }
}

The compiler errors out failing to infer an appropriate lifetime:


error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
  --> src/main.rs:11:12
   |
11 |         Ok(Foo(s))
   |            ^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 10:5...
  --> src/main.rs:10:5
   |
10 | /     fn from_str(s: &str) -> Result<Self, Self::Err> {
11 | |         Ok(Foo(s))
12 | |     }
   | |_____^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:11:16
   |
11 |         Ok(Foo(s))
   |                ^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 8:1...
  --> src/main.rs:8:1
   |
8  | impl<'a> FromStr<'a> for Foo<'a> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: ...so that the expression is assignable:
           expected std::result::Result<Foo<'a>, _>
              found std::result::Result<Foo<'_>, _>

But the most immediate error is that the declaration of from_str doesn't match the trait definition, missing the lifetime bound on &str to match the lifetime associated with the trait.

@Centril Centril 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. WG-diagnostics Working group: Diagnostics labels Mar 7, 2018
@jkordish jkordish added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Apr 10, 2018
@estebank estebank added 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. labels Oct 17, 2019
@estebank
Copy link
Contributor

Current output:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
  --> src/lib.rs:11:12
   |
11 |         Ok(Foo(s))
   |            ^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 10:5...
  --> src/lib.rs:10:5
   |
10 | /     fn from_str(s: &str) -> Result<Self, Self::Err> {
11 | |         Ok(Foo(s))
12 | |     }
   | |_____^
note: ...so that reference does not outlive borrowed content
  --> src/lib.rs:11:16
   |
11 |         Ok(Foo(s))
   |                ^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 8:6...
  --> src/lib.rs:8:6
   |
8  | impl<'a> FromStr<'a> for Foo<'a> {
   |      ^^
note: ...so that the expression is assignable
  --> src/lib.rs:11:9
   |
11 |         Ok(Foo(s))
   |         ^^^^^^^^^^
   = note: expected  `std::result::Result<Foo<'a>, _>`
              found  `std::result::Result<Foo<'_>, _>`

Output with nll enabled:

error: lifetime may not live long enough
  --> src/lib.rs:12:9
   |
9  | impl<'a> FromStr<'a> for Foo<'a> {
   |      -- lifetime `'a` defined here
10 |     type Err = ();
11 |     fn from_str(s: &str) -> Result<Self, Self::Err> {
   |                    - let's call the lifetime of this reference `'1`
12 |         Ok(Foo(s))
   |         ^^^^^^^^^^ returning this value requires that `'1` must outlive `'a`

@estebank estebank added the NLL-fixed-by-NLL Bugs fixed, but only when NLL is enabled. label Oct 4, 2021
@estebank
Copy link
Contributor

estebank commented Aug 3, 2023

Current output is the nll one above. Ideally we'd suggest using &'a str instead of &str, but the error already gives enough information to deal with the problem.

@estebank estebank added A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. D-papercut Diagnostics: An error or lint that needs small tweaks. and removed WG-diagnostics Working group: Diagnostics 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. labels Aug 3, 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 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-papercut Diagnostics: An error or lint that needs small tweaks. NLL-fixed-by-NLL Bugs fixed, but only when NLL is enabled. 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

4 participants