diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-07 05:16:46 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-07 05:16:46 +0000 |
commit | 3dfd2c09458b4b315a2913d27447d6ca565b3031 (patch) | |
tree | d1b307b141634c64710226695aca99d28b4c377f | |
parent | 0c2e319ae98e2ee744e5ae16c2156824cf133d43 (diff) | |
parent | 5449335803dfea4e815c47fd8c3f46ce7fa4e216 (diff) | |
download | rustversion-aml_uwb_341513070.tar.gz |
Snap for 10453563 from 5449335803dfea4e815c47fd8c3f46ce7fa4e216 to mainline-uwb-releaseaml_uwb_341710010aml_uwb_341513070aml_uwb_341511050aml_uwb_341310300aml_uwb_341310030aml_uwb_341111010aml_uwb_341011000android14-mainline-uwb-release
Change-Id: I195e791bb92bb795c7fcbd400ffda7ca99c97d53
-rw-r--r-- | .cargo_vcs_info.json | 7 | ||||
-rw-r--r-- | .github/FUNDING.yml | 1 | ||||
-rw-r--r-- | .github/workflows/ci.yml | 63 | ||||
-rw-r--r-- | Android.bp | 4 | ||||
-rw-r--r-- | Cargo.toml | 21 | ||||
-rw-r--r-- | Cargo.toml.orig | 13 | ||||
-rw-r--r-- | LICENSE-APACHE | 25 | ||||
-rw-r--r-- | METADATA | 14 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | TEST_MAPPING | 9 | ||||
-rw-r--r-- | build/build.rs | 82 | ||||
-rw-r--r-- | build/rustc.rs | 20 | ||||
-rw-r--r-- | patches/version.diff | 37 | ||||
-rw-r--r-- | src/expand.rs | 72 | ||||
-rw-r--r-- | src/lib.rs | 109 | ||||
-rw-r--r-- | tests/compiletest.rs | 1 | ||||
-rw-r--r-- | tests/test_const.rs | 2 | ||||
-rw-r--r-- | tests/test_parse.rs | 13 | ||||
-rw-r--r-- | tests/ui/bad-bound.stderr | 4 | ||||
-rw-r--r-- | tests/ui/bad-date.stderr | 4 | ||||
-rw-r--r-- | tests/ui/bad-not.stderr | 4 | ||||
-rw-r--r-- | tests/ui/bad-version.stderr | 4 | ||||
-rw-r--r-- | tests/ui/const-not-fn.stderr | 2 |
23 files changed, 326 insertions, 189 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 6895b5b..6f0afbd 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,6 @@ { "git": { - "sha1": "ecc07fb53f45a093811484d4ee1ac791144defd7" - } -} + "sha1": "a85f2db274e1367a945a83ed4fe5a7a53d8f4f0e" + }, + "path_in_vcs": "" +}
\ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..7507077 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: dtolnay diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ba68d6..748c2b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,28 +3,58 @@ name: CI on: push: pull_request: + workflow_dispatch: schedule: [cron: "40 1 * * *"] +permissions: + contents: read + +env: + RUSTFLAGS: -Dwarnings + jobs: + pre_ci: + uses: dtolnay/.github/.github/workflows/pre_ci.yml@master + test: name: Rust ${{matrix.rust}} + needs: pre_ci + if: needs.pre_ci.outputs.continue runs-on: ubuntu-latest strategy: fail-fast: false matrix: - rust: [nightly, beta, stable, 1.31.0] + rust: [nightly, beta, stable, 1.56.0] + timeout-minutes: 45 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{matrix.rust}} + - name: Enable type layout randomization + run: echo RUSTFLAGS=${RUSTFLAGS}\ -Zrandomize-layout >> $GITHUB_ENV + if: matrix.rust == 'nightly' - run: cargo test + msrv: + name: Rust 1.31.0 + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@1.31.0 + - run: cargo check + minimal: name: Minimal versions + needs: pre_ci + if: needs.pre_ci.outputs.continue runs-on: ubuntu-latest + timeout-minutes: 45 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@nightly - run: cargo update -Z minimal-versions - run: cargo test @@ -32,7 +62,32 @@ jobs: clippy: name: Clippy runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + timeout-minutes: 45 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@clippy - run: cargo clippy --tests -- -Dclippy::all -Dclippy::pedantic + + miri: + name: Miri + needs: pre_ci + if: needs.pre_ci.outputs.continue + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@miri + - run: cargo miri test + env: + MIRIFLAGS: -Zmiri-strict-provenance + + outdated: + name: Outdated + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + timeout-minutes: 45 + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/install@cargo-outdated + - run: cargo outdated --workspace --exit-code 1 @@ -41,7 +41,9 @@ rust_proc_macro { name: "librustversion", crate_name: "rustversion", cargo_env_compat: true, - cargo_pkg_version: "1.0.5", + cargo_pkg_version: "1.0.12", srcs: ["src/lib.rs"], edition: "2018", + product_available: true, + vendor_available: true, } @@ -3,28 +3,35 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. [package] edition = "2018" +rust-version = "1.31" name = "rustversion" -version = "1.0.5" +version = "1.0.12" authors = ["David Tolnay <dtolnay@gmail.com>"] build = "build/build.rs" description = "Conditional compilation according to rustc compiler version" documentation = "https://docs.rs/rustversion" readme = "README.md" +categories = [ + "development-tools::build-utils", + "no-std", +] license = "MIT OR Apache-2.0" repository = "https://github.com/dtolnay/rustversion" + [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] [lib] proc-macro = true + [dev-dependencies.trybuild] -version = "1.0.35" +version = "1.0.49" +features = ["diff"] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 75f8ea1..6f5c372 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,20 +1,21 @@ [package] name = "rustversion" -version = "1.0.5" +version = "1.0.12" authors = ["David Tolnay <dtolnay@gmail.com>"] +build = "build/build.rs" +categories = ["development-tools::build-utils", "no-std"] +description = "Conditional compilation according to rustc compiler version" +documentation = "https://docs.rs/rustversion" edition = "2018" license = "MIT OR Apache-2.0" -description = "Conditional compilation according to rustc compiler version" repository = "https://github.com/dtolnay/rustversion" -documentation = "https://docs.rs/rustversion" -readme = "README.md" -build = "build/build.rs" +rust-version = "1.31" [lib] proc-macro = true [dev-dependencies] -trybuild = "1.0.35" +trybuild = { version = "1.0.49", features = ["diff"] } [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/LICENSE-APACHE b/LICENSE-APACHE index 16fe87b..1b5ec8b 100644 --- a/LICENSE-APACHE +++ b/LICENSE-APACHE @@ -174,28 +174,3 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. @@ -1,3 +1,7 @@ +# This project was upgraded with external_updater. +# Usage: tools/external_updater/updater.sh update rust/crates/rustversion +# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md + name: "rustversion" description: "Conditional compilation according to rustc compiler version" third_party { @@ -7,13 +11,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/rustversion/rustversion-1.0.5.crate" + value: "https://static.crates.io/crates/rustversion/rustversion-1.0.12.crate" } - version: "1.0.5" + version: "1.0.12" license_type: NOTICE last_upgrade_date { - year: 2021 - month: 5 - day: 25 + year: 2023 + month: 4 + day: 3 } } @@ -3,8 +3,8 @@ Compiler version cfg [<img alt="github" src="https://img.shields.io/badge/github-dtolnay/rustversion-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/rustversion) [<img alt="crates.io" src="https://img.shields.io/crates/v/rustversion.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/rustversion) -[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-rustversion-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/rustversion) -[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/rustversion/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/rustversion/actions?query=branch%3Amaster) +[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-rustversion-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/rustversion) +[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/dtolnay/rustversion/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/dtolnay/rustversion/actions?query=branch%3Amaster) This crate provides macros for conditional compilation according to rustc compiler version, analogous to [`#[cfg(...)]`][cfg] and diff --git a/TEST_MAPPING b/TEST_MAPPING index 684ef48..ed43c73 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -2,10 +2,19 @@ { "imports": [ { + "path": "external/rust/crates/async-stream" + }, + { "path": "external/rust/crates/bitflags" }, { + "path": "external/rust/crates/crossbeam-epoch" + }, + { "path": "external/rust/crates/crossbeam-utils" + }, + { + "path": "external/rust/crates/slab" } ] } diff --git a/build/build.rs b/build/build.rs index 1531251..0a45f4c 100644 --- a/build/build.rs +++ b/build/build.rs @@ -13,41 +13,63 @@ use std::path::Path; use std::process::{self, Command}; fn main() { + println!("cargo:rerun-if-changed=build/build.rs"); + let rustc = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc")); - let output = match Command::new(&rustc).arg("--version").output() { - Ok(output) => output, - Err(e) => { - let rustc = rustc.to_string_lossy(); - eprintln!("Error: failed to run `{} --version`: {}", rustc, e); - process::exit(1); - } - }; - let string = match String::from_utf8(output.stdout) { - Ok(string) => string, - Err(e) => { - let rustc = rustc.to_string_lossy(); - eprintln!( - "Error: failed to parse output of `{} --version`: {}", - rustc, e, - ); - process::exit(1); + let mut is_clippy_driver = false; + let version = loop { + let mut command = Command::new(&rustc); + if is_clippy_driver { + command.arg("--rustc"); } - }; + command.arg("--version"); - let version = match rustc::parse(&string) { - Some(version) => format!("{:#?}\n", version), - None => { - eprintln!( - "Error: unexpected output from `rustc --version`: {:?}\n\n\ - Please file an issue in https://github.com/dtolnay/rustversion", - string - ); - process::exit(1); - } + let output = match command.output() { + Ok(output) => output, + Err(e) => { + let rustc = rustc.to_string_lossy(); + eprintln!("Error: failed to run `{} --version`: {}", rustc, e); + process::exit(1); + } + }; + + let string = match String::from_utf8(output.stdout) { + Ok(string) => string, + Err(e) => { + let rustc = rustc.to_string_lossy(); + eprintln!( + "Error: failed to parse output of `{} --version`: {}", + rustc, e, + ); + process::exit(1); + } + }; + + break match rustc::parse(&string) { + rustc::ParseResult::Success(version) => version, + rustc::ParseResult::OopsClippy if !is_clippy_driver => { + is_clippy_driver = true; + continue; + } + rustc::ParseResult::Unrecognized | rustc::ParseResult::OopsClippy => { + eprintln!( + "Error: unexpected output from `rustc --version`: {:?}\n\n\ + Please file an issue in https://github.com/dtolnay/rustversion", + string + ); + process::exit(1); + } + }; }; + if version.minor < 38 { + // Prior to 1.38, a #[proc_macro] is not allowed to be named `cfg`. + println!("cargo:rustc-cfg=cfg_macro_not_allowed"); + } + + let version = format!("{:#?}\n", version); let out_dir = env::var_os("OUT_DIR").expect("OUT_DIR not set"); - let out_file = Path::new(&out_dir).join("version.rs"); - fs::write(out_file, version).expect("failed to write version.rs"); + let out_file = Path::new(&out_dir).join("version.expr"); + fs::write(out_file, version).expect("failed to write version.expr"); } diff --git a/build/rustc.rs b/build/rustc.rs index dfc6a05..71a830b 100644 --- a/build/rustc.rs +++ b/build/rustc.rs @@ -1,6 +1,12 @@ use self::Channel::*; use std::fmt::{self, Debug}; +pub enum ParseResult { + Success(Version), + OopsClippy, + Unrecognized, +} + #[cfg_attr(test, derive(PartialEq))] pub struct Version { pub minor: u16, @@ -23,14 +29,20 @@ pub struct Date { pub day: u8, } -pub fn parse(string: &str) -> Option<Version> { - let last_line = string.lines().last().unwrap_or(&string); +pub fn parse(string: &str) -> ParseResult { + let last_line = string.lines().last().unwrap_or(string); let mut words = last_line.trim().split(' '); - if words.next()? != "rustc" { - return None; + match words.next() { + Some("rustc") => {} + Some(word) if word.starts_with("clippy") => return ParseResult::OopsClippy, + Some(_) | None => return ParseResult::Unrecognized, } + parse_words(&mut words).map_or(ParseResult::Unrecognized, ParseResult::Success) +} + +fn parse_words(words: &mut dyn Iterator<Item = &str>) -> Option<Version> { let mut version_channel = words.next()?.split('-'); let version = version_channel.next()?; let channel = version_channel.next(); diff --git a/patches/version.diff b/patches/version.diff index cd19b04..3eb570b 100644 --- a/patches/version.diff +++ b/patches/version.diff @@ -1,12 +1,12 @@ diff --git a/src/lib.rs b/src/lib.rs -index 172eb89..6c4ef6a 100644 +index 2e8f1b9..e826b25 100644 --- a/src/lib.rs +++ b/src/lib.rs -@@ -180,7 +180,16 @@ use crate::version::Version; - use proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree}; - use std::iter::FromIterator; +@@ -182,7 +182,16 @@ use crate::error::Error; + use crate::version::Version; + use proc_macro::TokenStream; --const RUSTVERSION: Version = include!(concat!(env!("OUT_DIR"), "/version.rs")); +-const RUSTVERSION: Version = include!(concat!(env!("OUT_DIR"), "/version.expr")); +// ANDROID: Soong is providing the version of rustc via an env variable. +const ANDROID_RUSTVERSION: Option<&str> = option_env!("ANDROID_RUST_VERSION"); +fn rust_version() -> Version { @@ -20,21 +20,34 @@ index 172eb89..6c4ef6a 100644 #[proc_macro_attribute] pub fn stable(args: TokenStream, input: TokenStream) -> TokenStream { -@@ -241,7 +250,7 @@ fn try_cfg(introducer: &str, args: TokenStream, input: TokenStream) -> Result<To +@@ -239,7 +248,7 @@ pub fn cfg(input: TokenStream) -> TokenStream { + let ref mut args = iter::new(input); + let expr = expr::parse(args)?; + token::parse_end(args)?; +- let boolean = expr.eval(RUSTVERSION); ++ let boolean = expr.eval(rust_version()); + let ident = Ident::new(&boolean.to_string(), Span::call_site()); + Ok(TokenStream::from(TokenTree::Ident(ident))) + })() +diff --git a/src/expand.rs b/src/expand.rs +index 813ba85..3d4e314 100644 +--- a/src/expand.rs ++++ b/src/expand.rs +@@ -23,7 +23,7 @@ fn try_cfg(introducer: &str, args: TokenStream, input: TokenStream) -> Result<To let expr = expr::parse(full_args)?; token::parse_end(full_args)?; -- if expr.eval(RUSTVERSION) { -+ if expr.eval(rust_version()) { +- if expr.eval(crate::RUSTVERSION) { ++ if expr.eval(crate::rust_version()) { Ok(input) } else { Ok(TokenStream::new()) -@@ -256,7 +265,7 @@ pub fn attr(args: TokenStream, input: TokenStream) -> TokenStream { +@@ -31,7 +31,7 @@ fn try_cfg(introducer: &str, args: TokenStream, input: TokenStream) -> Result<To } - fn try_attr(args: attr::Args, input: TokenStream) -> Result<TokenStream> { -- if !args.condition.eval(RUSTVERSION) { -+ if !args.condition.eval(rust_version()) { + pub fn try_attr(args: attr::Args, input: TokenStream) -> Result<TokenStream> { +- if !args.condition.eval(crate::RUSTVERSION) { ++ if !args.condition.eval(crate::rust_version()) { return Ok(input); } diff --git a/src/expand.rs b/src/expand.rs new file mode 100644 index 0000000..3d4e314 --- /dev/null +++ b/src/expand.rs @@ -0,0 +1,72 @@ +use crate::attr::{self, Then}; +use crate::error::{Error, Result}; +use crate::{constfn, expr, iter, token}; +use proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree}; +use std::iter::FromIterator; + +pub fn cfg(introducer: &str, args: TokenStream, input: TokenStream) -> TokenStream { + try_cfg(introducer, args, input).unwrap_or_else(Error::into_compile_error) +} + +fn try_cfg(introducer: &str, args: TokenStream, input: TokenStream) -> Result<TokenStream> { + let introducer = Ident::new(introducer, Span::call_site()); + + let mut full_args = TokenStream::from(TokenTree::Ident(introducer)); + if !args.is_empty() { + full_args.extend(std::iter::once(TokenTree::Group(Group::new( + Delimiter::Parenthesis, + args, + )))); + } + + let ref mut full_args = iter::new(full_args); + let expr = expr::parse(full_args)?; + token::parse_end(full_args)?; + + if expr.eval(crate::rust_version()) { + Ok(input) + } else { + Ok(TokenStream::new()) + } +} + +pub fn try_attr(args: attr::Args, input: TokenStream) -> Result<TokenStream> { + if !args.condition.eval(crate::rust_version()) { + return Ok(input); + } + + match args.then { + Then::Const(const_token) => constfn::insert_const(input, const_token), + Then::Attribute(then) => { + // #[cfg_attr(all(), #then)] + Ok(TokenStream::from_iter( + vec![ + TokenTree::Punct(Punct::new('#', Spacing::Alone)), + TokenTree::Group(Group::new( + Delimiter::Bracket, + TokenStream::from_iter(vec![ + TokenTree::Ident(Ident::new("cfg_attr", Span::call_site())), + TokenTree::Group(Group::new( + Delimiter::Parenthesis, + TokenStream::from_iter( + vec![ + TokenTree::Ident(Ident::new("all", Span::call_site())), + TokenTree::Group(Group::new( + Delimiter::Parenthesis, + TokenStream::new(), + )), + TokenTree::Punct(Punct::new(',', Spacing::Alone)), + ] + .into_iter() + .chain(then), + ), + )), + ]), + )), + ] + .into_iter() + .chain(input), + )) + } + } +} @@ -2,7 +2,7 @@ //! //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust -//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K +//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs //! //! <br> //! @@ -145,12 +145,16 @@ //! //! <br> +#![doc(html_root_url = "https://docs.rs/rustversion/1.0.12")] #![allow( clippy::cast_lossless, clippy::cast_possible_truncation, + clippy::derive_partial_eq_without_eq, clippy::doc_markdown, clippy::enum_glob_use, clippy::from_iter_instead_of_collect, + // https://github.com/rust-lang/rust-clippy/issues/8539 + clippy::iter_with_drain, clippy::module_name_repetitions, clippy::must_use_candidate, clippy::needless_doctest_main, @@ -167,6 +171,7 @@ mod bound; mod constfn; mod date; mod error; +mod expand; mod expr; mod iter; mod release; @@ -174,11 +179,9 @@ mod time; mod token; mod version; -use crate::attr::Then; -use crate::error::{Error, Result}; +use crate::error::Error; use crate::version::Version; -use proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree}; -use std::iter::FromIterator; +use proc_macro::TokenStream; // ANDROID: Soong is providing the version of rustc via an env variable. const ANDROID_RUSTVERSION: Option<&str> = option_env!("ANDROID_RUST_VERSION"); @@ -193,114 +196,62 @@ fn rust_version() -> Version { #[proc_macro_attribute] pub fn stable(args: TokenStream, input: TokenStream) -> TokenStream { - cfg("stable", args, input) + expand::cfg("stable", args, input) } #[proc_macro_attribute] pub fn beta(args: TokenStream, input: TokenStream) -> TokenStream { - cfg("beta", args, input) + expand::cfg("beta", args, input) } #[proc_macro_attribute] pub fn nightly(args: TokenStream, input: TokenStream) -> TokenStream { - cfg("nightly", args, input) + expand::cfg("nightly", args, input) } #[proc_macro_attribute] pub fn since(args: TokenStream, input: TokenStream) -> TokenStream { - cfg("since", args, input) + expand::cfg("since", args, input) } #[proc_macro_attribute] pub fn before(args: TokenStream, input: TokenStream) -> TokenStream { - cfg("before", args, input) + expand::cfg("before", args, input) } #[proc_macro_attribute] pub fn not(args: TokenStream, input: TokenStream) -> TokenStream { - cfg("not", args, input) + expand::cfg("not", args, input) } #[proc_macro_attribute] pub fn any(args: TokenStream, input: TokenStream) -> TokenStream { - cfg("any", args, input) + expand::cfg("any", args, input) } #[proc_macro_attribute] pub fn all(args: TokenStream, input: TokenStream) -> TokenStream { - cfg("all", args, input) -} - -fn cfg(introducer: &str, args: TokenStream, input: TokenStream) -> TokenStream { - try_cfg(introducer, args, input).unwrap_or_else(Error::into_compile_error) -} - -fn try_cfg(introducer: &str, args: TokenStream, input: TokenStream) -> Result<TokenStream> { - let introducer = Ident::new(introducer, Span::call_site()); - - let mut full_args = TokenStream::from(TokenTree::Ident(introducer)); - if !args.is_empty() { - full_args.extend(std::iter::once(TokenTree::Group(Group::new( - Delimiter::Parenthesis, - args, - )))); - } - - let ref mut full_args = iter::new(full_args); - let expr = expr::parse(full_args)?; - token::parse_end(full_args)?; - - if expr.eval(rust_version()) { - Ok(input) - } else { - Ok(TokenStream::new()) - } + expand::cfg("all", args, input) } #[proc_macro_attribute] pub fn attr(args: TokenStream, input: TokenStream) -> TokenStream { attr::parse(args) - .and_then(|args| try_attr(args, input)) + .and_then(|args| expand::try_attr(args, input)) .unwrap_or_else(Error::into_compile_error) } -fn try_attr(args: attr::Args, input: TokenStream) -> Result<TokenStream> { - if !args.condition.eval(rust_version()) { - return Ok(input); - } - - match args.then { - Then::Const(const_token) => constfn::insert_const(input, const_token), - Then::Attribute(then) => { - // #[cfg_attr(all(), #then)] - Ok(TokenStream::from_iter( - vec![ - TokenTree::Punct(Punct::new('#', Spacing::Alone)), - TokenTree::Group(Group::new( - Delimiter::Bracket, - TokenStream::from_iter(vec![ - TokenTree::Ident(Ident::new("cfg_attr", Span::call_site())), - TokenTree::Group(Group::new( - Delimiter::Parenthesis, - TokenStream::from_iter( - vec![ - TokenTree::Ident(Ident::new("all", Span::call_site())), - TokenTree::Group(Group::new( - Delimiter::Parenthesis, - TokenStream::new(), - )), - TokenTree::Punct(Punct::new(',', Spacing::Alone)), - ] - .into_iter() - .chain(then), - ), - )), - ]), - )), - ] - .into_iter() - .chain(input), - )) - } - } +#[cfg(not(cfg_macro_not_allowed))] +#[proc_macro] +pub fn cfg(input: TokenStream) -> TokenStream { + use proc_macro::{Ident, Span, TokenTree}; + (|| { + let ref mut args = iter::new(input); + let expr = expr::parse(args)?; + token::parse_end(args)?; + let boolean = expr.eval(rust_version()); + let ident = Ident::new(&boolean.to_string(), Span::call_site()); + Ok(TokenStream::from(TokenTree::Ident(ident))) + })() + .unwrap_or_else(Error::into_compile_error) } diff --git a/tests/compiletest.rs b/tests/compiletest.rs index f9aea23..7974a62 100644 --- a/tests/compiletest.rs +++ b/tests/compiletest.rs @@ -1,4 +1,5 @@ #[rustversion::attr(not(nightly), ignore)] +#[cfg_attr(miri, ignore)] #[test] fn ui() { let t = trybuild::TestCases::new(); diff --git a/tests/test_const.rs b/tests/test_const.rs index 1765c95..3c4f7d5 100644 --- a/tests/test_const.rs +++ b/tests/test_const.rs @@ -1,3 +1,5 @@ +#![allow(clippy::semicolon_if_nothing_returned)] // https://github.com/rust-lang/rust-clippy/issues/7324 + #[rustversion::attr(all(), const)] fn _basic() {} const _BASIC: () = _basic(); diff --git a/tests/test_parse.rs b/tests/test_parse.rs index cb39b31..95064ee 100644 --- a/tests/test_parse.rs +++ b/tests/test_parse.rs @@ -1,4 +1,8 @@ -#![allow(clippy::enum_glob_use, clippy::must_use_candidate)] +#![allow( + clippy::derive_partial_eq_without_eq, + clippy::enum_glob_use, + clippy::must_use_candidate +)] include!("../build/rustc.rs"); @@ -89,6 +93,11 @@ fn test_parse() { ]; for (string, expected) in cases { - assert_eq!(parse(string).unwrap(), *expected); + match parse(string) { + ParseResult::Success(version) => assert_eq!(version, *expected), + ParseResult::OopsClippy | ParseResult::Unrecognized => { + panic!("unrecognized: {:?}", string); + } + } } } diff --git a/tests/ui/bad-bound.stderr b/tests/ui/bad-bound.stderr index 2c56acb..77956c6 100644 --- a/tests/ui/bad-bound.stderr +++ b/tests/ui/bad-bound.stderr @@ -1,11 +1,11 @@ error: expected rustc release number like 1.31, or nightly date like 2020-02-25 - --> $DIR/bad-bound.rs:1:22 + --> tests/ui/bad-bound.rs:1:22 | 1 | #[rustversion::since(stable)] | ^^^^^^ error: expected rustc release number like 1.31, or nightly date like 2020-02-25 - --> $DIR/bad-bound.rs:4:26 + --> tests/ui/bad-bound.rs:4:26 | 4 | #[rustversion::any(since(stable))] | ^^^^^^ diff --git a/tests/ui/bad-date.stderr b/tests/ui/bad-date.stderr index c523ccc..378b00e 100644 --- a/tests/ui/bad-date.stderr +++ b/tests/ui/bad-date.stderr @@ -1,11 +1,11 @@ error: expected nightly date, like 2020-02-25 - --> $DIR/bad-date.rs:1:24 + --> tests/ui/bad-date.rs:1:24 | 1 | #[rustversion::nightly(stable)] | ^^^^^^ error: expected nightly date, like 2020-02-25 - --> $DIR/bad-date.rs:4:28 + --> tests/ui/bad-date.rs:4:28 | 4 | #[rustversion::any(nightly(stable))] | ^^^^^^ diff --git a/tests/ui/bad-not.stderr b/tests/ui/bad-not.stderr index bfe239b..2b0c699 100644 --- a/tests/ui/bad-not.stderr +++ b/tests/ui/bad-not.stderr @@ -1,11 +1,11 @@ error: expected `(` after `not` - --> $DIR/bad-not.rs:1:20 + --> tests/ui/bad-not.rs:1:20 | 1 | #[rustversion::any(not)] | ^^^ error: expected `(` - --> $DIR/bad-not.rs:4:23 + --> tests/ui/bad-not.rs:4:23 | 4 | #[rustversion::any(not, not)] | ^ diff --git a/tests/ui/bad-version.stderr b/tests/ui/bad-version.stderr index 5f7a01f..bf3f144 100644 --- a/tests/ui/bad-version.stderr +++ b/tests/ui/bad-version.stderr @@ -1,11 +1,11 @@ error: expected rustc release number, like 1.31 - --> $DIR/bad-version.rs:1:23 + --> tests/ui/bad-version.rs:1:23 | 1 | #[rustversion::stable(nightly)] | ^^^^^^^ error: expected rustc release number, like 1.31 - --> $DIR/bad-version.rs:4:27 + --> tests/ui/bad-version.rs:4:27 | 4 | #[rustversion::any(stable(nightly))] | ^^^^^^^ diff --git a/tests/ui/const-not-fn.stderr b/tests/ui/const-not-fn.stderr index 7371ff2..d3cb4aa 100644 --- a/tests/ui/const-not-fn.stderr +++ b/tests/ui/const-not-fn.stderr @@ -1,5 +1,5 @@ error: only allowed on a fn item - --> $DIR/const-not-fn.rs:1:28 + --> tests/ui/const-not-fn.rs:1:28 | 1 | #[rustversion::attr(all(), const)] | ^^^^^ |