From 03a51019a40c1c5e2ab1635f993fc71517d1edc2 Mon Sep 17 00:00:00 2001 From: Michael Hewson Date: Wed, 10 May 2017 00:30:47 +0000 Subject: Resurrecting #33135 Started rebasing @sgrif's PR #33135 off of current master. (Well, actually merging it into a new branch based off current master.) The following files still need to be fixed or at least reviewed: - `src/libsyntax/ext/tt/macro_parser.rs`: calls `Parser::parse_lifetime`, which doesn't exist anymore - `src/libsyntax/parse/parser.rs`: @sgrif added an error message to `Parser::parse_lifetime`. Code has since been refactored, so I just took it out for now. - `src/libsyntax/ext/tt/transcribe.rs`: This code has been refactored bigtime. Not sure whether @sgrif's changes here are still necessary. Took it out for this commit. --- .../run-pass/macro-lifetime-used-with-bound.rs | 23 ++++++++++++++++++++++ .../run-pass/macro-lifetime-used-with-static.rs | 23 ++++++++++++++++++++++ src/test/run-pass/macro-lifetime.rs | 23 ++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 src/test/run-pass/macro-lifetime-used-with-bound.rs create mode 100644 src/test/run-pass/macro-lifetime-used-with-static.rs create mode 100644 src/test/run-pass/macro-lifetime.rs (limited to 'src/test') diff --git a/src/test/run-pass/macro-lifetime-used-with-bound.rs b/src/test/run-pass/macro-lifetime-used-with-bound.rs new file mode 100644 index 00000000000..b9e1fde6b1f --- /dev/null +++ b/src/test/run-pass/macro-lifetime-used-with-bound.rs @@ -0,0 +1,23 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +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); +} diff --git a/src/test/run-pass/macro-lifetime-used-with-static.rs b/src/test/run-pass/macro-lifetime-used-with-static.rs new file mode 100644 index 00000000000..5c1f8683e00 --- /dev/null +++ b/src/test/run-pass/macro-lifetime-used-with-static.rs @@ -0,0 +1,23 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +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); +} diff --git a/src/test/run-pass/macro-lifetime.rs b/src/test/run-pass/macro-lifetime.rs new file mode 100644 index 00000000000..ff5798ff78d --- /dev/null +++ b/src/test/run-pass/macro-lifetime.rs @@ -0,0 +1,23 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +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); +} -- cgit 1.4.1-3-g733a5 From 0e53360af69bf9e71ef39e570655d73fc44339b9 Mon Sep 17 00:00:00 2001 From: Matt Peterson Date: Wed, 20 Dec 2017 15:37:22 -0500 Subject: Fix build and add a macro lifetime labels test --- src/libsyntax/ext/quote.rs | 3 +- .../run-pass/macro-lifetime-used-with-labels.rs | 43 ++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/test/run-pass/macro-lifetime-used-with-labels.rs (limited to 'src/test') diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index a0d72b786bf..59996d1e4a7 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -192,8 +192,7 @@ pub mod rt { impl ToTokens for ast::Lifetime { fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - let lifetime_ident = ast::Ident::with_empty_ctxt(self.name); - vec![TokenTree::Token(DUMMY_SP, token::Lifetime(lifetime_ident))] + vec![TokenTree::Token(DUMMY_SP, token::Lifetime(self.ident))] } } diff --git a/src/test/run-pass/macro-lifetime-used-with-labels.rs b/src/test/run-pass/macro-lifetime-used-with-labels.rs new file mode 100644 index 00000000000..d003d7dcfb6 --- /dev/null +++ b/src/test/run-pass/macro-lifetime-used-with-labels.rs @@ -0,0 +1,43 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(unreachable_code)] + +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"); + } +} -- cgit 1.4.1-3-g733a5 From b2844190640fc9a69d087e30e3c3cf37cbd40142 Mon Sep 17 00:00:00 2001 From: Matt Peterson Date: Thu, 21 Dec 2017 10:44:44 -0500 Subject: Add feature gate macro_lifetime_matcher --- src/libsyntax/ext/tt/macro_rules.rs | 14 +++++++++++++- src/libsyntax/feature_gate.rs | 8 +++++++- src/test/run-pass/macro-lifetime-used-with-bound.rs | 2 ++ src/test/run-pass/macro-lifetime-used-with-labels.rs | 1 + src/test/run-pass/macro-lifetime-used-with-static.rs | 2 ++ src/test/run-pass/macro-lifetime.rs | 2 ++ src/test/ui/feature-gate-macro-lifetime-matcher.rs | 19 +++++++++++++++++++ .../ui/feature-gate-macro-lifetime-matcher.stderr | 10 ++++++++++ 8 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/feature-gate-macro-lifetime-matcher.rs create mode 100644 src/test/ui/feature-gate-macro-lifetime-matcher.stderr (limited to 'src/test') diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 8f2e571c213..5412decd3b7 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -886,8 +886,20 @@ fn is_legal_fragment_specifier(sess: &ParseSess, frag_name: &str, frag_span: Span) -> bool { match frag_name { - "item" | "block" | "stmt" | "expr" | "pat" | "lifetime" | + "item" | "block" | "stmt" | "expr" | "pat" | "path" | "ty" | "ident" | "meta" | "tt" | "" => true, + "lifetime" => { + if !features.borrow().macro_lifetime_matcher + && !attr::contains_name(attrs, "allow_internal_unstable") { + let explain = feature_gate::EXPLAIN_LIFETIME_MATCHER; + emit_feature_err(sess, + "macro_lifetime_matcher", + frag_span, + GateIssue::Language, + explain); + } + true + }, "vis" => { if !features.borrow().macro_vis_matcher && !attr::contains_name(attrs, "allow_internal_unstable") { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 7ae360678cd..471251b0630 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -447,6 +447,9 @@ declare_features! ( // Termination trait in main (RFC 1937) (active, termination_trait, "1.24.0", Some(43301)), + + // Allows use of the :lifetime macro fragment specifier + (active, macro_lifetime_matcher, "1.24.0", Some(46895)), ); declare_features! ( @@ -520,7 +523,7 @@ declare_features! ( (accepted, loop_break_value, "1.19.0", Some(37339)), // Permits numeric fields in struct expressions and patterns. (accepted, relaxed_adts, "1.19.0", Some(35626)), - // Coerces non capturing closures to function pointers + // Coerces non capturing closures to function pointers (accepted, closure_to_fn_coercion, "1.19.0", Some(39817)), // Allows attributes on struct literal fields. (accepted, struct_field_attributes, "1.20.0", Some(38814)), @@ -1226,6 +1229,9 @@ pub const EXPLAIN_DERIVE_UNDERSCORE: &'static str = pub const EXPLAIN_VIS_MATCHER: &'static str = ":vis fragment specifier is experimental and subject to change"; +pub const EXPLAIN_LIFETIME_MATCHER: &'static str = + ":lifetime fragment specifier is experimental and subject to change"; + pub const EXPLAIN_PLACEMENT_IN: &'static str = "placement-in expression syntax is experimental and subject to change."; diff --git a/src/test/run-pass/macro-lifetime-used-with-bound.rs b/src/test/run-pass/macro-lifetime-used-with-bound.rs index b9e1fde6b1f..b0c9280b6ce 100644 --- a/src/test/run-pass/macro-lifetime-used-with-bound.rs +++ b/src/test/run-pass/macro-lifetime-used-with-bound.rs @@ -8,6 +8,8 @@ // 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 { diff --git a/src/test/run-pass/macro-lifetime-used-with-labels.rs b/src/test/run-pass/macro-lifetime-used-with-labels.rs index d003d7dcfb6..8a2d76e17df 100644 --- a/src/test/run-pass/macro-lifetime-used-with-labels.rs +++ b/src/test/run-pass/macro-lifetime-used-with-labels.rs @@ -9,6 +9,7 @@ // except according to those terms. #![allow(unreachable_code)] +#![feature(macro_lifetime_matcher)] macro_rules! x { ($a:lifetime) => { diff --git a/src/test/run-pass/macro-lifetime-used-with-static.rs b/src/test/run-pass/macro-lifetime-used-with-static.rs index 5c1f8683e00..468ee2e9436 100644 --- a/src/test/run-pass/macro-lifetime-used-with-static.rs +++ b/src/test/run-pass/macro-lifetime-used-with-static.rs @@ -8,6 +8,8 @@ // 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 { diff --git a/src/test/run-pass/macro-lifetime.rs b/src/test/run-pass/macro-lifetime.rs index ff5798ff78d..db521ca7f10 100644 --- a/src/test/run-pass/macro-lifetime.rs +++ b/src/test/run-pass/macro-lifetime.rs @@ -8,6 +8,8 @@ // 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 { diff --git a/src/test/ui/feature-gate-macro-lifetime-matcher.rs b/src/test/ui/feature-gate-macro-lifetime-matcher.rs new file mode 100644 index 00000000000..0d107d283cd --- /dev/null +++ b/src/test/ui/feature-gate-macro-lifetime-matcher.rs @@ -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 or the MIT license +// , 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); +} diff --git a/src/test/ui/feature-gate-macro-lifetime-matcher.stderr b/src/test/ui/feature-gate-macro-lifetime-matcher.stderr new file mode 100644 index 00000000000..e78f7684cf2 --- /dev/null +++ b/src/test/ui/feature-gate-macro-lifetime-matcher.stderr @@ -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 + -- cgit 1.4.1-3-g733a5