Skip to content

reset anonymous-lifetime-mode as we enter () scopes #51220

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

Conversation

nikomatsakis
Copy link
Contributor

Background:

The anonymous lifetime mode is used to prohibit elided lifetimes where
they didn't used to be permitted, and instead require that '_ be
used. For example:

impl Trait for Ref<T> { .. }
//             ^^^^^^ ERROR: should be `Ref<'_, T>`

When we are parsing the parts of the impl header, we enter into an alternate mode called CreateParameter. In this mode, we give an error for things like Ref<T>, but for elided lifetimes in a reference type like &T we make the elided lifetime into an in-band lifetime:

/// Invoked to create the lifetime argument for a type `&T`
/// with no explicit lifetime.
fn elided_ref_lifetime(&mut self, span: Span) -> hir::Lifetime {
match self.anonymous_lifetime_mode {
// Intercept when we are in an impl header and introduce an in-band lifetime.
// Hence `impl Foo for &u32` becomes `impl<'f> Foo for &'f u32` for some fresh
// `'f`.
AnonymousLifetimeMode::CreateParameter => {
let fresh_name = self.collect_fresh_in_band_lifetime(span);
hir::Lifetime {
id: self.next_id().node_id,
span,
name: fresh_name,
}
}
AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),
}
}

This was not intended to change behavior because we only enter into that mode in contexts where elision was not historically permitted. However, the problem is that we fail to reset the mode when we enter into bounds like Fn(&u32), where elision was allowed -- the same occurs for fn types like fn(&u32). This PR restores the original mode in those contexts.

Fixes #51008

r? @cramertj

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 30, 2018
@nikomatsakis nikomatsakis force-pushed the issue-51008-false-positive-lifetime-must-be-declared branch from 901ecdb to 85f5d46 Compare May 30, 2018 14:48
@cramertj
Copy link
Member

@bors r+

@bors
Copy link
Collaborator

bors commented May 30, 2018

📌 Commit 85f5d46 has been approved by cramertj

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 30, 2018
@bors
Copy link
Collaborator

bors commented May 30, 2018

🔒 Merge conflict

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 30, 2018
Background:

The anonymous lifetime mode is used to prohibit elided lifetimes where
they didn't used to be permitted, and instead require that `'_` be
used. For example:

```rust
impl Trait for Ref<T> { .. }
//             ^^^^^^ ERROR: should be `Ref<'_, T>`
```

When we are parsing the parts of the impl header, we enter into an
alternate mode called `CreateParameter`. In this mode, we give an
error for things like `Ref<T>`, but for elided lifetimes in a
reference type like `&T` we make the elided lifetime into an in-band
lifetime:

https://github.com/rust-lang/rust/blob/4f99f37b7e213d69a489884f651adfc6d217cef5/src/librustc/hir/lowering.rs#L4017-L4035

This was not intended to change behavior because we only enter into
that mode in contexts where elision was not historically
permitted. However, the problem is that we fail to reset the mode when
we enter into bounds like `Fn(&u32)`, where elision *was* allowed --
the same occurs for fn types like `fn(&u32`). This PR restores the
original mode in those contexts.
@nikomatsakis nikomatsakis force-pushed the issue-51008-false-positive-lifetime-must-be-declared branch from 85f5d46 to da69bbc Compare May 30, 2018 18:55
@nikomatsakis
Copy link
Contributor Author

@bors r=cramertj

@bors
Copy link
Collaborator

bors commented May 30, 2018

📌 Commit da69bbc has been approved by cramertj

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 30, 2018
@nikomatsakis
Copy link
Contributor Author

@bors p=1 -- edition preview blocking bug

@bors
Copy link
Collaborator

bors commented May 31, 2018

⌛ Testing commit da69bbc with merge c1287c0...

bors added a commit that referenced this pull request May 31, 2018
…me-must-be-declared, r=cramertj

reset anonymous-lifetime-mode as we enter `()` scopes

Background:

The anonymous lifetime mode is used to prohibit elided lifetimes where
they didn't used to be permitted, and instead require that `'_` be
used. For example:

```rust
impl Trait for Ref<T> { .. }
//             ^^^^^^ ERROR: should be `Ref<'_, T>`
```

When we are parsing the parts of the impl header, we enter into an alternate mode called `CreateParameter`. In this mode, we give an error for things like `Ref<T>`, but for elided lifetimes in a reference type like `&T` we make the elided lifetime into an in-band lifetime:

https://github.com/rust-lang/rust/blob/4f99f37b7e213d69a489884f651adfc6d217cef5/src/librustc/hir/lowering.rs#L4017-L4035

This was not intended to change behavior because we only enter into that mode in contexts where elision was not historically permitted. However, the problem is that we fail to reset the mode when we enter into bounds like `Fn(&u32)`, where elision *was* allowed -- the same occurs for fn types like `fn(&u32`). This PR restores the original mode in those contexts.

Fixes #51008

r? @cramertj
@bors
Copy link
Collaborator

bors commented May 31, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: cramertj
Pushing c1287c0 to master...

@bors bors merged commit da69bbc into rust-lang:master May 31, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants