Skip to content
4 changes: 2 additions & 2 deletions compiler/rustc_abi/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ rustc_index::newtype_index! {
/// `b` is `FieldIdx(1)` in `VariantIdx(0)`,
/// `d` is `FieldIdx(1)` in `VariantIdx(1)`, and
/// `f` is `FieldIdx(1)` in `VariantIdx(0)`.
#[cfg_attr(feature = "nightly", derive(rustc_macros::HashStable_Generic))]
#[stable_hash_generic]
#[encodable]
#[orderable]
#[gate_rustc_only]
Expand All @@ -70,7 +70,7 @@ rustc_index::newtype_index! {
///
/// `struct`s, `tuples`, and `unions`s are considered to have a single variant
/// with variant index zero, aka [`FIRST_VARIANT`].
#[cfg_attr(feature = "nightly", derive(rustc_macros::HashStable_Generic))]
#[stable_hash_generic]
#[encodable]
#[orderable]
#[gate_rustc_only]
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_data_structures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#![feature(min_specialization)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(pattern_type_macro)]
#![feature(pattern_types)]
#![feature(ptr_alignment_type)]
#![feature(rustc_attrs)]
#![feature(sized_hierarchy)]
Expand Down
52 changes: 28 additions & 24 deletions compiler/rustc_hir_analysis/src/delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,31 +597,35 @@ fn get_delegation_user_specified_args<'tcx>(
.as_slice()
});

let child_args = info.child_args_segment_id.and_then(get_segment).map(|(segment, def_id)| {
let parent_args = if let Some(parent_args) = parent_args {
parent_args
} else {
let parent = tcx.parent(def_id);
if matches!(tcx.def_kind(parent), DefKind::Trait) {
ty::GenericArgs::identity_for_item(tcx, parent).as_slice()
let child_args = info
.child_args_segment_id
.and_then(get_segment)
.filter(|(_, def_id)| matches!(tcx.def_kind(*def_id), DefKind::Fn | DefKind::AssocFn))
.map(|(segment, def_id)| {
let parent_args = if let Some(parent_args) = parent_args {
parent_args
} else {
&[]
}
};

let args = lowerer
.lower_generic_args_of_path(
segment.ident.span,
def_id,
parent_args,
segment,
None,
GenericArgPosition::Value,
)
.0;

&args[parent_args.len()..]
});
let parent = tcx.parent(def_id);
if matches!(tcx.def_kind(parent), DefKind::Trait) {
ty::GenericArgs::identity_for_item(tcx, parent).as_slice()
} else {
&[]
}
};

let args = lowerer
.lower_generic_args_of_path(
segment.ident.span,
def_id,
parent_args,
segment,
None,
GenericArgPosition::Value,
)
.0;

&args[parent_args.len()..]
});

(parent_args.unwrap_or_default(), child_args.unwrap_or_default())
}
2 changes: 1 addition & 1 deletion compiler/rustc_hir_id/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ rustc_index::newtype_index! {
/// integers starting at zero, so a mapping that maps all or most nodes within
/// an "item-like" to something else can be implemented by a `Vec` instead of a
/// tree or hash map.
#[derive(HashStable_Generic)]
#[stable_hash_generic]
#[encodable]
#[orderable]
pub struct ItemLocalId {}
Expand Down
12 changes: 11 additions & 1 deletion compiler/rustc_index_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,17 @@ mod newtype;
/// 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))]
#[cfg_attr(
feature = "nightly",
allow_internal_unstable(
step_trait,
rustc_attrs,
trusted_step,
pattern_types,
pattern_type_macro,
structural_match,
)
)]
pub fn newtype_index(input: TokenStream) -> TokenStream {
newtype::newtype(input)
}
83 changes: 72 additions & 11 deletions compiler/rustc_index_macros/src/newtype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ impl Parse for Newtype {
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 stable_hash = false;
let mut stable_hash_generic = false;
let mut stable_hash_no_context = false;
let mut gate_rustc_only = quote! {};
let mut gate_rustc_only_cfg = quote! { all() };

Expand All @@ -42,6 +44,18 @@ impl Parse for Newtype {
ord = true;
false
}
"stable_hash" => {
stable_hash = true;
false
}
"stable_hash_generic" => {
stable_hash_generic = true;
false
}
"stable_hash_no_context" => {
stable_hash_no_context = true;
false
}
"max" => {
let Meta::NameValue(MetaNameValue { value: Expr::Lit(lit), .. }) = &attr.meta
else {
Expand Down Expand Up @@ -111,12 +125,6 @@ impl Parse for Newtype {
} else {
quote! {}
};

if ord {
derive_paths.push(parse_quote!(Ord));
derive_paths.push(parse_quote!(PartialOrd));
}

let step = if ord {
quote! {
#gate_rustc_only
Expand All @@ -139,6 +147,38 @@ impl Parse for Newtype {
Self::index(start).checked_sub(u).map(Self::from_usize)
}
}
impl ::std::cmp::Ord for #name {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.as_u32().cmp(&other.as_u32())
}
}
impl ::std::cmp::PartialOrd for #name {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.as_u32().partial_cmp(&other.as_u32())
}
}
}
} else {
quote! {}
};

