summaryrefslogtreecommitdiffstats
path: root/vendor/ra-ap-rustc_index_macros
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
commit9918693037dce8aa4bb6f08741b6812923486c18 (patch)
tree21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/ra-ap-rustc_index_macros
parentReleasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff)
downloadrustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz
rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/ra-ap-rustc_index_macros')
-rw-r--r--vendor/ra-ap-rustc_index_macros/.cargo-checksum.json1
-rw-r--r--vendor/ra-ap-rustc_index_macros/Cargo.toml45
-rw-r--r--vendor/ra-ap-rustc_index_macros/src/lib.rs41
-rw-r--r--vendor/ra-ap-rustc_index_macros/src/newtype.rs324
4 files changed, 411 insertions, 0 deletions
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<Self> {
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ input.parse::<Token![struct]>()?;
+ let name: Ident = input.parse()?;
+
+ let body;
+ braced!(body in input);
+
+ // Any additional `#[derive]` macro paths to apply
+ let mut derive_paths: Vec<Path> = Vec::new();
+ let mut debug_format: Option<Lit> = 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::<Token![const]>()?;
+ let const_name: Ident = body.parse()?;
+ body.parse::<Token![=]>()?;
+ let const_val: Expr = body.parse()?;
+ body.parse::<Token![;]>()?;
+ 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<D: ::rustc_serialize::Decoder> ::rustc_serialize::Decodable<D> for #name {
+ fn decode(d: &mut D) -> Self {
+ Self::from_u32(d.read_u32())
+ }
+ }
+ #gate_rustc_only
+ impl<E: ::rustc_serialize::Encoder> ::rustc_serialize::Encodable<E> 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<usize> {
+ <usize as ::std::iter::Step>::steps_between(
+ &Self::index(*start),
+ &Self::index(*end),
+ )
+ }
+
+ #[inline]
+ fn forward_checked(start: Self, u: usize) -> Option<Self> {
+ Self::index(start).checked_add(u).map(Self::from_usize)
+ }
+
+ #[inline]
+ fn backward_checked(start: Self, u: usize) -> Option<Self> {
+ 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::<u32>() {
+ quote! {
+ #gate_rustc_only
+ impl core::option::SpecOptionPartialEq for #name {
+ #[inline]
+ fn eq(l: &Option<Self>, r: &Option<Self>) -> 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<usize> 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<usize> for #name {
+ #[inline]
+ fn from(value: usize) -> Self {
+ Self::from_usize(value)
+ }
+ }
+
+ impl From<u32> 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()
+}