naga/proc/overloads/
rule.rs1use crate::common::{DiagnosticDebug, ForDebugWithTypes};
16use crate::ir;
17use crate::proc::overloads::constructor_set::ConstructorSize;
18use crate::proc::TypeResolution;
19use crate::UniqueArena;
20
21use alloc::vec::Vec;
22use core::fmt;
23use core::result::Result;
24
25#[derive(Clone)]
27pub struct Rule {
28 pub arguments: Vec<TypeResolution>,
29 pub conclusion: Conclusion,
30}
31
32#[derive(Clone, Debug)]
44pub enum Conclusion {
45 Value(ir::TypeInner),
49
50 Predeclared(ir::PredeclaredType),
59}
60
61impl Conclusion {
62 pub fn for_frexp_modf(
63 function: ir::MathFunction,
64 size: ConstructorSize,
65 scalar: ir::Scalar,
66 ) -> Self {
67 use ir::MathFunction as Mf;
68 use ir::PredeclaredType as Pt;
69
70 let size = match size {
71 ConstructorSize::Scalar => None,
72 ConstructorSize::Vector(size) => Some(size),
73 ConstructorSize::Matrix { .. } => {
74 unreachable!("FrexpModf only supports scalars and vectors");
75 }
76 };
77
78 let predeclared = match function {
79 Mf::Frexp => Pt::FrexpResult { size, scalar },
80 Mf::Modf => Pt::ModfResult { size, scalar },
81 _ => {
82 unreachable!("FrexpModf only supports Frexp and Modf");
83 }
84 };
85
86 Conclusion::Predeclared(predeclared)
87 }
88
89 pub fn into_resolution(
90 self,
91 special_types: &ir::SpecialTypes,
92 ) -> Result<TypeResolution, MissingSpecialType> {
93 match self {
94 Conclusion::Value(inner) => Ok(TypeResolution::Value(inner)),
95 Conclusion::Predeclared(predeclared) => {
96 let handle = *special_types
97 .predeclared_types
98 .get(&predeclared)
99 .ok_or(MissingSpecialType)?;
100 Ok(TypeResolution::Handle(handle))
101 }
102 }
103 }
104}
105
106#[derive(Debug, thiserror::Error)]
107#[error("Special type is not registered within the module")]
108pub struct MissingSpecialType;
109
110impl ForDebugWithTypes for &Rule {}
111
112impl fmt::Debug for DiagnosticDebug<(&Rule, &UniqueArena<ir::Type>)> {
113 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114 let (rule, arena) = self.0;
115 f.write_str("(")?;
116 for (i, argument) in rule.arguments.iter().enumerate() {
117 if i > 0 {
118 f.write_str(", ")?;
119 }
120 write!(f, "{:?}", argument.for_debug(arena))?;
121 }
122 write!(f, ") -> {:?}", rule.conclusion.for_debug(arena))
123 }
124}
125
126impl ForDebugWithTypes for &Conclusion {}
127
128impl fmt::Debug for DiagnosticDebug<(&Conclusion, &UniqueArena<ir::Type>)> {
129 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130 let (conclusion, ctx) = self.0;
131
132 #[cfg(any(feature = "wgsl-in", feature = "wgsl-out"))]
133 {
134 use crate::common::wgsl::TypeContext;
135 ctx.write_type_conclusion(conclusion, f)?;
136 }
137
138 #[cfg(not(any(feature = "wgsl-in", feature = "wgsl-out")))]
139 {
140 let _ = ctx;
141 write!(f, "{conclusion:?}")?;
142 }
143
144 Ok(())
145 }
146}