let hash_stable = if stable_hash {
quote! {
#gate_rustc_only
impl<'__ctx> ::rustc_data_structures::stable_hasher::HashStable<::rustc_middle::ich::StableHashingContext<'__ctx>> for #name {
fn hash_stable(&self, hcx: &mut ::rustc_middle::ich::StableHashingContext<'__ctx>, hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) {
self.as_u32().hash_stable(hcx, hasher)
}
}
}
} else if stable_hash_generic || stable_hash_no_context {
quote! {
#gate_rustc_only
impl<CTX> ::rustc_data_structures::stable_hasher::HashStable<CTX> for #name {
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) {
self.as_u32().hash_stable(hcx, hasher)
}
}
}
} else {
quote! {}
Expand All @@ -154,11 +194,13 @@ impl Parse for Newtype {

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))]
#[derive(Clone, Copy)]
#[cfg_attr(#gate_rustc_only_cfg, rustc_pass_by_value)]
#vis struct #name {
#[cfg(not(#gate_rustc_only_cfg))]
private_use_as_methods_instead: u32,
#[cfg(#gate_rustc_only_cfg)]
private_use_as_methods_instead: pattern_type!(u32 is 0..=#max),
}

#(#consts)*
Expand Down Expand Up @@ -226,7 +268,7 @@ impl Parse for Newtype {
/// Prefer using `from_u32`.
#[inline]
#vis const unsafe fn from_u32_unchecked(value: u32) -> Self {
Self { private_use_as_methods_instead: value }
Self { private_use_as_methods_instead: unsafe { std::mem::transmute(value) } }
}

/// Extracts the value of this index as a `usize`.
Expand All @@ -238,7 +280,7 @@ impl Parse for Newtype {
/// Extracts the value of this index as a `u32`.
#[inline]
#vis const fn as_u32(self) -> u32 {
self.private_use_as_methods_instead
unsafe { std::mem::transmute(self.private_use_as_methods_instead) }
}

/// Extracts the value of this index as a `usize`.
Expand Down Expand Up @@ -278,6 +320,8 @@ impl Parse for Newtype {

#step

#hash_stable

impl From<#name> for u32 {
#[inline]
fn from(v: #name) -> u32 {
Expand Down Expand Up @@ -306,6 +350,23 @@ impl Parse for Newtype {
}
}

impl ::std::cmp::Eq for #name {}

impl ::std::cmp::PartialEq for #name {
fn eq(&self, other: &Self) -> bool {
self.as_u32().eq(&other.as_u32())
}
}

#gate_rustc_only
impl ::std::marker::StructuralPartialEq for #name {}

impl ::std::hash::Hash for #name {
fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
self.as_u32().hash(state)
}
}

