From d66ecf69600d7dea0ca5376a3127af1a9a520b5d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 2 Jan 2018 20:05:42 -0800 Subject: [PATCH 1/2] Rename `unstable` feature to `nightly` --- .travis.yml | 4 ++-- Cargo.toml | 11 ++++++++++- README.md | 4 ++-- src/lib.rs | 16 ++++++++-------- tests/test.rs | 4 ++-- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index e5c59af2..c7f7d14e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,9 +11,9 @@ matrix: - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH script: - cargo test - - cargo build --features unstable + - cargo build --features nightly - RUSTFLAGS='--cfg procmacro2_unstable' cargo test - - RUSTFLAGS='--cfg procmacro2_unstable' cargo build --features unstable + - RUSTFLAGS='--cfg procmacro2_unstable' cargo build --features nightly - RUSTFLAGS='--cfg procmacro2_unstable' cargo doc --no-deps after_success: - travis-cargo --only nightly doc-upload diff --git a/Cargo.toml b/Cargo.toml index 19e860f3..ac336074 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,4 +21,13 @@ doctest = false unicode-xid = "0.1" [features] -unstable = [] + +# When enabled: act as a shim around the nightly compiler's proc_macro crate. +# This requires a nightly compiler. +# +# When disabled: emulate the same API as the nightly compiler's proc_macro crate +# but in a way that works on all stable compilers >=1.15.0. +nightly = [] + +# Deprecated; use "nightly" instead. +unstable = ["nightly"] diff --git a/README.md b/README.md index c26ec750..665678b5 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { } ``` -If you'd like you can enable the `unstable` feature in this crate. This will +If you'd like you can enable the `nightly` feature in this crate. This will cause it to compile against the **unstable and nightly-only** features of the `proc_macro` crate. This in turn requires a nightly compiler. This should help preserve span information, however, coming in from the compiler itself. @@ -57,7 +57,7 @@ You can enable this feature via: ```toml [dependencies] -proc-macro2 = { version = "0.1", features = ["unstable"] } +proc-macro2 = { version = "0.1", features = ["nightly"] } ``` diff --git a/src/lib.rs b/src/lib.rs index 26d32446..153b9c84 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,16 +14,16 @@ //! to use this crate will be trivially able to switch to the upstream //! `proc_macro` crate once its API stabilizes. //! -//! In the meantime this crate also has an `unstable` Cargo feature which +//! In the meantime this crate also has a `nightly` Cargo feature which //! enables it to reimplement itself with the unstable API of `proc_macro`. //! This'll allow immediate usage of the beneficial upstream API, particularly //! around preserving span information. -#![cfg_attr(feature = "unstable", feature(proc_macro))] +#![cfg_attr(feature = "nightly", feature(proc_macro))] extern crate proc_macro; -#[cfg(not(feature = "unstable"))] +#[cfg(not(feature = "nightly"))] extern crate unicode_xid; use std::fmt; @@ -31,14 +31,14 @@ use std::str::FromStr; use std::iter::FromIterator; #[macro_use] -#[cfg(not(feature = "unstable"))] +#[cfg(not(feature = "nightly"))] mod strnom; #[path = "stable.rs"] -#[cfg(not(feature = "unstable"))] +#[cfg(not(feature = "nightly"))] mod imp; #[path = "unstable.rs"] -#[cfg(feature = "unstable")] +#[cfg(feature = "nightly")] mod imp; #[macro_use] @@ -162,8 +162,8 @@ impl Span { Span(imp::Span::def_site()) } - /// This method is only available when the `"unstable"` feature is enabled. - #[cfg(feature = "unstable")] + /// This method is only available when the `"nightly"` feature is enabled. + #[cfg(feature = "nightly")] pub fn unstable(self) -> proc_macro::Span { self.0.unstable() } diff --git a/tests/test.rs b/tests/test.rs index 6442ba6b..83208763 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -6,7 +6,7 @@ use proc_macro2::{Term, Literal, TokenStream}; use proc_macro2::TokenNode; #[cfg(procmacro2_unstable)] -#[cfg(not(feature = "unstable"))] +#[cfg(not(feature = "nightly"))] use proc_macro2::Span; #[test] @@ -121,7 +121,7 @@ testing 123 } #[cfg(procmacro2_unstable)] -#[cfg(not(feature = "unstable"))] +#[cfg(not(feature = "nightly"))] #[test] fn default_span() { let start = Span::call_site().start(); From 1ebe397e29491594c5d17cdd52224d8b1a1dfc61 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 2 Jan 2018 20:14:20 -0800 Subject: [PATCH 2/2] Rename procmacro2_unstable to procmacro2_semver_exempt --- .travis.yml | 8 ++++---- README.md | 16 +++++++++++---- src/lib.rs | 20 +++++++++---------- src/stable.rs | 52 ++++++++++++++++++++++++------------------------- src/strnom.rs | 6 +++--- src/unstable.rs | 22 ++++++++++----------- tests/test.rs | 10 +++++----- 7 files changed, 71 insertions(+), 63 deletions(-) diff --git a/.travis.yml b/.travis.yml index c7f7d14e..a524c016 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,15 +12,15 @@ matrix: script: - cargo test - cargo build --features nightly - - RUSTFLAGS='--cfg procmacro2_unstable' cargo test - - RUSTFLAGS='--cfg procmacro2_unstable' cargo build --features nightly - - RUSTFLAGS='--cfg procmacro2_unstable' cargo doc --no-deps + - RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo test + - RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build --features nightly + - RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo doc --no-deps after_success: - travis-cargo --only nightly doc-upload script: - cargo test - - RUSTFLAGS='--cfg procmacro2_unstable' cargo test + - RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo test env: global: - TRAVIS_CARGO_NIGHTLY_FEATURE="" diff --git a/README.md b/README.md index 665678b5..576da8d7 100644 --- a/README.md +++ b/README.md @@ -65,11 +65,19 @@ proc-macro2 = { version = "0.1", features = ["nightly"] } `proc-macro2` supports exporting some methods from `proc_macro` which are currently highly unstable, and may not be stabilized in the first pass of -`proc_macro` stabilizations. These features are not exported by default. +`proc_macro` stabilizations. These features are not exported by default. Minor +versions of `proc-macro2` may make breaking changes to them at any time. -To export these features, the `procmacro2_unstable` config flag must be passed -to rustc. To pass this flag, run `cargo` with -`RUSTFLAGS='--cfg procmacro2_unstable' cargo build`. +To enable these features, the `procmacro2_semver_exempt` config flag must be +passed to rustc. + +``` +RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build +``` + +Note that this must not only be done for your crate, but for any crate that +depends on your crate. This infectious nature is intentional, as it serves as a +reminder that you are outside of the normal semver guarantees. # License diff --git a/src/lib.rs b/src/lib.rs index 153b9c84..49e3d21e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -104,14 +104,14 @@ impl TokenStream { } // Returned by reference, so we can't easily wrap it. -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] pub use imp::FileName; -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] #[derive(Clone, PartialEq, Eq)] pub struct SourceFile(imp::SourceFile); -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] impl SourceFile { /// Get the path to this source file as a string. pub fn path(&self) -> &FileName { @@ -123,21 +123,21 @@ impl SourceFile { } } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] impl AsRef for SourceFile { fn as_ref(&self) -> &FileName { self.0.path() } } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] impl fmt::Debug for SourceFile { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) } } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] pub struct LineColumn { pub line: usize, pub column: usize, @@ -168,24 +168,24 @@ impl Span { self.0.unstable() } - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] pub fn source_file(&self) -> SourceFile { SourceFile(self.0.source_file()) } - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] pub fn start(&self) -> LineColumn { let imp::LineColumn{ line, column } = self.0.start(); LineColumn { line: line, column: column } } - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] pub fn end(&self) -> LineColumn { let imp::LineColumn{ line, column } = self.0.end(); LineColumn { line: line, column: column } } - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] pub fn join(&self, other: Span) -> Option { self.0.join(other.0).map(Span) } diff --git a/src/stable.rs b/src/stable.rs index d892ae52..984a1466 100644 --- a/src/stable.rs +++ b/src/stable.rs @@ -1,7 +1,7 @@ use std::ascii; use std::borrow::Borrow; use std::cell::RefCell; -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] use std::cmp; use std::collections::HashMap; use std::fmt; @@ -36,7 +36,7 @@ impl TokenStream { } } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] fn get_cursor(src: &str) -> Cursor { // Create a dummy file & add it to the codemap CODEMAP.with(|cm| { @@ -50,7 +50,7 @@ fn get_cursor(src: &str) -> Cursor { }) } -#[cfg(not(procmacro2_unstable))] +#[cfg(not(procmacro2_semver_exempt))] fn get_cursor(src: &str) -> Cursor { Cursor { rest: src, @@ -163,24 +163,24 @@ impl IntoIterator for TokenStream { } } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] #[derive(Clone, PartialEq, Eq, Debug)] pub struct FileName(String); -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] impl fmt::Display for FileName { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) } } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] #[derive(Clone, PartialEq, Eq)] pub struct SourceFile { name: FileName, } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] impl SourceFile { /// Get the path to this source file as a string. pub fn path(&self) -> &FileName { @@ -193,14 +193,14 @@ impl SourceFile { } } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] impl AsRef for SourceFile { fn as_ref(&self) -> &FileName { self.path() } } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] impl fmt::Debug for SourceFile { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("SourceFile") @@ -210,14 +210,14 @@ impl fmt::Debug for SourceFile { } } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct LineColumn { pub line: usize, pub column: usize, } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] thread_local! { static CODEMAP: RefCell = RefCell::new(Codemap { // NOTE: We start with a single dummy file which all call_site() and @@ -230,14 +230,14 @@ thread_local! { }); } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] struct FileInfo { name: String, span: Span, lines: Vec, } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] impl FileInfo { fn offset_line_column(&self, offset: usize) -> LineColumn { assert!(self.span_within(Span { lo: offset as u32, hi: offset as u32 })); @@ -260,7 +260,7 @@ impl FileInfo { } /// Computes the offsets of each line in the given source string. -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] fn lines_offsets(s: &str) -> Vec { let mut lines = vec![0]; let mut prev = 0; @@ -271,12 +271,12 @@ fn lines_offsets(s: &str) -> Vec { lines } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] struct Codemap { files: Vec, } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] impl Codemap { fn next_start_pos(&self) -> u32 { // Add 1 so there's always space between files. @@ -313,19 +313,19 @@ impl Codemap { #[derive(Clone, Copy, Debug)] pub struct Span { - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] lo: u32, - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] hi: u32, } impl Span { - #[cfg(not(procmacro2_unstable))] + #[cfg(not(procmacro2_semver_exempt))] pub fn call_site() -> Span { Span {} } - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] pub fn call_site() -> Span { Span { lo: 0, hi: 0 } } @@ -334,7 +334,7 @@ impl Span { Span::call_site() } - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] pub fn source_file(&self) -> SourceFile { CODEMAP.with(|cm| { let cm = cm.borrow(); @@ -345,7 +345,7 @@ impl Span { }) } - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] pub fn start(&self) -> LineColumn { CODEMAP.with(|cm| { let cm = cm.borrow(); @@ -354,7 +354,7 @@ impl Span { }) } - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] pub fn end(&self) -> LineColumn { CODEMAP.with(|cm| { let cm = cm.borrow(); @@ -363,7 +363,7 @@ impl Span { }) } - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] pub fn join(&self, other: Span) -> Option { CODEMAP.with(|cm| { let cm = cm.borrow(); @@ -578,7 +578,7 @@ named!(token_stream -> ::TokenStream, map!( |trees| ::TokenStream(TokenStream { inner: trees }) )); -#[cfg(not(procmacro2_unstable))] +#[cfg(not(procmacro2_semver_exempt))] fn token_tree(input: Cursor) -> PResult { let (input, kind) = token_kind(input)?; Ok((input, TokenTree { @@ -587,7 +587,7 @@ fn token_tree(input: Cursor) -> PResult { })) } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] fn token_tree(input: Cursor) -> PResult { let input = skip_whitespace(input); let lo = input.off; diff --git a/src/strnom.rs b/src/strnom.rs index 2f9e73fd..35acff72 100644 --- a/src/strnom.rs +++ b/src/strnom.rs @@ -9,18 +9,18 @@ use imp::LexError; #[derive(Copy, Clone, Eq, PartialEq)] pub struct Cursor<'a> { pub rest: &'a str, - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] pub off: u32, } impl<'a> Cursor<'a> { - #[cfg(not(procmacro2_unstable))] + #[cfg(not(procmacro2_semver_exempt))] pub fn advance(&self, amt: usize) -> Cursor<'a> { Cursor { rest: &self.rest[amt..], } } - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] pub fn advance(&self, amt: usize) -> Cursor<'a> { Cursor { rest: &self.rest[amt..], diff --git a/src/unstable.rs b/src/unstable.rs index 56df0dd3..f8cd68c2 100644 --- a/src/unstable.rs +++ b/src/unstable.rs @@ -159,11 +159,11 @@ impl fmt::Debug for TokenTreeIter { } } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] #[derive(Clone, PartialEq, Eq)] pub struct FileName(String); -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] impl fmt::Display for FileName { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) @@ -172,11 +172,11 @@ impl fmt::Display for FileName { // NOTE: We have to generate our own filename object here because we can't wrap // the one provided by proc_macro. -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] #[derive(Clone, PartialEq, Eq)] pub struct SourceFile(proc_macro::SourceFile, FileName); -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] impl SourceFile { fn new(sf: proc_macro::SourceFile) -> Self { let filename = FileName(sf.path().to_string()); @@ -193,21 +193,21 @@ impl SourceFile { } } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] impl AsRef for SourceFile { fn as_ref(&self) -> &FileName { self.path() } } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] impl fmt::Debug for SourceFile { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) } } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] pub struct LineColumn { pub line: usize, pub column: usize, @@ -229,24 +229,24 @@ impl Span { self.0 } - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] pub fn source_file(&self) -> SourceFile { SourceFile::new(self.0.source_file()) } - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] pub fn start(&self) -> LineColumn { let proc_macro::LineColumn{ line, column } = self.0.start(); LineColumn { line, column } } - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] pub fn end(&self) -> LineColumn { let proc_macro::LineColumn{ line, column } = self.0.end(); LineColumn { line, column } } - #[cfg(procmacro2_unstable)] + #[cfg(procmacro2_semver_exempt)] pub fn join(&self, other: Span) -> Option { self.0.join(other.0).map(Span) } diff --git a/tests/test.rs b/tests/test.rs index 83208763..89f7b102 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -2,10 +2,10 @@ extern crate proc_macro2; use proc_macro2::{Term, Literal, TokenStream}; -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] use proc_macro2::TokenNode; -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] #[cfg(not(feature = "nightly"))] use proc_macro2::Span; @@ -72,7 +72,7 @@ fn fail() { fail("'mut"); } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] #[test] fn span_test() { fn check_spans(p: &str, mut lines: &[(usize, usize, usize, usize)]) { @@ -120,7 +120,7 @@ testing 123 ]); } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] #[cfg(not(feature = "nightly"))] #[test] fn default_span() { @@ -135,7 +135,7 @@ fn default_span() { assert!(!source_file.is_real()); } -#[cfg(procmacro2_unstable)] +#[cfg(procmacro2_semver_exempt)] #[test] fn span_join() { let source1 =