Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[naga] Disallow logical operators && and || on vectors #7368

Open
wants to merge 1 commit into
base: trunk
Choose a base branch
from

Conversation

andyleiserson
Copy link
Contributor

@andyleiserson andyleiserson commented Mar 18, 2025

Connections
Fixes #6856

Description
This change disallows the logical operators && and || on vectors, which WGSL does not allow. There are two relevant codepaths, one for constant evaluation and one for type checking of expressions to be evaluated at runtime.

I tested this change locally in combination with #7339. The two changes actually do not conflict and interact minimally. In #7339, I implemented a transformation while lowering to IR that gets applied only if the operands have a correct (scalar) type. If the operands are not scalars, the expression is passed through with the expectation that validation rejects it. This change affects what will ultimately pass validation.

Arguably, these operators should be removed from the Naga IR entirely. I have not done that, because the BinaryOperator enum is shared by the AST and IR representations.

Testing
Added tests in wgsl_errors to verify both operators are rejected in both const and runtime contexts.

Squash or Rebase? Squash

Checklist

  • Run cargo fmt.
  • Run taplo format.
  • Run cargo clippy --tests. If applicable, add:
    • --target wasm32-unknown-unknown
  • Run cargo xtask test to run tests.
  • Add a CHANGELOG.md entry.

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR updates the operator handling to disallow the use of logical operators (&& and ||) on vectors according to WGSL specifications.

  • Enforces scalar-only operands for && and || in the type-checking phase.
  • Updates constant evaluation to immediately error out on vector operands.
  • Adds tests and updates the changelog to validate and document these restrictions.

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
naga/tests/wgsl_errors.rs Added tests to verify error handling for logical operators on vectors
naga/src/proc/typifier.rs Revised type-checking to permit only scalar operands for logical ops
naga/src/proc/constant_evaluator.rs Adjusted constant evaluation to error on unsupported vector usage
CHANGELOG.md Documented removal of logical operators on vectors

@cwfitzgerald
Copy link
Member

Imma try this "review by copilot" thing, we'll see how it does

Copy link
Member

@cwfitzgerald cwfitzgerald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One non-blocking question

"fn foo(a: vec2<bool>, b: vec2<bool>) {
let y = a || b;
}",
r#"error: Incompatible operands: LogicalOr(Vector { size: Bi, scalar: Scalar { kind: Bool, width: 1 } }, _)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this currently the best we can do with the current infra? @jimblandy did you do a thing wrt this, or am I misremembering.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not spend a lot of time digging into it, other than checking that there do appear to be many places in typifier.rs where we generate errors by formatting some piece of IR state with {:?} and calling it a day. The kind of error reporting that @jimblandy is adding with the function database (analyzing the overloads and saying things like "the supplied type A of argument X is not compatible with the supplied type B for argument Y") would be useful here, but I don't think it's going to be possible to drop in for operator overloads.

I'm not sure there's a clearly delineated scope to be file an issue for this, but if you'd like me to I can think on it. Having a bunch of our not-great error messages memorialized in the wgsl_errors test may come in handy, since we can just read through it and pick out the ones that we want to make better.

Comment on lines +616 to +618
return Err(ResolveError::IncompatibleOperands(format!(
"{op:?}({ty:?}, _)"
)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that the overload database has landed, see if you can't use common::ForDebugWithTypes::for_debug to get a nicer string out of this. I think it might be as simple as:

Suggested change
return Err(ResolveError::IncompatibleOperands(format!(
"{op:?}({ty:?}, _)"
)));
return Err(ResolveError::IncompatibleOperands(format!(
"{op:?}({:?}, _)",
ty.for_debug(types),
)));

Copy link
Member

@jimblandy jimblandy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Give for_debug a try, but otherwise this looks good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Naga wgsl-in allows vecN<bool> && vecN<bool> (with 2 &s) but Chromium/dawn doesn't
4 participants