naga/proc/overloads/
any_overload_set.rs

1//! Dynamically dispatched [`OverloadSet`]s.
2
3use crate::common::DiagnosticDebug;
4use crate::ir;
5use crate::proc::overloads::{list, regular, OverloadSet, Rule};
6use crate::proc::{GlobalCtx, TypeResolution};
7
8use alloc::vec::Vec;
9use core::fmt;
10
11macro_rules! define_any_overload_set {
12    { $( $module:ident :: $name:ident, )* } => {
13        /// An [`OverloadSet`] that dynamically dispatches to concrete implementations.
14        #[derive(Clone)]
15        pub(in crate::proc::overloads) enum AnyOverloadSet {
16            $(
17                $name ( $module :: $name ),
18            )*
19        }
20
21        $(
22            impl From<$module::$name> for AnyOverloadSet {
23                fn from(concrete: $module::$name) -> Self {
24                    AnyOverloadSet::$name(concrete)
25                }
26            }
27        )*
28
29        impl OverloadSet for AnyOverloadSet {
30            fn is_empty(&self) -> bool {
31                match *self {
32                    $(
33                        AnyOverloadSet::$name(ref x) => x.is_empty(),
34                    )*
35                }
36            }
37
38            fn min_arguments(&self) -> usize {
39                match *self {
40                    $(
41                        AnyOverloadSet::$name(ref x) => x.min_arguments(),
42                    )*
43                }
44            }
45
46            fn max_arguments(&self) -> usize {
47                match *self {
48                    $(
49                        AnyOverloadSet::$name(ref x) => x.max_arguments(),
50                    )*
51                }
52            }
53
54            fn arg(
55                &self,
56                i: usize,
57                ty: &ir::TypeInner,
58                types: &crate::UniqueArena<ir::Type>,
59            ) -> Self {
60                match *self {
61                    $(
62                        AnyOverloadSet::$name(ref x) => AnyOverloadSet::$name(x.arg(i, ty, types)),
63                    )*
64                }
65            }
66
67            fn concrete_only(self, types: &crate::UniqueArena<ir::Type>) -> Self {
68                match self {
69                    $(
70                        AnyOverloadSet::$name(x) => AnyOverloadSet::$name(x.concrete_only(types)),
71                    )*
72                }
73            }
74
75            fn most_preferred(&self) -> Rule {
76                match *self {
77                    $(
78                        AnyOverloadSet::$name(ref x) => x.most_preferred(),
79                    )*
80                }
81            }
82
83            fn overload_list(&self, gctx: &GlobalCtx<'_>) -> Vec<Rule> {
84                match *self {
85                    $(
86                        AnyOverloadSet::$name(ref x) => x.overload_list(gctx),
87                    )*
88                }
89            }
90
91            fn allowed_args(&self, i: usize, gctx: &GlobalCtx<'_>) -> Vec<TypeResolution> {
92                match *self {
93                    $(
94                        AnyOverloadSet::$name(ref x) => x.allowed_args(i, gctx),
95                    )*
96                }
97            }
98
99            fn for_debug(&self, types: &crate::UniqueArena<ir::Type>) -> impl fmt::Debug {
100                DiagnosticDebug((self, types))
101            }
102        }
103
104        impl fmt::Debug for DiagnosticDebug<(&AnyOverloadSet, &crate::UniqueArena<ir::Type>)> {
105            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106                let (set, types) = self.0;
107                match *set {
108                    $(
109                        AnyOverloadSet::$name(ref x) => DiagnosticDebug((x, types)).fmt(f),
110                    )*
111                }
112            }
113        }
114    }
115}
116
117define_any_overload_set! {
118    list::List,
119    regular::Regular,
120}