From 9918693037dce8aa4bb6f08741b6812923486c18 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 19 Jun 2024 11:26:03 +0200 Subject: Merging upstream version 1.76.0+dfsg1. Signed-off-by: Daniel Baumann --- .../ra-ap-rustc_index_macros/.cargo-checksum.json | 1 + vendor/ra-ap-rustc_index_macros/Cargo.toml | 45 +++ vendor/ra-ap-rustc_index_macros/src/lib.rs | 41 +++ vendor/ra-ap-rustc_index_macros/src/newtype.rs | 324 +++++++++++++++++++++ 4 files changed, 411 insertions(+) create mode 100644 vendor/ra-ap-rustc_index_macros/.cargo-checksum.json create mode 100644 vendor/ra-ap-rustc_index_macros/Cargo.toml create mode 100644 vendor/ra-ap-rustc_index_macros/src/lib.rs create mode 100644 vendor/ra-ap-rustc_index_macros/src/newtype.rs (limited to 'vendor/ra-ap-rustc_index_macros') diff --git a/vendor/ra-ap-rustc_index_macros/.cargo-checksum.json b/vendor/ra-ap-rustc_index_macros/.cargo-checksum.json new file mode 100644 index 000000000..bea9cd60f --- /dev/null +++ b/vendor/ra-ap-rustc_index_macros/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"635ee135a17f833063aabd22ed39922e25a359e98c1d6c17afb72b268c61226a","src/lib.rs":"b87e5622dda11ee7bccf4e33ed095e3f7677e01e0db83fbd225b2ddbe516f545","src/newtype.rs":"6046566edbde7470ea1ba53bbfad8348f8b6614fdbc2ed5df7c64d78341efb67"},"package":"66a9424018828155a3e3596515598f90e68427d8f35eff6df7f0856c73fc58a8"} \ No newline at end of file diff --git a/vendor/ra-ap-rustc_index_macros/Cargo.toml b/vendor/ra-ap-rustc_index_macros/Cargo.toml new file mode 100644 index 000000000..339526583 --- /dev/null +++ b/vendor/ra-ap-rustc_index_macros/Cargo.toml @@ -0,0 +1,45 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# 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. +# +# 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 = "2021" +name = "ra-ap-rustc_index_macros" +version = "0.21.0" +description = """ + +Automatically published version of the package `rustc_index_macros` +in the rust-lang/rust repository from commit f536185ed8fe11d45da662c8575f4253fede3986 + +The publishing script for this crate lives at: +https://github.com/rust-analyzer/rustc-auto-publish +""" +license = "MIT / Apache-2.0" +repository = "https://github.com/rust-lang/rust" + +[lib] +proc-macro = true + +[dependencies.proc-macro2] +version = "1" + +[dependencies.quote] +version = "1" + +[dependencies.syn] +version = "2.0.9" +features = ["full"] + +[dependencies.synstructure] +version = "0.13.0" + +[features] +default = ["nightly"] +nightly = [] diff --git a/vendor/ra-ap-rustc_index_macros/src/lib.rs b/vendor/ra-ap-rustc_index_macros/src/lib.rs new file mode 100644 index 000000000..ac374a41e --- /dev/null +++ b/vendor/ra-ap-rustc_index_macros/src/lib.rs @@ -0,0 +1,41 @@ +#![cfg_attr(feature = "nightly", feature(allow_internal_unstable))] +#![cfg_attr(feature = "nightly", allow(internal_features))] + +use proc_macro::TokenStream; + +mod newtype; + +/// Creates a struct type `S` that can be used as an index with +/// `IndexVec` and so on. +/// +/// There are two ways of interacting with these indices: +/// +/// - The `From` impls are the preferred way. So you can do +/// `S::from(v)` with a `usize` or `u32`. And you can convert back +/// to an integer with `u32::from(s)`. +/// +/// - Alternatively, you can use the methods `S::new(v)` and `s.index()` +/// to create/return a value. +/// +/// Internally, the index uses a u32, so the index must not exceed +/// `u32::MAX`. +/// +/// The impls provided by default are Clone, Copy, PartialEq, Eq, and Hash. +/// +/// Accepted attributes for customization: +/// - `#[derive(HashStable_Generic)]`/`#[derive(HashStable)]`: derives +/// `HashStable`, as normal. +/// - `#[encodable]`: derives `Encodable`/`Decodable`. +/// - `#[orderable]`: derives `PartialOrd`/`Ord`, plus step-related methods. +/// - `#[debug_format = "Foo({})"]`: derives `Debug` with particular output. +/// - `#[max = 0xFFFF_FFFD]`: specifies the max value, which allows niche +/// optimizations. The default max value is 0xFFFF_FF00. +/// - `#[gate_rustc_only]`: makes parts of the generated code nightly-only. +#[proc_macro] +#[cfg_attr( + feature = "nightly", + allow_internal_unstable(step_trait, rustc_attrs, trusted_step, spec_option_partial_eq) +)] +pub fn newtype_index(input: TokenStream) -> TokenStream { + newtype::newtype(input) +} diff --git a/vendor/ra-ap-rustc_index_macros/src/newtype.rs b/vendor/ra-ap-rustc_index_macros/src/newtype.rs new file mode 100644 index 000000000..df1318c83 --- /dev/null +++ b/vendor/ra-ap-rustc_index_macros/src/newtype.rs @@ -0,0 +1,324 @@ +use proc_macro2::{Span, TokenStream}; +use quote::quote; +use syn::parse::*; +use syn::*; + +// We parse the input and emit the output in a single step. +// This field stores the final macro output +struct Newtype(TokenStream); + +impl Parse for Newtype { + fn parse(input: ParseStream<'_>) -> Result { + let mut attrs = input.call(Attribute::parse_outer)?; + let vis: Visibility = input.parse()?; + input.parse::()?; + let name: Ident = input.parse()?; + + let body; + braced!(body in input); + + // Any additional `#[derive]` macro paths to apply + let mut derive_paths: Vec = Vec::new(); + let mut debug_format: Option = None; + let mut max = None; + let mut consts = Vec::new(); + let mut encodable = false; + let mut ord = false; + let mut gate_rustc_only = quote! {}; + let mut gate_rustc_only_cfg = quote! { all() }; + + attrs.retain(|attr| match attr.path().get_ident() { + Some(ident) => match &*ident.to_string() { + "gate_rustc_only" => { + gate_rustc_only = quote! { #[cfg(feature = "nightly")] }; + gate_rustc_only_cfg = quote! { feature = "nightly" }; + false + } + "encodable" => { + encodable = true; + false + } + "orderable" => { + ord = true; + false + } + "max" => { + let Meta::NameValue(MetaNameValue { value: Expr::Lit(lit), .. }) = &attr.meta + else { + panic!("#[max = NUMBER] attribute requires max value"); + }; + + if let Some(old) = max.replace(lit.lit.clone()) { + panic!("Specified multiple max: {old:?}"); + } + + false + } + "debug_format" => { + let Meta::NameValue(MetaNameValue { value: Expr::Lit(lit), .. }) = &attr.meta + else { + panic!("#[debug_format = FMT] attribute requires a format"); + }; + + if let Some(old) = debug_format.replace(lit.lit.clone()) { + panic!("Specified multiple debug format options: {old:?}"); + } + + false + } + _ => true, + }, + _ => true, + }); + + loop { + // We've parsed everything that the user provided, so we're done + if body.is_empty() { + break; + } + + // Otherwise, we are parsing a user-defined constant + let const_attrs = body.call(Attribute::parse_outer)?; + body.parse::()?; + let const_name: Ident = body.parse()?; + body.parse::()?; + let const_val: Expr = body.parse()?; + body.parse::()?; + consts.push(quote! { #(#const_attrs)* #vis const #const_name: #name = #name::from_u32(#const_val); }); + } + + let debug_format = + debug_format.unwrap_or_else(|| Lit::Str(LitStr::new("{}", Span::call_site()))); + + // shave off 256 indices at the end to allow space for packing these indices into enums + let max = max.unwrap_or_else(|| Lit::Int(LitInt::new("0xFFFF_FF00", Span::call_site()))); + + let encodable_impls = if encodable { + quote! { + #gate_rustc_only + impl ::rustc_serialize::Decodable for #name { + fn decode(d: &mut D) -> Self { + Self::from_u32(d.read_u32()) + } + } + #gate_rustc_only + impl ::rustc_serialize::Encodable for #name { + fn encode(&self, e: &mut E) { + e.emit_u32(self.private); + } + } + } + } else { + quote! {} + }; + + if ord { + derive_paths.push(parse_quote!(Ord)); + derive_paths.push(parse_quote!(PartialOrd)); + } + + let step = if ord { + quote! { + #gate_rustc_only + impl ::std::iter::Step for #name { + #[inline] + fn steps_between(start: &Self, end: &Self) -> Option { + ::steps_between( + &Self::index(*start), + &Self::index(*end), + ) + } + + #[inline] + fn forward_checked(start: Self, u: usize) -> Option { + Self::index(start).checked_add(u).map(Self::from_usize) + } + + #[inline] + fn backward_checked(start: Self, u: usize) -> Option { + Self::index(start).checked_sub(u).map(Self::from_usize) + } + } + + // Safety: The implementation of `Step` upholds all invariants. + #gate_rustc_only + unsafe impl ::std::iter::TrustedStep for #name {} + } + } else { + quote! {} + }; + + let debug_impl = quote! { + impl ::std::fmt::Debug for #name { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(fmt, #debug_format, self.as_u32()) + } + } + }; + + let spec_partial_eq_impl = if let Lit::Int(max) = &max { + if let Ok(max_val) = max.base10_parse::() { + quote! { + #gate_rustc_only + impl core::option::SpecOptionPartialEq for #name { + #[inline] + fn eq(l: &Option, r: &Option) -> bool { + if #max_val < u32::MAX { + l.map(|i| i.private).unwrap_or(#max_val+1) == r.map(|i| i.private).unwrap_or(#max_val+1) + } else { + match (l, r) { + (Some(l), Some(r)) => r == l, + (None, None) => true, + _ => false + } + } + } + } + } + } else { + quote! {} + } + } else { + quote! {} + }; + + Ok(Self(quote! { + #(#attrs)* + #[derive(Clone, Copy, PartialEq, Eq, Hash, #(#derive_paths),*)] + #[cfg_attr(#gate_rustc_only_cfg, rustc_layout_scalar_valid_range_end(#max))] + #[cfg_attr(#gate_rustc_only_cfg, rustc_pass_by_value)] + #vis struct #name { + private: u32, + } + + #(#consts)* + + impl #name { + /// Maximum value the index can take, as a `u32`. + #vis const MAX_AS_U32: u32 = #max; + + /// Maximum value the index can take. + #vis const MAX: Self = Self::from_u32(#max); + + /// Creates a new index from a given `usize`. + /// + /// # Panics + /// + /// Will panic if `value` exceeds `MAX`. + #[inline] + #vis const fn from_usize(value: usize) -> Self { + assert!(value <= (#max as usize)); + // SAFETY: We just checked that `value <= max`. + unsafe { + Self::from_u32_unchecked(value as u32) + } + } + + /// Creates a new index from a given `u32`. + /// + /// # Panics + /// + /// Will panic if `value` exceeds `MAX`. + #[inline] + #vis const fn from_u32(value: u32) -> Self { + assert!(value <= #max); + // SAFETY: We just checked that `value <= max`. + unsafe { + Self::from_u32_unchecked(value) + } + } + + /// Creates a new index from a given `u32`. + /// + /// # Safety + /// + /// The provided value must be less than or equal to the maximum value for the newtype. + /// Providing a value outside this range is undefined due to layout restrictions. + /// + /// Prefer using `from_u32`. + #[inline] + #vis const unsafe fn from_u32_unchecked(value: u32) -> Self { + Self { private: value } + } + + /// Extracts the value of this index as a `usize`. + #[inline] + #vis const fn index(self) -> usize { + self.as_usize() + } + + /// Extracts the value of this index as a `u32`. + #[inline] + #vis const fn as_u32(self) -> u32 { + self.private + } + + /// Extracts the value of this index as a `usize`. + #[inline] + #vis const fn as_usize(self) -> usize { + self.as_u32() as usize + } + } + + impl std::ops::Add for #name { + type Output = Self; + + fn add(self, other: usize) -> Self { + Self::from_usize(self.index() + other) + } + } + + impl rustc_index::Idx for #name { + #[inline] + fn new(value: usize) -> Self { + Self::from_usize(value) + } + + #[inline] + fn index(self) -> usize { + self.as_usize() + } + } + + #step + + #spec_partial_eq_impl + + impl From<#name> for u32 { + #[inline] + fn from(v: #name) -> u32 { + v.as_u32() + } + } + + impl From<#name> for usize { + #[inline] + fn from(v: #name) -> usize { + v.as_usize() + } + } + + impl From for #name { + #[inline] + fn from(value: usize) -> Self { + Self::from_usize(value) + } + } + + impl From for #name { + #[inline] + fn from(value: u32) -> Self { + Self::from_u32(value) + } + } + + #encodable_impls + #debug_impl + })) + } +} + +pub fn newtype(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input = parse_macro_input!(input as Newtype); + input.0.into() +} -- cgit v1.2.3