diff --git a/Cargo.lock b/Cargo.lock index 490161626c..5750be2086 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,7 +73,7 @@ version = "0.1.0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.9", ] [[package]] @@ -145,7 +145,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -213,7 +213,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 2.0.117", ] [[package]] @@ -224,7 +224,7 @@ checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -520,7 +520,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.117", ] [[package]] @@ -745,7 +745,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -780,7 +780,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -807,7 +807,7 @@ version = "0.1.0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.9", ] [[package]] @@ -881,7 +881,7 @@ dependencies = [ "quote", "serde", "serde_json", - "syn", + "syn 3.0.9", ] [[package]] @@ -910,6 +910,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syscalls" version = "0.6.18" @@ -1094,7 +1105,7 @@ dependencies = [ "heck", "indexmap 2.13.1", "prettyplease", - "syn", + "syn 2.0.117", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -1110,7 +1121,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -1178,7 +1189,7 @@ checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] diff --git a/crates/assert-instr-macro/Cargo.toml b/crates/assert-instr-macro/Cargo.toml index 77ee571ccb..a71dd0f69a 100644 --- a/crates/assert-instr-macro/Cargo.toml +++ b/crates/assert-instr-macro/Cargo.toml @@ -11,7 +11,7 @@ test = false [dependencies] proc-macro2 = "1.0" quote = "1.0" -syn = { version = "2.0", features = ["full"] } +syn = { version = "3.0", features = ["full"] } [lints.rust] unexpected_cfgs = {level = "warn", check-cfg = ['cfg(optimized)'] } diff --git a/crates/assert-instr-macro/src/lib.rs b/crates/assert-instr-macro/src/lib.rs index 839aae67cb..3c53e92c71 100644 --- a/crates/assert-instr-macro/src/lib.rs +++ b/crates/assert-instr-macro/src/lib.rs @@ -107,6 +107,7 @@ pub fn assert_instr( let generic_ty_value = syn::TypePath { qself: qself.clone(), path: path.clone(), + attrs: Vec::new(), }; // Replace any function arguments that use generic parameters with the diff --git a/crates/simd-test-macro/Cargo.toml b/crates/simd-test-macro/Cargo.toml index 8f9f9b1327..717acb03b2 100644 --- a/crates/simd-test-macro/Cargo.toml +++ b/crates/simd-test-macro/Cargo.toml @@ -11,4 +11,4 @@ test = false [dependencies] proc-macro2 = "1.0" quote = "1.0" -syn = { version = "2.0", features = ["full"] } +syn = { version = "3.0", features = ["full"] } diff --git a/crates/simd-test-macro/src/lib.rs b/crates/simd-test-macro/src/lib.rs index 51dd8aaf46..ee11fb5c06 100644 --- a/crates/simd-test-macro/src/lib.rs +++ b/crates/simd-test-macro/src/lib.rs @@ -2,13 +2,9 @@ //! //! This macro expands to a `#[test]` function which tests the local machine //! for the appropriate cfg before calling the inner test function. -#![deny(rust_2018_idioms)] -#[macro_use] -extern crate quote; - -use proc_macro2::{Ident, Span, TokenStream, TokenTree}; -use quote::ToTokens; +use proc_macro2::{Span, TokenStream, TokenTree}; +use quote::{ToTokens, quote, quote_spanned}; use std::env; #[proc_macro_attribute] @@ -18,14 +14,6 @@ pub fn simd_test( ) -> proc_macro::TokenStream { let tokens = TokenStream::from(attr).into_iter().collect::>(); - let target = env::var("TARGET").expect( - "TARGET environment variable should be set for rustc (e.g. TARGET=x86_64-apple-darwin cargo test)" - ); - let target_arch = target - .split('-') - .next() - .unwrap_or_else(|| panic!("target triple contained no \"-\": {target}")); - let (target_features, target_feature_attr) = match &tokens[..] { [] => (Vec::new(), TokenStream::new()), [ @@ -33,25 +21,25 @@ pub fn simd_test( TokenTree::Punct(equals), TokenTree::Literal(literal), ] if enable == "enable" && equals.as_char() == '=' => { - let mut enable_feature = literal - .to_string() - .trim_start_matches('"') - .trim_end_matches('"') - .to_string(); + let lit = literal.to_string(); + let enable_feature = lit.trim_start_matches('"').trim_end_matches('"'); let target_features: Vec<_> = enable_feature .replace('+', "") .split(',') .map(String::from) .collect(); + let mut enable_feature_arm = enable_feature.to_string(); + // Allows using `#[simd_test(enable = "neon")]` on aarch64/armv7 shared tests. - if target_arch == "armv7" && target_features.iter().any(|feat| feat == "neon") { - enable_feature.push_str(",v7"); + if target_features.iter().any(|feat| feat == "neon") { + enable_feature_arm.push_str(",v7"); } ( target_features, quote! { - #[target_feature(enable = #enable_feature)] + #[cfg_attr(target_arch = "arm", target_feature(enable = #enable_feature_arm))] + #[cfg_attr(not(target_arch = "arm"), target_feature(enable = #enable_feature))] }, ) } @@ -62,83 +50,105 @@ pub fn simd_test( let item_attrs = std::mem::take(&mut item.attrs); let name = &item.sig.ident; - let macro_test = match target_arch { - "i686" | "x86_64" | "i586" => "is_x86_feature_detected", - "arm" | "armv7" | "thumbv7neon" => "is_arm_feature_detected", - "aarch64" | "arm64ec" | "aarch64_be" => "is_aarch64_feature_detected", - maybe_riscv if maybe_riscv.starts_with("riscv") => "is_riscv_feature_detected", - "powerpc" | "powerpcle" | "powerpc64" | "powerpc64le" => "is_powerpc_feature_detected", - "loongarch32" | "loongarch64" => "is_loongarch_feature_detected", - "s390x" => "is_s390x_feature_detected", - "mips64" | "mips64el" => "is_mips64_feature_detected", - t => panic!("unknown target: {t}"), - }; - let macro_test = Ident::new(macro_test, Span::call_site()); - - let skipped_functions = env::var("STDARCH_TEST_SKIP_FUNCTION").unwrap_or_default(); - let skipped_features = env::var("STDARCH_TEST_SKIP_FEATURE").unwrap_or_default(); - let mut name_str = &*name.to_string(); if name_str.starts_with("test_") { name_str = &name_str[5..]; } - let skip_this = skipped_functions + let skipped_functions = env::var("STDARCH_TEST_SKIP_FUNCTION").unwrap_or_default(); + let skipped_features = env::var("STDARCH_TEST_SKIP_FEATURE").unwrap_or_default(); + let skipped_function = skipped_functions + .split(',') + .map(str::trim) + .any(|s| s == name_str); + let skipped_feature = skipped_features .split(',') .map(str::trim) - .any(|s| s == name_str) - || skipped_features - .split(',') - .map(str::trim) - .any(|s| target_features.iter().any(|feature| s == feature)); + .any(|s| target_features.iter().any(|feature| s == feature)); let mut detect_missing_features = TokenStream::new(); for feature in target_features { - let q = if target_arch == "armv7" && feature == "fp16" { - // "fp16" cannot be checked at runtime - quote_spanned! { - proc_macro2::Span::call_site() => - if !cfg!(target_feature = #feature) { - missing_features.push(#feature); - } + let mut q = quote_spanned! { Span::call_site() => + // Default target feature check + if !test_macro!(#feature) { + missing_features.push(#feature); } - } else { - quote_spanned! { - proc_macro2::Span::call_site() => - if !::std::arch::#macro_test!(#feature) { - missing_features.push(#feature); + }; + + // For features that cannot be checked at runtime (currently fp16 on arm32), use the + // static check instead. + if feature == "fp16" { + q = quote_spanned! { Span::call_site() => + cfg_select! { + target_arch = "arm" => { + if !cfg!(target_feature = #feature) { + missing_features.push(#feature); + } + } + _ => { + #q + } } } - }; + } + q.to_tokens(&mut detect_missing_features); } - let maybe_ignore = if skip_this { - quote! { #[ignore] } - } else { - TokenStream::new() - }; + let mut maybe_ignore = TokenStream::new(); + let mut const_test = TokenStream::new(); + let mut const_stability = TokenStream::new(); - let (const_test, const_stability) = if item.sig.constness.is_some() { - ( - quote! { - const _: () = unsafe { #name() }; - }, - quote! { - #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] - }, - ) - } else { - (TokenStream::new(), TokenStream::new()) - }; + if skipped_function || skipped_feature { + maybe_ignore = quote! { #[ignore] } + } - let ret: TokenStream = quote_spanned! { - proc_macro2::Span::call_site() => + if item.sig.constness.is_some() { + const_test = quote! { + const _: () = unsafe { #name() }; + }; + const_stability = quote! { + #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")] + }; + } + + let ret: TokenStream = quote_spanned! { Span::call_site() => #[allow(non_snake_case)] #[test] #maybe_ignore #(#item_attrs)* fn #name() { + cfg_select! { + any(target_arch = "x86", target_arch = "x86_64") => { + use std::arch::is_x86_feature_detected as test_macro; + } + target_arch = "arm" => { + use std::arch::is_arm_feature_detected as test_macro; + } + any(target_arch = "aarch64", target_arch = "arm64ec") => { + use std::arch::is_aarch64_feature_detected as test_macro; + } + any(target_arch = "riscv32", target_arch = "riscv64") => { + use std::arch::is_riscv_feature_detected as test_macro; + } + any(target_arch = "powerpc", target_arch = "powerpc64") => { + use std::arch::is_powerpc_feature_detected as test_macro; + } + any(target_arch = "loongarch32", target_arch = "loongarch64") => { + use std::arch::is_loongarch_feature_detected as test_macro; + } + target_arch = "s390x" => { + use std::arch::is_s390x_feature_detected as test_macro; + } + any(target_arch = "mips", target_arch = "mips32r6") => { + use std::arch::is_mips_feature_detected as test_macro; + } + any(target_arch = "mips64", target_arch = "mips64r6") => { + use std::arch::is_mips64_feature_detected as test_macro; + } + _ => compile_error!("unknown target; need to update simd-test-macro"), + } + #const_test let mut missing_features = ::std::vec::Vec::new(); diff --git a/crates/stdarch-verify/Cargo.toml b/crates/stdarch-verify/Cargo.toml index c82a1262d0..ca921fd8a3 100644 --- a/crates/stdarch-verify/Cargo.toml +++ b/crates/stdarch-verify/Cargo.toml @@ -7,7 +7,7 @@ edition = "2024" [dependencies] proc-macro2 = "1.0" quote = "1.0" -syn = { version = "2.0", features = ["full"] } +syn = { version = "3.0", features = ["full"] } [lib] proc-macro = true diff --git a/crates/stdarch-verify/src/lib.rs b/crates/stdarch-verify/src/lib.rs index c681eca1dd..9676dd7dbb 100644 --- a/crates/stdarch-verify/src/lib.rs +++ b/crates/stdarch-verify/src/lib.rs @@ -391,23 +391,32 @@ fn to_type(t: &syn::Type) -> proc_macro2::TokenStream { }, syn::Type::Ptr(syn::TypePtr { ref elem, - ref mutability, + mutability: syn::PointerMutability::Mut(_), .. }) | syn::Type::Reference(syn::TypeReference { ref elem, - ref mutability, + mutability: Some(_), .. }) => { - // Both pointers and references can have a mut token (*mut and &mut) - if mutability.is_some() { - let tokens = to_type(elem); - quote! { &Type::MutPtr(#tokens) } - } else { - // If they don't (*const or &) then they are "const" - let tokens = to_type(elem); - quote! { &Type::ConstPtr(#tokens) } - } + // // Both pointers and references can have a mut token (*mut and &mut) + let tokens = to_type(elem); + quote! { &Type::MutPtr(#tokens) } + } + + syn::Type::Ptr(syn::TypePtr { + ref elem, + mutability: syn::PointerMutability::Const(_), + .. + }) + | syn::Type::Reference(syn::TypeReference { + ref elem, + mutability: None, + .. + }) => { + // If they don't (*const or &) then they are "const" + let tokens = to_type(elem); + quote! { &Type::ConstPtr(#tokens) } } syn::Type::Slice(_) => panic!("unsupported slice"),