midenc_hir/pass/
conversion.rs1use midenc_session::Session;
2
3use super::{AnalysisManager, Chain, PassInfo};
4use crate::diagnostics::Report;
5
6pub type ConversionResult<T> = Result<T, Report>;
8
9pub trait ConversionPassInfo: PassInfo + ConversionPass {}
13impl<P> ConversionPassInfo for P where P: PassInfo + ConversionPass {}
14
15pub trait ConversionPass {
25 type From;
26 type To;
27
28 fn convert(
30 &mut self,
31 entity: Self::From,
32 analyses: &mut AnalysisManager,
33 session: &Session,
34 ) -> ConversionResult<Self::To>;
35
36 fn chain<P>(self, next: P) -> Chain<Self, P>
38 where
39 Self: Sized,
40 P: ConversionPass<From = Self::To>,
41 {
42 Chain::new(self, next)
43 }
44}
45impl<P, T, U> ConversionPass for Box<P>
46where
47 P: ?Sized + ConversionPass<From = T, To = U>,
48{
49 type From = T;
50 type To = U;
51
52 fn convert(
53 &mut self,
54 entity: Self::From,
55 analyses: &mut AnalysisManager,
56 session: &Session,
57 ) -> ConversionResult<Self::To> {
58 (**self).convert(entity, analyses, session)
59 }
60}
61
62type ConversionPassCtor<T, U> = fn() -> Box<dyn ConversionPass<From = T, To = U>>;
63
64#[doc(hidden)]
65pub struct ConversionPassRegistration<T, U> {
66 pub name: &'static str,
67 pub summary: &'static str,
68 pub description: &'static str,
69 ctor: ConversionPassCtor<T, U>,
70}
71impl<T, U> ConversionPassRegistration<T, U> {
72 pub const fn new<P>() -> Self
73 where
74 P: ConversionPass<From = T, To = U> + PassInfo + Default + 'static,
75 {
76 Self {
77 name: <P as PassInfo>::FLAG,
78 summary: <P as PassInfo>::SUMMARY,
79 description: <P as PassInfo>::DESCRIPTION,
80 ctor: dyn_conversion_pass_ctor::<P, T, U>,
81 }
82 }
83
84 #[inline]
86 pub const fn name(&self) -> &'static str {
87 self.name
88 }
89
90 #[inline]
92 pub const fn summary(&self) -> &'static str {
93 self.summary
94 }
95
96 #[inline]
98 pub const fn description(&self) -> &'static str {
99 self.description
100 }
101
102 #[inline]
104 pub fn get(&self) -> Box<dyn ConversionPass<From = T, To = U>> {
105 (self.ctor)()
106 }
107}
108
109fn dyn_conversion_pass_ctor<P, T, U>() -> Box<dyn ConversionPass<From = T, To = U>>
110where
111 P: Default + ConversionPass<From = T, To = U> + 'static,
112{
113 Box::<P>::default()
114}