Auto merge of #46895 - ricochet1k:macro-lifetimes, r=jseyfried

Allow lifetimes in macros

This is a resurrection of PR #41927 which was a resurrection of #33135, which is intended to fix #34303.

In short, this allows macros_rules! to use :lifetime as a matcher to match 'lifetimes.

Still to do:
- [x]  Feature gate
This commit is contained in:
bors 2018-01-01 07:21:23 +00:00
commit 1bcc6dc7ea
15 changed files with 231 additions and 21 deletions

View file

@ -0,0 +1,25 @@
// Copyright 2012 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(macro_lifetime_matcher)]
macro_rules! foo {
($l:lifetime, $l2:lifetime) => {
fn f<$l: $l2, $l2>(arg: &$l str, arg2: &$l2 str) -> &$l str {
arg
}
}
}
pub fn main() {
foo!('a, 'b);
let x: &'static str = f("hi", "there");
assert_eq!("hi", x);
}

View file

@ -0,0 +1,44 @@
// Copyright 2012 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(unreachable_code)]
#![feature(macro_lifetime_matcher)]
macro_rules! x {
($a:lifetime) => {
$a: loop {
break $a;
panic!("failed");
}
}
}
macro_rules! br {
($a:lifetime) => {
break $a;
}
}
macro_rules! br2 {
($b:lifetime) => {
'b: loop {
break $b; // this $b should refer to the outer loop.
}
}
}
fn main() {
x!('a);
'c: loop {
br!('c);
panic!("failed");
}
'b: loop {
br2!('b);
panic!("failed");
}
}

View file

@ -0,0 +1,25 @@
// Copyright 2012 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(macro_lifetime_matcher)]
macro_rules! foo {
($l:lifetime) => {
fn f(arg: &$l str) -> &$l str {
arg
}
}
}
pub fn main() {
foo!('static);
let x: &'static str = f("hi");
assert_eq!("hi", x);
}

View file

@ -0,0 +1,25 @@
// Copyright 2012 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(macro_lifetime_matcher)]
macro_rules! foo {
($l:lifetime) => {
fn f<$l>(arg: &$l str) -> &$l str {
arg
}
}
}
pub fn main() {
foo!('a);
let x: &'static str = f("hi");
assert_eq!("hi", x);
}

View file

@ -0,0 +1,19 @@
// 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.
// Test that the :lifetime macro fragment cannot be used when macro_lifetime_matcher
// feature gate is not used.
macro_rules! m { ($lt:lifetime) => {} }
//~^ ERROR :lifetime fragment specifier is experimental and subject to change
fn main() {
m!('a);
}

View file

@ -0,0 +1,10 @@
error: :lifetime fragment specifier is experimental and subject to change (see issue #46895)
--> $DIR/feature-gate-macro-lifetime-matcher.rs:14:19
|
14 | macro_rules! m { ($lt:lifetime) => {} }
| ^^^^^^^^^^^^
|
= help: add #![feature(macro_lifetime_matcher)] to the crate attributes to enable
error: aborting due to previous error