Skip to content

Commit

Permalink
Auto merge of rust-lang#53016 - scottmcm:impl-header-lifetime-elision…
Browse files Browse the repository at this point in the history
…, r=nikomatsakis

Extract impl_header_lifetime_elision out of in_band_lifetimes

This way we can experiment with `impl Debug for &MyType` separately from `impl Debug for &'a MyType`.

I can't say I know what the code in here is doing, so please let me know if there's a better way 🙂

I marked this as enabled in 2018 so that edition code continues to work without another flag.

Actual feature PR rust-lang#49251; Tracking Issue rust-lang#15872; In-band lifetimes tracking issue rust-lang#44524.

cc @aturon, per discussion on discord earlier
cc @cramertj & @nikomatsakis, who actually wrote these features
  • Loading branch information
bors committed Aug 6, 2018
2 parents cf84056 + 1c7af27 commit 45a9d41
Show file tree
Hide file tree
Showing 21 changed files with 88 additions and 32 deletions.
14 changes: 10 additions & 4 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ pub struct LoweringContext<'a> {
// Whether or not in-band lifetimes are being collected. This is used to
// indicate whether or not we're in a place where new lifetimes will result
// in in-band lifetime definitions, such a function or an impl header.
// This will always be false unless the `in_band_lifetimes` feature is
// enabled.
// This will always be false unless the `in_band_lifetimes` or
// `impl_header_lifetime_elision` feature is enabled.
is_collecting_in_band_lifetimes: bool,

