Skip to content

Underscore lifetimes are incorrectly accepted as lifetime bounds in impl headers #54902

Closed
@scottmcm

Description

@scottmcm
Member

This is currently accepted in 2018: https://play.rust-lang.org/?gist=7ba2dee1134f9848b54b7364ea9568aa&version=nightly&edition=2018

trait Foo<'a> {}
impl<'b: '_> Foo<'b> for i32 {}

AFAICT, it desugars to

impl<'b: 'c, 'c> Foo<'b> for i32 {}

So it's "fine", but useless.

It should error, as trying to do this does in other places, such as

struct Foo<'a: '_>(&'a i32);

Tracking issue for the impl_header_lifetime_elision feature: #15872

On the current beta this gives

error[E0688]: cannot mix in-band and explicit lifetime definitions

so this was at least exposed by #54458

Activity

changed the title [-]Underscore lifetimes are accepted as lifetime bounds in impl headers[/-] [+]Underscore lifetimes are incorrectly accepted as lifetime bounds in impl headers[/+] on Oct 8, 2018
added
P-highHigh priority
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
C-bugCategory: This is a bug.
on Oct 8, 2018
added this to the Edition 2018 RC 2 milestone on Oct 8, 2018
self-assigned this
on Oct 11, 2018
pnkfelix

pnkfelix commented on Oct 11, 2018

@pnkfelix
Member

visited for triage. Agreed that P-high and RC2 milestones are appropriate. @nikomatsakis is going to work first on mentorship; if that fails to find a volunter, they will fallback to fixing it themself.

nikomatsakis

nikomatsakis commented on Oct 11, 2018

@nikomatsakis
Contributor

Actually, I'm not sure if this is an error or not. We currently permit '_ in other, similar contexts.

Example 1 (playground):

trait Foo<'a> { }

struct Bar<T> { t: T }

impl<T: Foo<'_>> Bar<T> { }

fn main() { }

and example 2 (playground):

trait Foo<'a> { }

struct Bar<T> { t: T }

impl<T> Bar<T> where T: Foo<'_> { }

fn main() { }

Are we comfortable with those, but just not this? (I guess because this is clearly useless, whereas those .. may be useful?)

nikomatsakis

nikomatsakis commented on Oct 11, 2018

@nikomatsakis
Contributor

For some reason, I thought maybe we were not going to permit '_ in those contexts, out of fear that the semantics were not what we might want. In particular, I can imagine that people might expect T: Foo<'_> to be equivalent to T: for<'a> Foo<'a>.

nikomatsakis

nikomatsakis commented on Oct 11, 2018

@nikomatsakis
Contributor

Survey of current behavior.

In Rust 2018 on nightly, all of the following are accepted.

Using '_ in a where clause (inherent impl)

Playground.

trait WithType<T> {}
trait WithRegion<'a> { }

struct Foo<T> { 
    t: T
}

impl<T> Foo<T>
where T: WithRegion<'_> { }

fn main() {}

Using &u32 in a where clause (inherent impl)

Playground.

trait WithType<T> {}
trait WithRegion<'a> { }

struct Foo<T> { 
    t: T
}

impl<T> Foo<T>
where T: WithType<&u32> { }

fn main() {}

Using &u32 in a where clause (trait impl)

Playground.

trait WithType<T> {}
trait WithRegion<'a> { }

trait Foo { }

impl<T> Foo for Vec<T>
where T: WithType<&u32> { }

fn main() {}

Using '_ in a where clause (trait impl)

Playground.

trait WithType<T> {}
trait WithRegion<'a> { }

trait Foo { }

impl<T> Foo for Vec<T>
where T: WithRegion<'_> { }

fn main() {}
nikomatsakis

nikomatsakis commented on Oct 11, 2018

@nikomatsakis
Contributor

Survey of current behavior.

In Rust 2015 on nightly, all are errors.

nikomatsakis

nikomatsakis commented on Oct 11, 2018

@nikomatsakis
Contributor

We discussed this in the @rust-lang/lang meeting and there seemed to be consensus that we ought to make it an error to use '_ or &u32 in a where-clause for the time being, so as to leave room for locating the "implicit binder" at a different spot in the future. I think there is a connection here between this and in-band lifetimes, since they must also specify an "implicit binder", and hence it probably makes sense to "wait and see" where they go first.

(I have first hand observed confusion on this point.)

Given that the behavior is only accepted in Rust 2018, it seems we still have room to change this without requiring backporting.

nikomatsakis

nikomatsakis commented on Oct 11, 2018

@nikomatsakis
Contributor

See also #45667

nikomatsakis

nikomatsakis commented on Oct 18, 2018

@nikomatsakis
Contributor

Fixed in #55162

added a commit that references this issue on Oct 19, 2018

Auto merge of #55162 - nikomatsakis:issue-54902-underscore-bound, r=t…

added a commit that references this issue on Oct 23, 2018

Auto merge of #54778 - scottmcm:stabilize-ihle, r=pnkfelix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

C-bugCategory: This is a bug.P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team

Type

No type

Projects

No projects

Relationships

None yet

    Development

    Participants

    @nikomatsakis@pnkfelix@Centril@scottmcm

    Issue actions

      Underscore lifetimes are incorrectly accepted as lifetime bounds in impl headers · Issue #54902 · rust-lang/rust