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:: { TryToWgsl , 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 {
@@ -108,24 +100,20 @@ impl<'source> Lowerer<'source, '_> {
108100 /// it's one of the `Partial` variants, we need to consider the argument
109101 /// types as well.
110102 ///
111- /// This is used for [`Construct`] expressions, but also for [`Call`]
112- /// expressions, once we've determined that the "callable" (in WGSL spec
113- /// terms) is actually a type.
103+ /// This is used for [`Call`] expressions, once we've determined that
104+ /// the "callable" (in WGSL spec terms) is actually a type.
114105 ///
115- /// [`Construct`]: ast::Expression::Construct
116106 /// [`Call`]: ast::Expression::Call
117107 pub fn construct (
118108 & mut self ,
119109 span : Span ,
120- constructor : & ast :: ConstructorType < ' source > ,
110+ constructor : Constructor < Handle < crate :: Type > > ,
121111 ty_span : Span ,
122112 components : & [ Handle < ast:: Expression < ' source > > ] ,
123113 ctx : & mut ExpressionContext < ' source , ' _ , ' _ > ,
124114 ) -> Result < ' source , Handle < crate :: Expression > > {
125115 use crate :: proc:: TypeResolution as Tr ;
126116
127- let constructor_h = self . constructor ( constructor, ctx) ?;
128-
129117 let components = match * components {
130118 [ ] => Components :: None ,
131119 [ component] => {
@@ -160,7 +148,7 @@ impl<'source> Lowerer<'source, '_> {
160148 // Even though we computed `constructor` above, wait until now to borrow
161149 // a reference to the `TypeInner`, so that the component-handling code
162150 // above can have mutable access to the type arena.
163- let constructor = constructor_h . borrow_inner ( ctx. module ) ;
151+ let constructor = constructor . borrow_inner ( ctx. module ) ;
164152
165153 let expr;
166154 match ( components, constructor) {
@@ -573,14 +561,19 @@ impl<'source> Lowerer<'source, '_> {
573561 Components :: One {
574562 span, component, ..
575563 } ,
576- constructor,
564+ Constructor :: Type ( (
565+ ty,
566+ & ( crate :: TypeInner :: Scalar { .. }
567+ | crate :: TypeInner :: Vector { .. }
568+ | crate :: TypeInner :: Matrix { .. } ) ,
569+ ) ) ,
577570 ) => {
578571 let component_ty = & ctx. typifier ( ) [ component] ;
579572 let from_type = ctx. type_resolution_to_string ( component_ty) ;
580573 return Err ( Box :: new ( Error :: BadTypeCast {
581574 span,
582575 from_type,
583- to_type : constructor . to_error_string ( ctx ) ,
576+ to_type : ctx . type_to_string ( ty ) ,
584577 } ) ) ;
585578 }
586579
@@ -600,100 +593,4 @@ impl<'source> Lowerer<'source, '_> {
600593 let expr = ctx. append_expression ( expr, span) ?;
601594 Ok ( expr)
602595 }
603-
604- /// Build a [`Constructor`] for a WGSL construction expression.
605- ///
606- /// If `constructor` conveys enough information to determine which Naga [`Type`]
607- /// we're actually building (i.e., it's not a partial constructor), then
608- /// ensure the `Type` exists in [`ctx.module`], and return
609- /// [`Constructor::Type`].
610- ///
611- /// Otherwise, return the [`Constructor`] partial variant corresponding to
612- /// `constructor`.
613- ///
614- /// [`Type`]: crate::Type
615- /// [`ctx.module`]: ExpressionContext::module
616- fn constructor < ' out > (
617- & mut self ,
618- constructor : & ast:: ConstructorType < ' source > ,
619- ctx : & mut ExpressionContext < ' source , ' _ , ' out > ,
620- ) -> Result < ' source , Constructor < Handle < crate :: Type > > > {
621- let handle = match * constructor {
622- ast:: ConstructorType :: Scalar ( scalar) => {
623- let ty = ctx. ensure_type_exists ( scalar. to_inner_scalar ( ) ) ;
624- Constructor :: Type ( ty)
625- }
626- ast:: ConstructorType :: PartialVector { size } => Constructor :: PartialVector { size } ,
627- ast:: ConstructorType :: Vector { size, ty, ty_span } => {
628- let ty = self . resolve_ast_type ( ty, & mut ctx. as_const ( ) ) ?;
629- let scalar = match ctx. module . types [ ty] . inner {
630- crate :: TypeInner :: Scalar ( sc) => sc,
631- _ => return Err ( Box :: new ( Error :: UnknownScalarType ( ty_span) ) ) ,
632- } ;
633- let ty = ctx. ensure_type_exists ( crate :: TypeInner :: Vector { size, scalar } ) ;
634- Constructor :: Type ( ty)
635- }
636- ast:: ConstructorType :: PartialMatrix { columns, rows } => {
637- Constructor :: PartialMatrix { columns, rows }
638- }
639- ast:: ConstructorType :: Matrix {
640- rows,
641- columns,
642- ty,
643- ty_span,
644- } => {
645- let ty = self . resolve_ast_type ( ty, & mut ctx. as_const ( ) ) ?;
646- let scalar = match ctx. module . types [ ty] . inner {
647- crate :: TypeInner :: Scalar ( sc) => sc,
648- _ => return Err ( Box :: new ( Error :: UnknownScalarType ( ty_span) ) ) ,
649- } ;
650- let ty = match scalar. kind {
651- crate :: ScalarKind :: Float => ctx. ensure_type_exists ( crate :: TypeInner :: Matrix {
652- columns,
653- rows,
654- scalar,
655- } ) ,
656- _ => return Err ( Box :: new ( Error :: BadMatrixScalarKind ( ty_span, scalar) ) ) ,
657- } ;
658- Constructor :: Type ( ty)
659- }
660- ast:: ConstructorType :: PartialCooperativeMatrix { .. } => {
661- return Err ( Box :: new ( Error :: UnderspecifiedCooperativeMatrix ) ) ;
662- }
663- ast:: ConstructorType :: CooperativeMatrix {
664- rows,
665- columns,
666- ty,
667- ty_span,
668- role,
669- } => {
670- let ty = self . resolve_ast_type ( ty, & mut ctx. as_const ( ) ) ?;
671- let scalar = match ctx. module . types [ ty] . inner {
672- crate :: TypeInner :: Scalar ( s) => s,
673- _ => return Err ( Box :: new ( Error :: UnsupportedCooperativeScalar ( ty_span) ) ) ,
674- } ;
675- let ty = ctx. ensure_type_exists ( crate :: TypeInner :: CooperativeMatrix {
676- columns,
677- rows,
678- scalar,
679- role,
680- } ) ;
681- Constructor :: Type ( ty)
682- }
683- ast:: ConstructorType :: PartialArray => Constructor :: PartialArray ,
684- ast:: ConstructorType :: Array { base, size } => {
685- let base = self . resolve_ast_type ( base, & mut ctx. as_const ( ) ) ?;
686- let size = self . array_size ( size, & mut ctx. as_const ( ) ) ?;
687-
688- ctx. layouter . update ( ctx. module . to_ctx ( ) ) . unwrap ( ) ;
689- let stride = ctx. layouter [ base] . to_stride ( ) ;
690-
691- let ty = ctx. ensure_type_exists ( crate :: TypeInner :: Array { base, size, stride } ) ;
692- Constructor :: Type ( ty)
693- }
694- ast:: ConstructorType :: Type ( ty) => Constructor :: Type ( ty) ,
695- } ;
696-
697- Ok ( handle)
698- }
699596}
0 commit comments