mirror of
https://gitee.com/openharmony/third_party_rust_proc-macro2
synced 2024-11-23 07:19:41 +00:00
Automatically use rich API on 1.30.0+
This commit detects the rustc version in the build script of proc-macro2 to determine whether the compiler supports the necessary backend APIs. This should hopefully allow the crate to compile on stable by default but have a better implementation on 1.30.0+ compilers.
This commit is contained in:
parent
ff8e52f171
commit
ce0904dc1a
32
README.md
32
README.md
@ -5,25 +5,20 @@
|
||||
[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/proc-macro2)
|
||||
|
||||
A small shim over the `proc_macro` crate in the compiler intended to multiplex
|
||||
the current stable interface (as of 2017-07-05) and the [upcoming richer
|
||||
interface][upcoming].
|
||||
the stable interface as of 1.15.0 and the interface as of 1.30.0.
|
||||
|
||||
[upcoming]: https://github.com/rust-lang/rust/pull/40939
|
||||
|
||||
The upcoming support has features like:
|
||||
New features added in Rust 1.30.0 include:
|
||||
|
||||
* Span information on tokens
|
||||
* No need to go in/out through strings
|
||||
* Structured input/output
|
||||
|
||||
The hope is that libraries ported to `proc_macro2` will be trivial to port to
|
||||
the real `proc_macro` crate once the support on nightly is stabilized.
|
||||
Libraries ported to `proc_macro2` can retain support for older compilers while
|
||||
continuing to get all the nice benefits of using a 1.30.0+ compiler.
|
||||
|
||||
## Usage
|
||||
|
||||
This crate by default compiles on the stable version of the compiler. It only
|
||||
uses the stable surface area of the `proc_macro` crate upstream in the compiler
|
||||
itself. Usage is done via:
|
||||
This crate compiles on all 1.15.0+ stable compilers and usage looks like:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
@ -48,23 +43,13 @@ pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
}
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
You can enable this feature via:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
proc-macro2 = { version = "0.4", features = ["nightly"] }
|
||||
```
|
||||
|
||||
The 1.30.0 compiler is automatically detected and its interfaces are used when
|
||||
available.
|
||||
|
||||
## Unstable Features
|
||||
|
||||
`proc-macro2` supports exporting some methods from `proc_macro` which are
|
||||
currently highly unstable, and may not be stabilized in the first pass of
|
||||
currently highly unstable, and are not stabilized in the first pass of
|
||||
`proc_macro` stabilizations. These features are not exported by default. Minor
|
||||
versions of `proc-macro2` may make breaking changes to them at any time.
|
||||
|
||||
@ -79,7 +64,6 @@ 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
|
||||
|
||||
This project is licensed under either of
|
||||
|
44
build.rs
44
build.rs
@ -1,21 +1,53 @@
|
||||
use std::env;
|
||||
use std::process::Command;
|
||||
use std::str;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
|
||||
let target = env::var("TARGET").unwrap();
|
||||
|
||||
maybe_enable_use_proc_macro(&target);
|
||||
if !enable_use_proc_macro(&target) {
|
||||
return
|
||||
}
|
||||
println!("cargo:rustc-cfg=use_proc_macro");
|
||||
|
||||
let minor = match rustc_minor_version() {
|
||||
Some(n) => n,
|
||||
None => return,
|
||||
};
|
||||
|
||||
// Rust 1.30 stabilized the necessary APIs in the `proc_macro` crate
|
||||
if minor >= 30 || cfg!(feature = "nightly") {
|
||||
println!("cargo:rustc-cfg=wrap_proc_macro");
|
||||
|
||||
if cfg!(procmacro2_semver_exempt) {
|
||||
println!("cargo:rustc-cfg=super_unstable");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_enable_use_proc_macro(target: &str) {
|
||||
fn enable_use_proc_macro(target: &str) -> bool {
|
||||
// wasm targets don't have the `proc_macro` crate, disable this feature.
|
||||
if target.contains("wasm32") {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, only enable it if our feature is actually enabled.
|
||||
if cfg!(feature = "proc-macro") {
|
||||
println!("cargo:rustc-cfg=use_proc_macro");
|
||||
}
|
||||
cfg!(feature = "proc-macro")
|
||||
}
|
||||
|
||||
fn rustc_minor_version() -> Option<u32> {
|
||||
macro_rules! otry {
|
||||
($e:expr) => (match $e { Some(e) => e, None => return None })
|
||||
}
|
||||
let rustc = otry!(env::var_os("RUSTC"));
|
||||
let output = otry!(Command::new(rustc).arg("--version").output().ok());
|
||||
let version = otry!(str::from_utf8(&output.stdout).ok());
|
||||
let mut pieces = version.split('.');
|
||||
if pieces.next() != Some("rustc 1") {
|
||||
return None;
|
||||
}
|
||||
otry!(pieces.next()).parse().ok()
|
||||
}
|
||||
|
@ -45,7 +45,7 @@
|
||||
// Proc-macro2 types in rustdoc of other crates get linked to here.
|
||||
#![doc(html_root_url = "https://docs.rs/proc-macro2/0.4.13")]
|
||||
#![cfg_attr(
|
||||
feature = "nightly",
|
||||
super_unstable,
|
||||
feature(proc_macro_raw_ident, proc_macro_span)
|
||||
)]
|
||||
|
||||
@ -65,10 +65,10 @@ use std::str::FromStr;
|
||||
mod strnom;
|
||||
mod stable;
|
||||
|
||||
#[cfg(not(feature = "nightly"))]
|
||||
#[cfg(not(wrap_proc_macro))]
|
||||
use stable as imp;
|
||||
#[path = "unstable.rs"]
|
||||
#[cfg(feature = "nightly")]
|
||||
#[cfg(wrap_proc_macro)]
|
||||
mod imp;
|
||||
|
||||
/// An abstract stream of tokens, or more concretely a sequence of token trees.
|
||||
@ -328,7 +328,7 @@ impl Span {
|
||||
}
|
||||
|
||||
/// This method is only available when the `"nightly"` feature is enabled.
|
||||
#[cfg(all(feature = "nightly", use_proc_macro))]
|
||||
#[cfg(super_unstable)]
|
||||
pub fn unstable(self) -> proc_macro::Span {
|
||||
self.inner.unstable()
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![cfg_attr(not(procmacro2_semver_exempt), allow(dead_code))]
|
||||
#![cfg_attr(not(super_unstable), allow(dead_code))]
|
||||
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
@ -292,11 +292,13 @@ pub use stable::FileName;
|
||||
// NOTE: We have to generate our own filename object here because we can't wrap
|
||||
// the one provided by proc_macro.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[cfg(super_unstable)]
|
||||
pub enum SourceFile {
|
||||
Nightly(proc_macro::SourceFile, FileName),
|
||||
Stable(stable::SourceFile),
|
||||
}
|
||||
|
||||
#[cfg(super_unstable)]
|
||||
impl SourceFile {
|
||||
fn nightly(sf: proc_macro::SourceFile) -> Self {
|
||||
let filename = stable::file_name(sf.path().display().to_string());
|
||||
@ -319,12 +321,14 @@ impl SourceFile {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(super_unstable)]
|
||||
impl AsRef<FileName> for SourceFile {
|
||||
fn as_ref(&self) -> &FileName {
|
||||
self.path()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(super_unstable)]
|
||||
impl fmt::Debug for SourceFile {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
@ -354,6 +358,7 @@ impl Span {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(super_unstable)]
|
||||
pub fn def_site() -> Span {
|
||||
if nightly_works() {
|
||||
Span::Nightly(proc_macro::Span::def_site())
|
||||
@ -362,6 +367,7 @@ impl Span {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(super_unstable)]
|
||||
pub fn resolved_at(&self, other: Span) -> Span {
|
||||
match (self, other) {
|
||||
(Span::Nightly(a), Span::Nightly(b)) => Span::Nightly(a.resolved_at(b)),
|
||||
@ -370,6 +376,7 @@ impl Span {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(super_unstable)]
|
||||
pub fn located_at(&self, other: Span) -> Span {
|
||||
match (self, other) {
|
||||
(Span::Nightly(a), Span::Nightly(b)) => Span::Nightly(a.located_at(b)),
|
||||
@ -385,7 +392,7 @@ impl Span {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(procmacro2_semver_exempt)]
|
||||
#[cfg(super_unstable)]
|
||||
pub fn source_file(&self) -> SourceFile {
|
||||
match self {
|
||||
Span::Nightly(s) => SourceFile::nightly(s.source_file()),
|
||||
@ -393,7 +400,7 @@ impl Span {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(procmacro2_semver_exempt)]
|
||||
#[cfg(super_unstable)]
|
||||
pub fn start(&self) -> LineColumn {
|
||||
match self {
|
||||
Span::Nightly(s) => {
|
||||
@ -407,7 +414,7 @@ impl Span {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(procmacro2_semver_exempt)]
|
||||
#[cfg(super_unstable)]
|
||||
pub fn end(&self) -> LineColumn {
|
||||
match self {
|
||||
Span::Nightly(s) => {
|
||||
@ -421,7 +428,7 @@ impl Span {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(procmacro2_semver_exempt)]
|
||||
#[cfg(super_unstable)]
|
||||
pub fn join(&self, other: Span) -> Option<Span> {
|
||||
let ret = match (self, other) {
|
||||
(Span::Nightly(a), Span::Nightly(b)) => Span::Nightly(a.join(b)?),
|
||||
@ -431,6 +438,7 @@ impl Span {
|
||||
Some(ret)
|
||||
}
|
||||
|
||||
#[cfg(super_unstable)]
|
||||
pub fn eq(&self, other: &Span) -> bool {
|
||||
match (self, other) {
|
||||
(Span::Nightly(a), Span::Nightly(b)) => a.eq(b),
|
||||
@ -484,7 +492,17 @@ impl Ident {
|
||||
|
||||
pub fn new_raw(string: &str, span: Span) -> Ident {
|
||||
match span {
|
||||
Span::Nightly(s) => Ident::Nightly(proc_macro::Ident::new_raw(string, s)),
|
||||
Span::Nightly(s) => {
|
||||
let p: proc_macro::TokenStream = string.parse().unwrap();
|
||||
let ident = match p.into_iter().next() {
|
||||
Some(proc_macro::TokenTree::Ident(mut i)) => {
|
||||
i.set_span(s);
|
||||
i
|
||||
}
|
||||
_ => panic!(),
|
||||
};
|
||||
Ident::Nightly(ident)
|
||||
}
|
||||
Span::Stable(s) => Ident::Stable(stable::Ident::new_raw(string, s)),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user