From f13e5058a7da11b0960039c7a37623deb1c14a0f Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Fri, 31 May 2024 13:29:54 +0200 Subject: [PATCH 1/3] Export discriminant values in `AdtDef` --- frontend/exporter/src/index_vec.rs | 8 ++++++++ frontend/exporter/src/types/copied.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/frontend/exporter/src/index_vec.rs b/frontend/exporter/src/index_vec.rs index 6fdeecb88..8a5400112 100644 --- a/frontend/exporter/src/index_vec.rs +++ b/frontend/exporter/src/index_vec.rs @@ -30,6 +30,14 @@ impl std::ops::DerefMut for IndexVec { } } +impl IndexVec { + pub fn into_iter_enumerated( + self, + ) -> impl DoubleEndedIterator + ExactSizeIterator { + rustc_index::IndexVec::from_raw(self.raw).into_iter_enumerated() + } +} + impl< S, J: rustc_index::Idx, diff --git a/frontend/exporter/src/types/copied.rs b/frontend/exporter/src/types/copied.rs index 1f7cdc1fa..e7b5245c1 100644 --- a/frontend/exporter/src/types/copied.rs +++ b/frontend/exporter/src/types/copied.rs @@ -478,6 +478,14 @@ pub enum VariantDiscr { Relative(u32), } +/// Reflects [`rustc_middle::ty::util::Discr`] +#[derive(AdtInto, Clone, Debug, Serialize, Deserialize, JsonSchema)] +#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: rustc_middle::ty::util::Discr<'tcx>, state: S as gstate)] +pub struct DiscriminantValue { + pub val: u128, + pub ty: Ty, +} + /// Reflects [`rustc_middle::ty::Visibility`] #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub enum Visibility { @@ -1763,6 +1771,7 @@ pub struct AdtDef { pub did: DefId, pub adt_kind: AdtKind, pub variants: IndexVec, + pub discriminants: IndexVec, pub flags: AdtFlags, pub repr: ReprOptions, } @@ -1785,10 +1794,28 @@ pub struct ReprOptions { impl<'tcx, S: UnderOwnerState<'tcx>> SInto for rustc_middle::ty::AdtDef<'tcx> { fn sinto(&self, s: &S) -> AdtDef { + let discriminants: Vec<_> = if self.is_enum() { + self.variants() + .iter_enumerated() + .map(|(variant_idx, _variant)| { + self.discriminant_for_variant(s.base().tcx, variant_idx) + }) + .collect() + } else { + // Structs and unions have a single variant. + assert_eq!(self.variants().len(), 1); + vec![rustc_middle::ty::util::Discr { + val: 0, + ty: s.base().tcx.types.isize, + }] + }; + let discriminants: rustc_index::IndexVec = + rustc_index::IndexVec::from_raw(discriminants); AdtDef { did: self.did().sinto(s), adt_kind: self.adt_kind().sinto(s), variants: self.variants().sinto(s), + discriminants: discriminants.sinto(s), flags: self.flags().sinto(s), repr: self.repr().sinto(s), } From adb97733179ecca6ee4a55dae3e935e1ceb70084 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Fri, 14 Jun 2024 11:17:19 +0200 Subject: [PATCH 2/3] Tweak --- frontend/exporter/src/index_vec.rs | 40 ++++++++++++++---------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/frontend/exporter/src/index_vec.rs b/frontend/exporter/src/index_vec.rs index 8a5400112..32aa042e0 100644 --- a/frontend/exporter/src/index_vec.rs +++ b/frontend/exporter/src/index_vec.rs @@ -1,50 +1,46 @@ use crate::prelude::*; +use rustc_index::{Idx, IndexSlice}; #[derive( Clone, Debug, Serialize, Deserialize, JsonSchema, Hash, PartialEq, Eq, PartialOrd, Ord, )] -pub struct IndexVec { +pub struct IndexVec { pub raw: Vec, _marker: std::marker::PhantomData, } -impl Into> for rustc_index::IndexVec { - fn into(self) -> IndexVec { - IndexVec { - raw: self.raw, - _marker: std::marker::PhantomData, - } +impl IndexVec { + pub fn into_iter_enumerated( + self, + ) -> impl DoubleEndedIterator + ExactSizeIterator { + rustc_index::IndexVec::from_raw(self.raw).into_iter_enumerated() } } -impl std::ops::Deref for IndexVec { - type Target = rustc_index::IndexSlice; +impl std::ops::Deref for IndexVec { + type Target = IndexSlice; fn deref(&self) -> &Self::Target { Self::Target::from_raw(&self.raw) } } -impl std::ops::DerefMut for IndexVec { +impl std::ops::DerefMut for IndexVec { fn deref_mut(&mut self) -> &mut Self::Target { Self::Target::from_raw_mut(&mut self.raw) } } -impl IndexVec { - pub fn into_iter_enumerated( - self, - ) -> impl DoubleEndedIterator + ExactSizeIterator { - rustc_index::IndexVec::from_raw(self.raw).into_iter_enumerated() +impl Into> for rustc_index::IndexVec { + fn into(self) -> IndexVec { + IndexVec { + raw: self.raw, + _marker: std::marker::PhantomData, + } } } -impl< - S, - J: rustc_index::Idx, - I: rustc_index::Idx + SInto, - U: Clone, /*TODO: remove me?*/ - T: SInto, - > SInto> for rustc_index::IndexSlice +impl, U: Clone /*TODO: remove me?*/, T: SInto> + SInto> for IndexSlice { fn sinto(&self, s: &S) -> IndexVec { IndexVec { From 5f44786e609928358f914d672dc340137d2b3949 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Fri, 14 Jun 2024 11:34:41 +0200 Subject: [PATCH 3/3] Store the discriminant value directly in `VariantDef` --- frontend/exporter/src/index_vec.rs | 16 +++++++ frontend/exporter/src/types/copied.rs | 66 ++++++++++++++++----------- 2 files changed, 56 insertions(+), 26 deletions(-) diff --git a/frontend/exporter/src/index_vec.rs b/frontend/exporter/src/index_vec.rs index 32aa042e0..fa9f26335 100644 --- a/frontend/exporter/src/index_vec.rs +++ b/frontend/exporter/src/index_vec.rs @@ -15,6 +15,9 @@ impl IndexVec { ) -> impl DoubleEndedIterator + ExactSizeIterator { rustc_index::IndexVec::from_raw(self.raw).into_iter_enumerated() } + pub fn into_iter(self) -> impl DoubleEndedIterator + ExactSizeIterator { + self.raw.into_iter() + } } impl std::ops::Deref for IndexVec { @@ -50,6 +53,19 @@ impl, U: Clone /*TODO: remove me?*/, T: SInto FromIterator for IndexVec +where + I: Idx, +{ + #[inline] + fn from_iter>(iter: It) -> Self { + Self { + raw: Vec::from_iter(iter), + _marker: std::marker::PhantomData, + } + } +} + macro_rules! make_idx_wrapper { ($($mod:ident)::+, $type:ident) => { #[derive(Copy, Clone, Eq, Debug, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize, JsonSchema)] diff --git a/frontend/exporter/src/types/copied.rs b/frontend/exporter/src/types/copied.rs index e7b5245c1..6904dae02 100644 --- a/frontend/exporter/src/types/copied.rs +++ b/frontend/exporter/src/types/copied.rs @@ -473,7 +473,7 @@ pub enum CtorKind { /// Reflects [`rustc_middle::ty::VariantDiscr`] #[derive(AdtInto, Clone, Debug, Serialize, Deserialize, JsonSchema)] #[args(<'tcx, S: UnderOwnerState<'tcx>>, from: rustc_middle::ty::VariantDiscr, state: S as gstate)] -pub enum VariantDiscr { +pub enum DiscriminantDefinition { Explicit(DefId), Relative(u32), } @@ -544,24 +544,40 @@ impl<'tcx, S: UnderOwnerState<'tcx>> SInto for rustc_middle::ty::Fi } /// Reflects [`rustc_middle::ty::VariantDef`] -#[derive(AdtInto, Clone, Debug, Serialize, Deserialize, JsonSchema)] -#[args(<'tcx, S: UnderOwnerState<'tcx>>, from: rustc_middle::ty::VariantDef, state: S as s)] +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct VariantDef { pub def_id: DefId, pub ctor: Option<(CtorKind, DefId)>, pub name: Symbol, - pub discr: VariantDiscr, + pub discr_def: DiscriminantDefinition, + pub discr_val: DiscriminantValue, /// The definitions of the fields on this variant. In case of /// [tuple /// structs](https://doc.rust-lang.org/book/ch05-01-defining-structs.html#using-tuple-structs-without-named-fields-to-create-different-types), /// the fields are anonymous, otherwise fields are named. - #[value(self.fields.raw.sinto(s))] pub fields: Vec, /// Span of the definition of the variant - #[value(s.base().tcx.def_span(self.def_id).sinto(s))] pub span: Span, } +impl VariantDef { + fn sfrom<'tcx, S: UnderOwnerState<'tcx>>( + s: &S, + def: &ty::VariantDef, + discr_val: ty::util::Discr<'tcx>, + ) -> Self { + VariantDef { + def_id: def.def_id.sinto(s), + ctor: def.ctor.sinto(s), + name: def.name.sinto(s), + discr_def: def.discr.sinto(s), + discr_val: discr_val.sinto(s), + fields: def.fields.raw.sinto(s), + span: s.base().tcx.def_span(def.def_id).sinto(s), + } + } +} + /// Reflects [`rustc_middle::ty::EarlyParamRegion`] #[derive( AdtInto, Clone, Debug, Serialize, Deserialize, JsonSchema, Hash, PartialEq, Eq, PartialOrd, Ord, @@ -1771,7 +1787,6 @@ pub struct AdtDef { pub did: DefId, pub adt_kind: AdtKind, pub variants: IndexVec, - pub discriminants: IndexVec, pub flags: AdtFlags, pub repr: ReprOptions, } @@ -1794,28 +1809,27 @@ pub struct ReprOptions { impl<'tcx, S: UnderOwnerState<'tcx>> SInto for rustc_middle::ty::AdtDef<'tcx> { fn sinto(&self, s: &S) -> AdtDef { - let discriminants: Vec<_> = if self.is_enum() { - self.variants() - .iter_enumerated() - .map(|(variant_idx, _variant)| { + let variants = self + .variants() + .iter_enumerated() + .map(|(variant_idx, variant)| { + let discr = if self.is_enum() { self.discriminant_for_variant(s.base().tcx, variant_idx) - }) - .collect() - } else { - // Structs and unions have a single variant. - assert_eq!(self.variants().len(), 1); - vec![rustc_middle::ty::util::Discr { - val: 0, - ty: s.base().tcx.types.isize, - }] - }; - let discriminants: rustc_index::IndexVec = - rustc_index::IndexVec::from_raw(discriminants); + } else { + // Structs and unions have a single variant. + assert_eq!(variant_idx.index(), 0); + rustc_middle::ty::util::Discr { + val: 0, + ty: s.base().tcx.types.isize, + } + }; + VariantDef::sfrom(s, variant, discr) + }) + .collect(); AdtDef { did: self.did().sinto(s), adt_kind: self.adt_kind().sinto(s), - variants: self.variants().sinto(s), - discriminants: discriminants.sinto(s), + variants, flags: self.flags().sinto(s), repr: self.repr().sinto(s), } @@ -2919,7 +2933,7 @@ pub struct Variant { .find(|v| v.def_id == self.def_id.into()).unwrap(); variant.discr.sinto(s) })] - pub discr: VariantDiscr, + pub discr: DiscriminantDefinition, pub span: Span, #[value(s.base().tcx.hir().attrs(hir_id.clone()).sinto(s))] pub attributes: Vec,