diff --git a/src/front/glsl/context.rs b/src/front/glsl/context.rs index 781c9c7677..5675775dba 100644 --- a/src/front/glsl/context.rs +++ b/src/front/glsl/context.rs @@ -1279,6 +1279,25 @@ impl Context { Ok(()) } + pub fn forced_conversion( + &mut self, + parser: &Parser, + expr: &mut Handle, + meta: Span, + kind: ScalarKind, + width: crate::Bytes, + ) -> Result<()> { + if let Some((expr_scalar_kind, expr_width)) = + self.expr_scalar_components(parser, *expr, meta)? + { + if expr_scalar_kind != kind || expr_width != width { + self.conversion(expr, meta, kind, width)?; + } + } + + Ok(()) + } + pub fn binary_implicit_conversion( &mut self, parser: &Parser, diff --git a/src/front/glsl/functions.rs b/src/front/glsl/functions.rs index a6dd97e999..5989a8bbd9 100644 --- a/src/front/glsl/functions.rs +++ b/src/front/glsl/functions.rs @@ -113,7 +113,7 @@ impl Parser { Ok(match self.module.types[ty].inner { TypeInner::Vector { size, kind, width } if vector_size.is_none() => { - ctx.implicit_conversion(self, &mut value, meta, kind, width)?; + ctx.forced_conversion(self, &mut value, expr_meta, kind, width)?; if let TypeInner::Scalar { .. } = *self.resolve_type(ctx, value, expr_meta)? { ctx.add_expression(Expression::Splat { size, value }, meta, body) @@ -256,7 +256,7 @@ impl Parser { // `Expression::As` doesn't support matrix width // casts so we need to do some extra work for casts - ctx.implicit_conversion(self, &mut value, expr_meta, ScalarKind::Float, width)?; + ctx.forced_conversion(self, &mut value, expr_meta, ScalarKind::Float, width)?; match *self.resolve_type(ctx, value, expr_meta)? { TypeInner::Scalar { .. } => { // If a matrix is constructed with a single scalar value, then that @@ -446,7 +446,7 @@ impl Parser { let mut components = Vec::with_capacity(size as usize); for (mut arg, expr_meta) in args.iter().copied() { - ctx.implicit_conversion(self, &mut arg, expr_meta, kind, width)?; + ctx.forced_conversion(self, &mut arg, expr_meta, kind, width)?; if components.len() >= size as usize { break; @@ -512,10 +512,7 @@ impl Parser { let mut flattened = Vec::with_capacity(columns as usize * rows as usize); for (mut arg, meta) in args.iter().copied() { - let scalar_components = scalar_components(&self.module.types[ty].inner); - if let Some((kind, width)) = scalar_components { - ctx.implicit_conversion(self, &mut arg, meta, kind, width)?; - } + ctx.forced_conversion(self, &mut arg, meta, ScalarKind::Float, width)?; match *self.resolve_type(ctx, arg, meta)? { TypeInner::Vector { size, .. } => { diff --git a/tests/in/glsl/expressions.frag b/tests/in/glsl/expressions.frag index 66a5c0f252..777b0b973a 100644 --- a/tests/in/glsl/expressions.frag +++ b/tests/in/glsl/expressions.frag @@ -113,6 +113,11 @@ void testFreestandingConstructor() { vec4(1.0); } +void testNonImplicitCastVectorCast() { + uint a = 1; + ivec4 b = ivec4(a); +} + float global; void privatePointer(inout float a) {} diff --git a/tests/out/wgsl/expressions-frag.wgsl b/tests/out/wgsl/expressions-frag.wgsl index f487aae834..7853803e1c 100644 --- a/tests/out/wgsl/expressions-frag.wgsl +++ b/tests/out/wgsl/expressions-frag.wgsl @@ -286,7 +286,16 @@ fn testFreestandingConstructor() { return; } -fn privatePointer(a_18: ptr) { +fn testNonImplicitCastVectorCast() { + var a_18: u32 = 1u; + var b_16: vec4; + + let _e3 = a_18; + b_16 = vec4(i32(_e3)); + return; +} + +fn privatePointer(a_19: ptr) { return; }