mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Implement underscore lifetimes
This commit is contained in:
parent
e2504cfc76
commit
64314e3ae2
@ -2086,4 +2086,5 @@ register_diagnostics! {
|
||||
E0566, // conflicting representation hints
|
||||
E0623, // lifetime mismatch where both parameters are anonymous regions
|
||||
E0628, // generators cannot have explicit arguments
|
||||
E0637, // "'_" is not a valid lifetime bound
|
||||
}
|
||||
|
@ -159,7 +159,8 @@ impl fmt::Debug for Lifetime {
|
||||
|
||||
impl Lifetime {
|
||||
pub fn is_elided(&self) -> bool {
|
||||
self.name == keywords::Invalid.name()
|
||||
self.name == keywords::Invalid.name() ||
|
||||
self.name == "'_"
|
||||
}
|
||||
|
||||
pub fn is_static(&self) -> bool {
|
||||
|
@ -1422,7 +1422,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
let lifetime_i = &lifetimes[i];
|
||||
|
||||
for lifetime in lifetimes {
|
||||
if lifetime.lifetime.is_static() {
|
||||
if lifetime.lifetime.is_static() || lifetime.lifetime.name == "'_" {
|
||||
let lifetime = lifetime.lifetime;
|
||||
let mut err = struct_span_err!(self.sess, lifetime.span, E0262,
|
||||
"invalid lifetime parameter name: `{}`", lifetime.name);
|
||||
@ -1452,7 +1452,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
self.check_lifetime_def_for_shadowing(old_scope, &lifetime_i.lifetime);
|
||||
|
||||
for bound in &lifetime_i.bounds {
|
||||
if !bound.is_static() {
|
||||
if bound.name == "'_" {
|
||||
let mut err = struct_span_err!(self.sess, bound.span, E0637,
|
||||
"invalid lifetime bound name: `{}`", bound.name);
|
||||
err.span_label(bound.span,
|
||||
format!("{} is a reserved lifetime name", bound.name));
|
||||
err.emit();
|
||||
} else if !bound.is_static() {
|
||||
self.resolve_lifetime_ref(bound);
|
||||
} else {
|
||||
self.insert_lifetime(bound, Region::Static);
|
||||
|
@ -122,14 +122,6 @@ impl<'a> AstValidator<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
fn visit_lifetime(&mut self, lt: &'a Lifetime) {
|
||||
if lt.ident.name == "'_" {
|
||||
self.err_handler().span_err(lt.span, &format!("invalid lifetime name `{}`", lt.ident));
|
||||
}
|
||||
|
||||
visit::walk_lifetime(self, lt)
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'a Expr) {
|
||||
match expr.node {
|
||||
ExprKind::While(.., Some(ident)) |
|
||||
|
@ -389,6 +389,9 @@ declare_features! (
|
||||
// Copy/Clone closures (RFC 2132)
|
||||
(active, clone_closures, "1.22.0", Some(44490)),
|
||||
(active, copy_closures, "1.22.0", Some(44490)),
|
||||
|
||||
// allow `'_` placeholder lifetimes
|
||||
(active, underscore_lifetimes, "1.22.0", Some(44524)),
|
||||
);
|
||||
|
||||
declare_features! (
|
||||
@ -1572,6 +1575,14 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
}
|
||||
visit::walk_lifetime_def(self, lifetime_def)
|
||||
}
|
||||
|
||||
fn visit_lifetime(&mut self, lt: &'a ast::Lifetime) {
|
||||
if lt.ident.name == "'_" {
|
||||
gate_feature_post!(&self, underscore_lifetimes, lt.span,
|
||||
"underscore lifetimes are unstable");
|
||||
}
|
||||
visit::walk_lifetime(self, lt)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute]) -> Features {
|
||||
|
20
src/test/compile-fail/E0637.rs
Normal file
20
src/test/compile-fail/E0637.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// 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.
|
||||
#![feature(underscore_lifetimes)]
|
||||
|
||||
struct Foo<'a: '_>(&'a u8); //~ ERROR invalid lifetime bound name: `'_`
|
||||
fn foo<'a: '_>(_: &'a u8) {} //~ ERROR invalid lifetime bound name: `'_`
|
||||
|
||||
struct Bar<'a>(&'a u8);
|
||||
impl<'a: '_> Bar<'a> { //~ ERROR invalid lifetime bound name: `'_`
|
||||
fn bar() {}
|
||||
}
|
||||
|
||||
fn main() {}
|
20
src/test/compile-fail/feature-gate-underscore-lifetimes.rs
Normal file
20
src/test/compile-fail/feature-gate-underscore-lifetimes.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// 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.
|
||||
|
||||
struct Foo<'a>(&'a u8);
|
||||
|
||||
fn foo(x: &u8) -> Foo<'_> { //~ ERROR underscore lifetimes are unstable
|
||||
Foo(x)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = 5;
|
||||
let _ = foo(&x);
|
||||
}
|
@ -8,12 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn _f<'_>() //~ ERROR invalid lifetime name `'_`
|
||||
-> &'_ u8 //~ ERROR invalid lifetime name `'_`
|
||||
{
|
||||
panic!();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
'_: loop { //~ ERROR invalid label name `'_`
|
||||
break '_ //~ ERROR invalid label name `'_`
|
32
src/test/compile-fail/underscore-lifetime-binders.rs
Normal file
32
src/test/compile-fail/underscore-lifetime-binders.rs
Normal file
@ -0,0 +1,32 @@
|
||||
// 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.
|
||||
|
||||
#![feature(underscore_lifetimes)]
|
||||
|
||||
struct Foo<'a>(&'a u8);
|
||||
|
||||
fn foo<'_> //~ ERROR invalid lifetime parameter name: `'_`
|
||||
(_: Foo<'_>) {}
|
||||
|
||||
trait Meh<'a> {}
|
||||
impl<'a> Meh<'a> for u8 {}
|
||||
|
||||
fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR invalid lifetime parameter name: `'_`
|
||||
//~^ ERROR missing lifetime specifier
|
||||
//~^^ ERROR missing lifetime specifier
|
||||
{
|
||||
Box::new(5u8)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = 5;
|
||||
foo(Foo(&x));
|
||||
let _ = meh();
|
||||
}
|
35
src/test/run-pass/underscore-lifetimes.rs
Normal file
35
src/test/run-pass/underscore-lifetimes.rs
Normal file
@ -0,0 +1,35 @@
|
||||
// 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.
|
||||
|
||||
#![feature(underscore_lifetimes)]
|
||||
|
||||
struct Foo<'a>(&'a u8);
|
||||
|
||||
fn foo(x: &u8) -> Foo<'_> {
|
||||
Foo(x)
|
||||
}
|
||||
|
||||
fn foo2(x: &'_ u8) -> Foo<'_> {
|
||||
Foo(x)
|
||||
}
|
||||
|
||||
fn foo3(x: &'_ u8) -> Foo {
|
||||
Foo(x)
|
||||
}
|
||||
|
||||
fn foo4(_: Foo<'_>) {}
|
||||
|
||||
fn main() {
|
||||
let x = &5;
|
||||
let _ = foo(x);
|
||||
let _ = foo2(x);
|
||||
let _ = foo3(x);
|
||||
foo4(Foo(x));
|
||||
}
|
Loading…
Reference in New Issue
Block a user