#encodable_impls
#debug_impl
}))
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/middle/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ rustc_index::newtype_index! {
///
/// * The subscope with `first_statement_index == 1` is scope of `c`,
/// and thus does not include EXPR_2, but covers the `...`.
#[derive(HashStable)]
#[stable_hash]
#[encodable]
#[orderable]
pub struct FirstStatementIndex {}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/mir/coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rustc_span::Span;
rustc_index::newtype_index! {
/// Used by [`CoverageKind::BlockMarker`] to mark blocks during THIR-to-MIR
/// lowering, so that those blocks can be identified later.
#[derive(HashStable)]
#[stable_hash]
#[encodable]
#[debug_format = "BlockMarkerId({})"]
pub struct BlockMarkerId {}
Expand All @@ -26,7 +26,7 @@ rustc_index::newtype_index! {
///
/// Note that LLVM handles counter IDs as `uint32_t`, so there is no need
/// to use a larger representation on the Rust side.
#[derive(HashStable)]
#[stable_hash]
#[encodable]
#[orderable]
#[debug_format = "CounterId({})"]
Expand All @@ -43,7 +43,7 @@ rustc_index::newtype_index! {
///
/// Note that LLVM handles expression IDs as `uint32_t`, so there is no need
/// to use a larger representation on the Rust side.
#[derive(HashStable)]
#[stable_hash]
#[encodable]
#[orderable]
#[debug_format = "ExpressionId({})"]
Expand Down Expand Up @@ -203,7 +203,7 @@ rustc_index::newtype_index! {
///
/// After that pass is complete, the coverage graph no longer exists, so a
/// BCB is effectively an opaque ID.
#[derive(HashStable)]
#[stable_hash]
#[encodable]
#[orderable]
#[debug_format = "bcb{}"]
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,7 @@ impl SourceInfo {
// Variables and temps

rustc_index::newtype_index! {
#[derive(HashStable)]
#[stable_hash]
#[encodable]
#[orderable]
#[debug_format = "_{}"]
Expand Down Expand Up @@ -1263,7 +1263,7 @@ rustc_index::newtype_index! {
/// https://rustc-dev-guide.rust-lang.org/appendix/background.html#what-is-a-dataflow-analysis
/// [`CriticalCallEdges`]: ../../rustc_mir_transform/add_call_guards/enum.AddCallGuards.html#variant.CriticalCallEdges
/// [guide-mir]: https://rustc-dev-guide.rust-lang.org/mir/
#[derive(HashStable)]
#[stable_hash]
#[encodable]
#[orderable]
#[debug_format = "bb{}"]
Expand Down Expand Up @@ -1397,7 +1397,7 @@ impl<'tcx> BasicBlockData<'tcx> {
// Scopes

rustc_index::newtype_index! {
#[derive(HashStable)]
#[stable_hash]
#[encodable]
#[debug_format = "scope[{}]"]
pub struct SourceScope {
Expand Down Expand Up @@ -1536,7 +1536,7 @@ pub struct UserTypeProjection {
}

rustc_index::newtype_index! {
#[derive(HashStable)]
#[stable_hash]
#[encodable]
#[orderable]
#[debug_format = "promoted[{}]"]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use super::{ConstValue, SourceInfo};
use crate::ty::{self, CoroutineArgsExt, Ty};

rustc_index::newtype_index! {
#[derive(HashStable)]
#[stable_hash]
#[encodable]
#[debug_format = "_s{}"]
pub struct CoroutineSavedLocal {}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/thir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ macro_rules! thir_with_elements {
) => {
$(
newtype_index! {
#[derive(HashStable)]
#[stable_hash]
#[debug_format = $format]
pub struct $id {}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/typeck_results.rs
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ impl<'a> LocalSetInContextMut<'a> {
}

rustc_index::newtype_index! {
#[derive(HashStable)]
#[stable_hash]
#[encodable]
#[debug_format = "UserType({})"]
pub struct UserTypeAnnotationIndex {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/jump_threading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ struct TOFinder<'a, 'tcx> {
}

rustc_index::newtype_index! {
#[derive(Ord, PartialOrd)]
#[orderable]
#[debug_format = "_c{}"]
struct ConditionIndex {}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_monomorphize/src/graph_checks/statics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl From<usize> for StaticNodeIdx {
}

newtype_index! {
#[derive(Ord, PartialOrd)]
#[orderable]
struct StaticSccIdx {}
}

Expand Down
Loading
Loading