규칙 7.9
7장, 표현식과 문 테스트
An expression must be evaluated left to right, as TypeScript and WGSL both evaluate it, and a call that writes (its object, a module variable, a storage binding, an atomic location) inside a larger expression must take effect in that order on every target.
The compiler binds each such call to a temporary ahead of its statement, in source order, and binds ahead of the call an operand evaluated before it that reads what it writes; a call TypeScript evaluates conditionally, in an arm of ?: or the right operand of && or ||, keeps its condition as an if.
A call that takes a reference (Rule 8.25) is a call that writes each place it is handed, and ref(place) is a place and not a read: a call that writes a variable, in an argument after ref of that variable, runs ahead of the call that takes the reference, which then reads the variable as the call that wrote it left it.
A loop condition runs on every iteration, so it may hold such a call only as one side of its comparison.
규칙 본문과 그 아래 항목은 설계 문서에 적힌 컴파일러 원문이라 한국어 페이지에서도 영어로 둡니다.
근거
GLSL ES 3.00 leaves the order of an operator’s operands open, and a scalar ?: lowers to WGSL’s select, which evaluates both arms, so the one order every target keeps is the order the compiler writes out; the passes that fold and repeat expressions then see no call that writes inside one.
출처
- Program Order Within an Invocation (“The order of evaluation for operands of an expression is left-to-right in WGSL. For example, foo() + bar() must evaluate foo() before bar().”);
- Function Calls (“Function call argument values are evaluated. The relative order of evaluation is left-to-right.”);
- GLSL ES 3.00 §5.11, which relaxes C++‘s rules and fixes no order for an operator’s operands, §6.1.1 (“All arguments are evaluated at call time, exactly once, in order, from left to right”), and §5.8 (“Expressions on the left of an assignment are evaluated before expressions on the right of the assignment”);
- surface §19 and §26.
검증 방식
테스트로 확인합니다. 테스트나 게이트 스크립트, CI 워크플로가 이 규칙을 가리키고, 아래 파일 가운데 하나라도 규칙을 더는 가리키지 않으면 추적 검사가 실패합니다.
컴파일러가 이 규칙을 적용하는 곳을 규칙이 직접 적은 내용입니다.
src/compiler/ts/sequence.ts (sequenceEffects), pinned by src/compiler/ts/sequence.test.ts, which holds the CPU oracle, the codegen and the debugger to the source order; TS8006 LOOP_BOUND for a loop condition that holds a call that writes anywhere but as one side of its comparison (A while condition runs "rng.next()" on every iteration, and a call that writes can stand there only as one side of the comparison. …); examples/rng-method.shade.ts in the compile gate.
커밋 c66579bf에서 이 규칙을 확인하는 파일입니다. 파일마다 규칙을 처음 가리키는 줄로 연결했습니다.
설명하는 절
커밋 c66579bf의 표면 문서에서 이 규칙을 설명하는 절입니다.
적용하는 오류 코드
규칙이 Enforced by 항목에서 가리키는 진단 코드와, 레지스트리 설명에서 이 규칙을 가리키는 진단 코드입니다.
-
TS8006LOOP_BOUND - 컴파일러가 종료를 증명할 수 없는
for루프입니다. 카운터를 경계와 비교하지 않거나, 본문이 경계를 씁니다.
함께 보기
소스
커밋 c66579bf의 규칙 원문:
docs/language-design.md:592(설계 문서)reqs/rules/RULE-0709.md(추적 항목)