1- use alloc:: {
2- boxed:: Box ,
3- format,
4- string:: { String , ToString } ,
5- vec,
6- vec:: Vec ,
7- } ;
1+ use alloc:: { boxed:: Box , vec, vec:: Vec } ;
82use core:: num:: NonZeroU32 ;
93
104use crate :: common:: wgsl:: TypeContext ;
@@ -13,9 +7,22 @@ use crate::front::wgsl::parse::ast;
137use crate :: front:: wgsl:: { Error , Result } ;
148use crate :: { Handle , Span } ;
159
16- /// A cooked form of `ast::ConstructorType` that uses Naga types whenever
17- /// possible.
18- enum Constructor < T > {
10+ /// A [`constructor built-in function`].
11+ ///
12+ /// WGSL has two types of such functions:
13+ ///
14+ /// - Those that fully specify the type being constructed, like
15+ /// `vec3<f32>(x,y,z)`, which obviously constructs a `vec3<f32>`.
16+ ///
17+ /// - Those that leave the component type of the composite being constructed
18+ /// implicit, to be inferred from the argument types, like `vec3(x,y,z)`,
19+ /// which constructs a `vec3<T>` where `T` is the type of `x`, `y`, and `z`.
20+ ///
21+ /// This enum represents both cases. The `PartialFoo` variants
22+ /// represent the second case, where the component type is implicit.
23+ ///
24+ /// [`constructor built-in function`]: https://gpuweb.github.io/gpuweb/wgsl/#constructor-builtin-function
25+ pub enum Constructor < T > {
1926 /// A vector construction whose component type is inferred from the
2027 /// argument: `vec3(1.0)`.
2128 PartialVector { size : crate :: VectorSize } ,
@@ -62,21 +69,6 @@ impl Constructor<Handle<crate::Type>> {
6269 }
6370}
6471
65- impl Constructor < ( Handle < crate :: Type > , & crate :: TypeInner ) > {
66- fn to_error_string ( & self , ctx : & ExpressionContext ) -> String {
67- match * self {
68- Self :: PartialVector { size } => {
69- format ! ( "vec{}<?>" , size as u32 , )
70- }
71- Self :: PartialMatrix { columns, rows } => {
72- format ! ( "mat{}x{}<?>" , columns as u32 , rows as u32 , )
73- }
74- Self :: PartialArray => "array<?, ?>" . to_string ( ) ,
75- Self :: Type ( ( handle, _inner) ) => ctx. type_to_string ( handle) ,
76- }
77- }
78- }
79-
8072enum Components < ' a > {
8173 None ,
8274 One {
@@ -117,15 +109,13 @@ impl<'source> Lowerer<'source, '_> {
117109 pub fn construct (
118110 & mut self ,
119111 span : Span ,
120- constructor : & ast :: ConstructorType < ' source > ,
112+ constructor : Constructor < Handle < crate :: Type > > ,
121113 ty_span : Span ,
122114 components : & [ Handle < ast:: Expression < ' source > > ] ,
123115 ctx : & mut ExpressionContext < ' source , ' _ , ' _ > ,
124116 ) -> Result < ' source , Handle < crate :: Expression > > {
125117 use crate :: proc:: TypeResolution as Tr ;
126118
127- let constructor_h = self . constructor ( constructor, ctx) ?;
128-
129119 let components = match * components {
130120 [ ] => Components :: None ,
131121 [ component] => {
@@ -160,7 +150,7 @@ impl<'source> Lowerer<'source, '_> {
160150 // Even though we computed `constructor` above, wait until now to borrow
161151 // a reference to the `TypeInner`, so that the component-handling code
162152 // above can have mutable access to the type arena.
163- let constructor = constructor_h . borrow_inner ( ctx. module ) ;
153+ let constructor = constructor . borrow_inner ( ctx. module ) ;
164154
165155 let expr;
166156 match ( components, constructor) {
@@ -554,14 +544,19 @@ impl<'source> Lowerer<'source, '_> {
554544 Components :: One {
555545 span, component, ..
556546 } ,
557- constructor,
547+ Constructor :: Type ( (
548+ ty,
549+ & ( crate :: TypeInner :: Scalar { .. }
550+ | crate :: TypeInner :: Vector { .. }
551+ | crate :: TypeInner :: Matrix { .. } ) ,
552+ ) ) ,
558553 ) => {
559554 let component_ty = & ctx. typifier ( ) [ component] ;
560555 let from_type = ctx. type_resolution_to_string ( component_ty) ;
561556 return Err ( Box :: new ( Error :: BadTypeCast {
562557 span,
563558 from_type,
564- to_type : constructor . to_error_string ( ctx ) ,
559+ to_type : ctx . type_to_string ( ty ) ,
565560 } ) ) ;
566561 }
567562
@@ -581,77 +576,4 @@ impl<'source> Lowerer<'source, '_> {
581576 let expr = ctx. append_expression ( expr, span) ?;
582577 Ok ( expr)
583578 }
584-
585- /// Build a [`Constructor`] for a WGSL construction expression.
586- ///
587- /// If `constructor` conveys enough information to determine which Naga [`Type`]
588- /// we're actually building (i.e., it's not a partial constructor), then
589- /// ensure the `Type` exists in [`ctx.module`], and return
590- /// [`Constructor::Type`].
591- ///
592- /// Otherwise, return the [`Constructor`] partial variant corresponding to
593- /// `constructor`.
594- ///
595- /// [`Type`]: crate::Type
596- /// [`ctx.module`]: ExpressionContext::module
597- fn constructor < ' out > (
598- & mut self ,
599- constructor : & ast:: ConstructorType < ' source > ,
600- ctx : & mut ExpressionContext < ' source , ' _ , ' out > ,
601- ) -> Result < ' source , Constructor < Handle < crate :: Type > > > {
602- let handle = match * constructor {
603- ast:: ConstructorType :: Scalar ( scalar) => {
604- let ty = ctx. ensure_type_exists ( scalar. to_inner_scalar ( ) ) ;
605- Constructor :: Type ( ty)
606- }
607- ast:: ConstructorType :: PartialVector { size } => Constructor :: PartialVector { size } ,
608- ast:: ConstructorType :: Vector { size, ty, ty_span } => {
609- let ty = self . resolve_ast_type ( ty, & mut ctx. as_const ( ) ) ?;
610- let scalar = match ctx. module . types [ ty] . inner {
611- crate :: TypeInner :: Scalar ( sc) => sc,
612- _ => return Err ( Box :: new ( Error :: UnknownScalarType ( ty_span) ) ) ,
613- } ;
614- let ty = ctx. ensure_type_exists ( crate :: TypeInner :: Vector { size, scalar } ) ;
615- Constructor :: Type ( ty)
616- }
617- ast:: ConstructorType :: PartialMatrix { columns, rows } => {
618- Constructor :: PartialMatrix { columns, rows }
619- }
620- ast:: ConstructorType :: Matrix {
621- rows,
622- columns,
623- ty,
624- ty_span,
625- } => {
626- let ty = self . resolve_ast_type ( ty, & mut ctx. as_const ( ) ) ?;
627- let scalar = match ctx. module . types [ ty] . inner {
628- crate :: TypeInner :: Scalar ( sc) => sc,
629- _ => return Err ( Box :: new ( Error :: UnknownScalarType ( ty_span) ) ) ,
630- } ;
631- let ty = match scalar. kind {
632- crate :: ScalarKind :: Float => ctx. ensure_type_exists ( crate :: TypeInner :: Matrix {
633- columns,
634- rows,
635- scalar,
636- } ) ,
637- _ => return Err ( Box :: new ( Error :: BadMatrixScalarKind ( ty_span, scalar) ) ) ,
638- } ;
639- Constructor :: Type ( ty)
640- }
641- ast:: ConstructorType :: PartialArray => Constructor :: PartialArray ,
642- ast:: ConstructorType :: Array { base, size } => {
643- let base = self . resolve_ast_type ( base, & mut ctx. as_const ( ) ) ?;
644- let size = self . array_size ( size, & mut ctx. as_const ( ) ) ?;
645-
646- ctx. layouter . update ( ctx. module . to_ctx ( ) ) . unwrap ( ) ;
647- let stride = ctx. layouter [ base] . to_stride ( ) ;
648-
649- let ty = ctx. ensure_type_exists ( crate :: TypeInner :: Array { base, size, stride } ) ;
650- Constructor :: Type ( ty)
651- }
652- ast:: ConstructorType :: Type ( ty) => Constructor :: Type ( ty) ,
653- } ;
654-
655- Ok ( handle)
656- }
657579}
0 commit comments