Auto merge of #53016 - scottmcm:impl-header-lifetime-elision, 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 https://github.com/rust-lang/rust/pull/49251; Tracking Issue https://github.com/rust-lang/rust/issues/15872; In-band lifetimes tracking issue https://github.com/rust-lang/rust/issues/44524.

cc @aturon, per discussion on discord earlier
cc @cramertj & @nikomatsakis, who actually wrote these features
This commit is contained in:
bors 2018-08-06 21:45:32 +00:00
commit 45a9d410f9
21 changed files with 88 additions and 32 deletions

View File

@ -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.
@ -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);
@ -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;
}

View File

@ -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)]

View File

@ -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),
@ -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! (

View File

@ -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() {}

View File

@ -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`.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -13,7 +13,7 @@
#![allow(warnings)]
#![feature(in_band_lifetimes)]
#![feature(impl_header_lifetime_elision)]
trait MyTrait {
type Output;
@ -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;
}

View File

@ -13,7 +13,7 @@
#![allow(warnings)]
#![feature(in_band_lifetimes)]
#![feature(impl_header_lifetime_elision)]
use std::fmt::Debug;

View File

@ -9,7 +9,7 @@
// except according to those terms.
#![allow(warnings)]
#![feature(in_band_lifetimes)]
#![feature(impl_header_lifetime_elision)]
trait MyTrait { }

View File

@ -14,7 +14,7 @@
#![allow(warnings)]
#![feature(in_band_lifetimes)]
#![feature(impl_header_lifetime_elision)]
trait MyTrait { }

View File

@ -14,7 +14,7 @@
#![allow(warnings)]
#![feature(in_band_lifetimes)]
#![feature(impl_header_lifetime_elision)]
trait MyTrait { }

View File

@ -9,7 +9,7 @@
// except according to those terms.
#![allow(warnings)]
#![feature(in_band_lifetimes)]
#![feature(impl_header_lifetime_elision)]
trait MyTrait<'a> { }

View File

@ -15,7 +15,7 @@
#![allow(warnings)]
#![feature(in_band_lifetimes)]
#![feature(impl_header_lifetime_elision)]
trait MyTrait<'a> { }