// Currently in-scope lifetimes defined in impl headers, fn headers, or HRTB.
Expand Down Expand Up @@ -658,9 +658,11 @@ impl<'a> LoweringContext<'a> {
assert!(self.lifetimes_to_define.is_empty());
let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode;

self.is_collecting_in_band_lifetimes = self.sess.features_untracked().in_band_lifetimes;
if self.is_collecting_in_band_lifetimes {
if self.sess.features_untracked().impl_header_lifetime_elision {
self.anonymous_lifetime_mode = anonymous_lifetime_mode;
self.is_collecting_in_band_lifetimes = true;
} else if self.sess.features_untracked().in_band_lifetimes {
self.is_collecting_in_band_lifetimes = true;
}

let (in_band_ty_params, res) = f(self);
Expand Down Expand Up @@ -718,6 +720,10 @@ impl<'a> LoweringContext<'a> {
return;
}

if !self.sess.features_untracked().in_band_lifetimes {
return;
}

if self.in_scope_lifetimes.contains(&ident.modern()) {
return;
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
#![feature(step_trait)]
#![feature(integer_atomics)]
#![feature(test)]
#![cfg_attr(not(stage0), feature(impl_header_lifetime_elision))]
#![feature(in_band_lifetimes)]
#![feature(macro_at_most_once_rep)]
#![feature(crate_in_paths)]
Expand Down
6 changes: 5 additions & 1 deletion src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ declare_features! (
(active, crate_in_paths, "1.23.0", Some(45477), Some(Edition::Edition2018)),

// In-band lifetime bindings (e.g. `fn foo(x: &'a u8) -> &'a u8`)
(active, in_band_lifetimes, "1.23.0", Some(44524), Some(Edition::Edition2018)),
(active, in_band_lifetimes, "1.23.0", Some(44524), None),

// generic associated types (RFC 1598)
(active, generic_associated_types, "1.23.0", Some(44265), None),
Expand Down Expand Up @@ -481,6 +481,10 @@ declare_features! (
(active, alloc_error_handler, "1.29.0", Some(51540), None),

(active, abi_amdgpu_kernel, "1.29.0", Some(51575), None),

// impl<I:Iterator> Iterator for &mut Iterator
// impl Debug for Foo<'_>
(active, impl_header_lifetime_elision, "1.30.0", Some(15872), Some(Edition::Edition2018)),
);

declare_features! (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(warnings)]

// Make sure this related feature didn't accidentally enable this
#![feature(in_band_lifetimes)]

trait MyTrait<'a> { }

impl MyTrait<'a> for &u32 { }
//~^ ERROR missing lifetime specifier

struct MyStruct;
trait MarkerTrait {}

impl MarkerTrait for &'_ MyStruct { }
//~^ ERROR missing lifetime specifier

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0106]: missing lifetime specifier
--> $DIR/feature-gate-impl_header_lifetime_elision-with-in_band.rs:18:22
|
LL | impl MyTrait<'a> for &u32 { }
| ^ expected lifetime parameter

error[E0106]: missing lifetime specifier
--> $DIR/feature-gate-impl_header_lifetime_elision-with-in_band.rs:24:23
|
LL | impl MarkerTrait for &'_ MyStruct { }
| ^^ expected lifetime parameter

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0106`.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0106]: missing lifetime specifier
--> $DIR/feature-gate-in_band_lifetimes-impl.rs:15:26
--> $DIR/feature-gate-impl_header_lifetime_elision.rs:15:26
|
LL | impl<'a> MyTrait<'a> for &u32 { }
| ^ expected lifetime parameter

error[E0106]: missing lifetime specifier
--> $DIR/feature-gate-in_band_lifetimes-impl.rs:18:18
--> $DIR/feature-gate-impl_header_lifetime_elision.rs:18:18
|
LL | impl<'a> MyTrait<'_> for &'a f32 { }
| ^^ expected lifetime parameter
Expand Down
3 changes: 3 additions & 0 deletions src/test/ui/feature-gate-in_band_lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

#![allow(warnings)]

// Make sure this related feature didn't accidentally enable this
#![feature(impl_header_lifetime_elision)]

fn foo(x: &'x u8) -> &'x u8 { x }
//~^ ERROR use of undeclared lifetime name
//~^^ ERROR use of undeclared lifetime name
Expand Down
34 changes: 17 additions & 17 deletions src/test/ui/feature-gate-in_band_lifetimes.stderr
Original file line number Diff line number Diff line change
@@ -1,101 +1,101 @@
error[E0261]: use of undeclared lifetime name `'x`
--> $DIR/feature-gate-in_band_lifetimes.rs:13:12
--> $DIR/feature-gate-in_band_lifetimes.rs:16:12
|
LL | fn foo(x: &'x u8) -> &'x u8 { x }
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'x`
--> $DIR/feature-gate-in_band_lifetimes.rs:13:23
--> $DIR/feature-gate-in_band_lifetimes.rs:16:23
|
LL | fn foo(x: &'x u8) -> &'x u8 { x }
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:25:12
--> $DIR/feature-gate-in_band_lifetimes.rs:28:12
|
LL | impl<'a> X<'b> {
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:27:27
--> $DIR/feature-gate-in_band_lifetimes.rs:30:27
|
LL | fn inner_2(&self) -> &'b u8 {
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:33:8
--> $DIR/feature-gate-in_band_lifetimes.rs:36:8
|
LL | impl X<'b> {
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:35:27
--> $DIR/feature-gate-in_band_lifetimes.rs:38:27
|
LL | fn inner_3(&self) -> &'b u8 {
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/feature-gate-in_band_lifetimes.rs:43:9
--> $DIR/feature-gate-in_band_lifetimes.rs:46:9
|
LL | impl Y<&'a u8> {
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/feature-gate-in_band_lifetimes.rs:45:25
--> $DIR/feature-gate-in_band_lifetimes.rs:48:25
|
LL | fn inner(&self) -> &'a u8 {
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:53:27
--> $DIR/feature-gate-in_band_lifetimes.rs:56:27
|
LL | fn any_lifetime() -> &'b u8;
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:55:27
--> $DIR/feature-gate-in_band_lifetimes.rs:58:27
|
LL | fn borrowed_lifetime(&'b self) -> &'b u8;
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:55:40
--> $DIR/feature-gate-in_band_lifetimes.rs:58:40
|
LL | fn borrowed_lifetime(&'b self) -> &'b u8;
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/feature-gate-in_band_lifetimes.rs:60:14
--> $DIR/feature-gate-in_band_lifetimes.rs:63:14
|
LL | impl MyTrait<'a> for Y<&'a u8> {
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/feature-gate-in_band_lifetimes.rs:60:25
--> $DIR/feature-gate-in_band_lifetimes.rs:63:25
|
LL | impl MyTrait<'a> for Y<&'a u8> {
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/feature-gate-in_band_lifetimes.rs:63:31
--> $DIR/feature-gate-in_band_lifetimes.rs:66:31
|
LL | fn my_lifetime(&self) -> &'a u8 { self.0 }
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:65:27
--> $DIR/feature-gate-in_band_lifetimes.rs:68:27
|
LL | fn any_lifetime() -> &'b u8 { &0 }
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:67:27
--> $DIR/feature-gate-in_band_lifetimes.rs:70:27
|
LL | fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 }
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:67:40
--> $DIR/feature-gate-in_band_lifetimes.rs:70:40
|
LL | fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 }
| ^^ undeclared lifetime
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

#![allow(warnings)]

#![feature(in_band_lifetimes)]
#![feature(impl_header_lifetime_elision)]

trait MyTrait {
type Output;
Expand All @@ -30,7 +30,7 @@ impl MyTrait for &u32 {
}

// This is what you have to do:
impl MyTrait for &'a f32 {
impl<'a> MyTrait for &'a f32 {
type Output = &'a f32;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

#![allow(warnings)]

#![feature(in_band_lifetimes)]
#![feature(impl_header_lifetime_elision)]

use std::fmt::Debug;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// except according to those terms.
#![allow(warnings)]

#![feature(in_band_lifetimes)]
#![feature(impl_header_lifetime_elision)]

trait MyTrait { }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

#![allow(warnings)]

#![feature(in_band_lifetimes)]
#![feature(impl_header_lifetime_elision)]

trait MyTrait { }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

#![allow(warnings)]

#![feature(in_band_lifetimes)]
#![feature(impl_header_lifetime_elision)]

trait MyTrait { }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// except according to those terms.
#![allow(warnings)]

#![feature(in_band_lifetimes)]
#![feature(impl_header_lifetime_elision)]

trait MyTrait<'a> { }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

#![allow(warnings)]

#![feature(in_band_lifetimes)]
#![feature(impl_header_lifetime_elision)]

trait MyTrait<'a> { }

Expand Down

0 comments on commit 45a9d41

Please sign in to comment.