Skip to content

Rustc confuses lifetimes of different unrelated variables of type &'static str when implementing a trait for &'a str #26448

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
daboross opened this issue Jun 20, 2015 · 7 comments · Fixed by #58743
Labels
A-lifetimes Area: Lifetimes / regions A-trait-system Area: Trait system C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.

Comments

@daboross
Copy link
Contributor

Example 1:

pub trait Foo<T> {
    fn foo(self) -> T;
}

impl<'a, T> Foo<T> for &'a str where &'a str: Into<T> {
    fn foo(self) -> T {
        panic!();
    }
}

Results in:

<std macros>:1:23: 1:39 error: cannot infer an appropriate lifetime due to conflicting requirements
<std macros>:1 (  ) => ( { panic ! ( "explicit panic" ) } ) ; ( $ msg : expr ) => (
                                     ^~~~~~~~~~~~~~~~
...

Playground: https://play.rust-lang.org/?gist=22052e30a6d8e19c053e&version=stable.


Example 2:

pub struct Bar<T> {
    items: Vec<&'static str>,
    inner: T,
}

pub trait IntoBar<T> {
    fn into_bar(self) -> Bar<T>;
}

impl<'a, T> IntoBar<T> for &'a str where &'a str: Into<T> {
    fn into_bar(self) -> Bar<T> {
        Bar {
            items: Vec::new(),
            inner: self.into(),
        }
    }
}

Results in:

<anon>:16:20: 16:30 error: cannot infer an appropriate lifetime due to conflicting requirements
<anon>:16             items: Vec::new(),
...

Playground: https://play.rust-lang.org/?gist=1bffa565c5fd39f942d1&version=nightly


Example 3:

pub struct Item {
    _inner: &'static str,
}

pub struct Bar<T> {
    items: Vec<Item>,
    inner: T,
}

pub trait IntoBar<T> {
    fn into_bar(self) -> Bar<T>;
}

impl<'a, T> IntoBar<T> for &'a str where &'a str: Into<T> {
    fn into_bar(self) -> Bar<T> {
        Bar {
            items: Vec::new(),
            inner: self.into(),
        }
    }
}

Results in:

<anon>:17:20: 17:28 error: mismatched types:
 expected `core::marker::Sized`,
    found `core::marker::Sized`
(lifetime mismatch) [E0308]
<anon>:17             items: Vec::new(),
                             ^~~~~~~~
...

Playground: https://play.rust-lang.org/?gist=fd54c0069ab0f38079b7&version=stable


The first two examples occur on rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14), rustc 1.1.0-beta.3 (6aa2d5078 2015-06-12) and rustc 1.2.0-nightly (2f5683913 2015-06-18).

The third example occurs only on rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14) and rustc 1.1.0-beta.3 (6aa2d5078 2015-06-12), and appears to be fixed in nightly. I've included it to contrast with the first and second examples, which are still broken in the nightly.

@daboross daboross changed the title Rustc confuses lifetimes of format string inside panic!() when implementing a trait for &'a str Rustc confuses lifetimes of different unrelated variables of type &'static str when implementing a trait for &'a str Jun 20, 2015
daboross added a commit to daboross/rust-throw that referenced this issue Jun 20, 2015
@steveklabnik steveklabnik added A-lifetimes Area: Lifetimes / regions A-trait-system Area: Trait system labels Jun 23, 2015
@arielb1
Copy link
Contributor

arielb1 commented Oct 25, 2015

cc #29188

@nikomatsakis
Copy link
Contributor

Without having dug too deply into these examples, I think they are perhaps related to #21974. But I am not totally sure. #21988 may fix some of the examples, but it does not fix the first one.

@DanielKeep
Copy link
Contributor

Just ran head-first into this. Here's a reduced example, tested on playpen nightly as of 2016-01-21 and 1.7.0-nightly commit 4405944

use std::marker::PhantomData;

struct Ident<Output>(PhantomData<Output>);

trait ScanFromStr {
    fn scan_from() -> Option<&'static str>;
}

impl<'a, Output> ScanFromStr for Ident<Output>
where &'a str: Into<Output> {
    fn scan_from() -> Option<&'static str> {
        Some("expected identifier")
    }
}

fn main() {}

However, niconii on IRC discovered that this particular case can be worked around like so:

use std::marker::PhantomData;

struct Ident<Output>(PhantomData<Output>);

trait ScanFromStr {
    fn scan_from() -> Option<&'static str>;
}

impl<'a, Output> ScanFromStr for Ident<Output>
where for<'b> &'b str: Into<Output> {
    fn scan_from() -> Option<&'static str> {
        Some("expected identifier")
    }
}

fn main() {}

(Note the modification to the where clause.)

Edit: sadly, this doesn't help with the original, unreduced case, as the solution causes new problems (&str !impl for<'b> Into<&'b str>).

DanielKeep added a commit to DanielKeep/rust-scan-rules that referenced this issue Jan 21, 2016
Note that, due to rust-lang/rust#26448 some `ScanFromStr` implementations
*cannot* return a `Syntax` error without trigger the aforementioned
issue.  This is what `SyntaxNoMessage` is for, until it gets fixed.
@DanielKeep
Copy link
Contributor

I've also run into something that is suspiciously similar, except that it fails to compile with a different error message on stable, but compiles correctly on beta. This seems really strange, and makes me wonder if maybe this is interacting badly with something else...

use std::marker::PhantomData;

pub enum ScanErrorKind {
    Syntax(&'static str),
}

pub trait ScanFromStr<'a>: Sized {
    type Output;
    fn scan_from(s: &'a str) -> Result<(Self::Output, usize), ScanErrorKind>;
}

pub struct Everything<'a, Output=&'a str>(PhantomData<(&'a (), Output)>);

impl<'a, Output> ScanFromStr<'a> for Everything<'a, Output> where &'a str: Into<Output> {
    type Output = Output;
    fn scan_from(s: &'a str) -> Result<(Self::Output, usize), ScanErrorKind> {
        Ok((s.into(), s.len()))
    }
}

fn main() {}

Compiling with stable 1.6.0 yields:

.\local\boom.rs:13:23: 13:48 error: mismatched types:
 expected `core::marker::Sized`,
    found `core::marker::Sized`
(lifetime mismatch) [E0308]
.\local\boom.rs:13     fn scan_from() -> Result<(), ScanErrorKind> {
                                         ^~~~~~~~~~~~~~~~~~~~~~~~~
.\local\boom.rs:13:23: 13:48 help: run `rustc --explain E0308` to see a detailed explanation
.\local\boom.rs:13:49: 15:6 note: the lifetime 'a as defined on the block at 13:48...
.\local\boom.rs:13     fn scan_from() -> Result<(), ScanErrorKind> {
.\local\boom.rs:14         Ok(())
.\local\boom.rs:15     }
note: ...does not necessarily outlive the static lifetime
error: aborting due to previous error

Current beta and nightly compile just fine. Interestingly, if I change Ok(()) to panic!(), it stops compiling on nightly, like my previous example. It almost feels like whatever the problem here is, part of it was papered over between stable/beta, but the underlying problem wasn't fixed.

DanielKeep added a commit to DanielKeep/rust-scan-rules that referenced this issue Jan 22, 2016
* Added compatibility information to crate docs and readme.

* Added an extra rule to `scan!` for trailing commas.

* Modified syntax of an internal macro, because `where` isn't in `ty`'s
  follow set yet.

* Had to work around what appears to be an even worse case of
  rust-lang/rust#26448.  This involved dropping the generic impls of some
  scanners and supporting *only* `&str` and `String`.
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 22, 2017
@memoryruins
Copy link
Contributor

Triage: all of OP's examples now compile on both editions.
rustc: 1.32.0

@daboross
Copy link
Contributor Author

Tried to read through the issue when I got this notification and had no idea what it was, then looked at date! Can't believe it's been 3 years.

Thank you for finding the issue and retesting it.

@matthewjasper matthewjasper added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Jan 30, 2019
@matthewjasper
Copy link
Contributor

The fix appears to have been in 1.30, this needs a test if we don't already have one.

varkor added a commit to varkor/rust that referenced this issue Feb 26, 2019
Centril added a commit to Centril/rust that referenced this issue Feb 27, 2019
…hton

Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes rust-lang#10876.
Closes rust-lang#22892.
Closes rust-lang#26448.
Closes rust-lang#26577.
Closes rust-lang#26619.
Closes rust-lang#27054.
Closes rust-lang#28587.
Closes rust-lang#44127.
Closes rust-lang#44255.
Closes rust-lang#55731.
Closes rust-lang#57781.
varkor added a commit to varkor/rust that referenced this issue Feb 27, 2019
pietroalbini added a commit to pietroalbini/rust that referenced this issue Mar 1, 2019
…hton

Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes rust-lang#10876.
Closes rust-lang#22892.
Closes rust-lang#26448.
Closes rust-lang#26577.
Closes rust-lang#26619.
Closes rust-lang#27054.
Closes rust-lang#28587.
Closes rust-lang#44127.
Closes rust-lang#44255.
Closes rust-lang#55731.
Closes rust-lang#57781.
Centril added a commit to Centril/rust that referenced this issue Mar 9, 2019
…hton

Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes rust-lang#10876.
Closes rust-lang#22892.
Closes rust-lang#26448.
Closes rust-lang#26577.
Closes rust-lang#26619.
Closes rust-lang#27054.
Closes rust-lang#28587.
Closes rust-lang#44127.
Closes rust-lang#44255.
Closes rust-lang#55731.
Closes rust-lang#57781.
Centril added a commit to Centril/rust that referenced this issue Mar 9, 2019
…hton

Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes rust-lang#10876.
Closes rust-lang#22892.
Closes rust-lang#26448.
Closes rust-lang#26577.
Closes rust-lang#26619.
Closes rust-lang#27054.
Closes rust-lang#28587.
Closes rust-lang#44127.
Closes rust-lang#44255.
Closes rust-lang#55731.
Closes rust-lang#57781.
varkor added a commit to varkor/rust that referenced this issue Mar 11, 2019
bors added a commit that referenced this issue Mar 12, 2019
Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes #10876.
Closes #26448.
Closes #26577.
Closes #26619.
Closes #27054.
Closes #44127.
Closes #44255.
Closes #55731.
Closes #57781.
varkor added a commit to varkor/rust that referenced this issue Mar 12, 2019
pietroalbini added a commit to pietroalbini/rust that referenced this issue Mar 12, 2019
…hton

Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes rust-lang#10876.
Closes rust-lang#26448.
Closes rust-lang#26577.
Closes rust-lang#26619.
Closes rust-lang#27054.
Closes rust-lang#44127.
Closes rust-lang#44255.
Closes rust-lang#55731.
Closes rust-lang#57781.
bors added a commit that referenced this issue Mar 12, 2019
Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes #10876.
Closes #26448.
Closes #26577.
Closes #26619.
Closes #27054.
Closes #44127.
Closes #44255.
Closes #55731.
Closes #57781.
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-lifetimes Area: Lifetimes / regions A-trait-system Area: Trait system C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants