Skip to content

Commit 88fa2bb

Browse files
fix(naga): properly impl. auto. type conv. for select
1 parent 35f054b commit 88fa2bb

File tree

2 files changed

+89
-2
lines changed

2 files changed

+89
-2
lines changed

naga/src/front/wgsl/error.rs

+28
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,16 @@ pub(crate) enum Error<'a> {
399399
on_what: DiagnosticAttributeNotSupportedPosition,
400400
spans: Vec<Span>,
401401
},
402+
SelectUnexpectedArgumentType {
403+
arg_span: Span,
404+
arg_type: String,
405+
},
406+
SelectRejectAndAcceptHaveNoCommonType {
407+
reject_span: Span,
408+
reject_type: String,
409+
accept_span: Span,
410+
accept_type: String,
411+
},
402412
}
403413

404414
impl From<ConflictingDiagnosticRuleError> for Error<'_> {
@@ -1340,6 +1350,24 @@ impl<'a> Error<'a> {
13401350
],
13411351
}
13421352
}
1353+
Error::SelectUnexpectedArgumentType { arg_span, ref arg_type } => ParseError {
1354+
message: "unexpected argument type for `select` call".into(),
1355+
labels: vec![(arg_span, format!("this value of type {arg_type}").into())],
1356+
notes: vec!["expected a scalar or a `vecN` of scalars".into()],
1357+
},
1358+
Error::SelectRejectAndAcceptHaveNoCommonType {
1359+
reject_span,
1360+
ref reject_type,
1361+
accept_span,
1362+
ref accept_type,
1363+
} => ParseError {
1364+
message: "type mismatch for reject and accept values in `select` call".into(),
1365+
labels: vec![
1366+
(reject_span, format!("reject value of type {reject_type}").into()),
1367+
(accept_span, format!("accept value of type {accept_type}").into()),
1368+
],
1369+
notes: vec![],
1370+
},
13431371
}
13441372
}
13451373
}

naga/src/front/wgsl/lower/mod.rs

+61-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use alloc::{
22
borrow::ToOwned,
33
boxed::Box,
4+
format,
45
string::{String, ToString},
56
vec::Vec,
67
};
@@ -2483,12 +2484,70 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
24832484
"select" => {
24842485
let mut args = ctx.prepare_args(arguments, 3, span);
24852486

2486-
let reject = self.expression(args.next()?, ctx)?;
2487-
let accept = self.expression(args.next()?, ctx)?;
2487+
let reject_orig = args.next()?;
2488+
let accept_orig = args.next()?;
2489+
let mut values = [
2490+
self.expression_for_abstract(reject_orig, ctx)?,
2491+
self.expression_for_abstract(accept_orig, ctx)?,
2492+
];
24882493
let condition = self.expression(args.next()?, ctx)?;
24892494

24902495
args.finish()?;
24912496

2497+
fn expr_ty<'a>(
2498+
ctx: &'a ExpressionContext<'_, '_, '_>,
2499+
expr: Handle<ir::Expression>,
2500+
) -> &'a ir::TypeInner {
2501+
ctx.typifier()[expr].inner_with(&ctx.module.types)
2502+
}
2503+
let diag_deets =
2504+
|module: &ir::Module, ty: &ir::TypeInner, orig_expr| {
2505+
(
2506+
ctx.ast_expressions.get_span(orig_expr),
2507+
format!("`{:?}`", ty.for_debug(&module.types)),
2508+
)
2509+
};
2510+
for (&value, orig_value) in
2511+
values.iter().zip([reject_orig, accept_orig])
2512+
{
2513+
ctx.grow_types(value)?;
2514+
2515+
let value_type = expr_ty(ctx, value);
2516+
if value_type.vector_size_and_scalar().is_none() {
2517+
let (arg_span, arg_type) =
2518+
diag_deets(ctx.module, value_type, orig_value);
2519+
return Err(Box::new(Error::SelectUnexpectedArgumentType {
2520+
arg_span,
2521+
arg_type,
2522+
}));
2523+
}
2524+
}
2525+
let mut consensus_scalar = ctx
2526+
.automatic_conversion_consensus(&values)
2527+
.map_err(|_idx| {
2528+
let [reject, accept] = values;
2529+
let [(reject_span, reject_type), (accept_span, accept_type)] =
2530+
[(reject_orig, reject), (accept_orig, accept)].map(
2531+
|(orig_expr, expr)| {
2532+
let ty = expr_ty(ctx, expr);
2533+
diag_deets(ctx.module, ty, orig_expr)
2534+
},
2535+
);
2536+
Error::SelectRejectAndAcceptHaveNoCommonType {
2537+
reject_span,
2538+
reject_type,
2539+
accept_span,
2540+
accept_type,
2541+
}
2542+
})?;
2543+
if !ctx.is_const(condition) {
2544+
consensus_scalar = consensus_scalar.concretize();
2545+
}
2546+
2547+
ctx.convert_slice_to_common_leaf_scalar(&mut values, consensus_scalar)?;
2548+
2549+
let [reject, accept] = values;
2550+
24922551
ir::Expression::Select {
24932552
reject,
24942553
accept,

0 commit comments

Comments
 (0)