Skip to content

fix(typeck): reject non-path receivers for Vector/Mapping storage ops#29432

Merged
mohammadfawaz merged 1 commit into
masterfrom
fix/29428-ternary-storage-receiver
May 20, 2026
Merged

fix(typeck): reject non-path receivers for Vector/Mapping storage ops#29432
mohammadfawaz merged 1 commit into
masterfrom
fix/29428-ternary-storage-receiver

Conversation

@mohammadfawaz
Copy link
Copy Markdown
Collaborator

@mohammadfawaz mohammadfawaz commented May 19, 2026

Summary

  • Vector::{len,get,set,push,pop,swap_remove,clear} and Mapping::{get,get_or_use,contains,set,remove} assume an Expression::Path receiver downstream (storage_lowering for vectors, codegen for mappings), but type-checking only verified the receiver's type.
  • Read ops had no path check, so a ternary of two storage vectors ICEd in storage_lowering and a ternary of two mappings produced invalid bytecode that failed late at disassembly.
  • Write ops already had an is_local_path check, but emitted the "external vectors/mappings" diagnostic for a local ternary receiver, which is misleading.
  • Add an Expression::Path pre-check to all eleven arms and emit a new ETYC0372191. The existing "external" diagnostic now only fires when the receiver is an actual external path.

Fixes #29428.

@mohammadfawaz mohammadfawaz self-assigned this May 19, 2026
@mohammadfawaz mohammadfawaz added 🐛 bug Something isn't working 🧱 Core Compiler Anything related to the core compiler including parsing, analysis, transforms, codegen, etc. labels May 19, 2026
@mohammadfawaz mohammadfawaz requested a review from a team May 19, 2026 21:50
@mohammadfawaz mohammadfawaz force-pushed the fix/29428-ternary-storage-receiver branch from a7aaa5f to 960affc Compare May 19, 2026 21:56
@mohammadfawaz mohammadfawaz changed the title fix(typeck): reject non-path receivers for Vector/Mapping read ops fix(typeck): reject non-path receivers for Vector/Mapping storage ops May 19, 2026
Copy link
Copy Markdown
Collaborator

@mitchmindtree mitchmindtree left a comment

Choose a reason for hiding this comment

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

Left one optional suggestion, but lgtm! :shipit:

map_expr.span(),
));
return Type::Err;
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks like quite a few of these - I wonder we'd benefit from something like:

  /// Returns `true` if `expr` is a path receiver; otherwise emits a diagnostic and returns `false`.
  fn check_path_receiver(&self, module: &str, operation: &str, kind: &str, expr: &Expression) -> bool {
      if matches!(expr, Expression::Path(_)) {
          return true;
      }
      self.emit_err(crate::errors::type_checker::storage_op_requires_path_receiver(
          module, operation, kind, expr.span(),
      ));
      false
  }

Copy link
Copy Markdown
Collaborator Author

@mohammadfawaz mohammadfawaz May 20, 2026

Choose a reason for hiding this comment

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

Good call, done. Extracted into a check_path_receiver helper.

@mohammadfawaz mohammadfawaz force-pushed the fix/29428-ternary-storage-receiver branch 3 times, most recently from 5a98d21 to 8cc7db7 Compare May 20, 2026 19:00
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 20, 2026

Merging this PR will not alter performance

✅ 17 untouched benchmarks


Comparing fix/29428-ternary-storage-receiver (a9bc243) with master (33008b2)1

Open in CodSpeed

Footnotes

  1. No successful run was found on master (3a6eba3) during the generation of this report, so 33008b2 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

`Vector::{len,get,set,push,pop,swap_remove,clear}` and
`Mapping::{get,get_or_use,contains,set,remove}` assumed an
`Expression::Path` receiver downstream: storage_lowering for vectors,
codegen for mappings. Type-checking only verified the receiver's type.

- Read ops (`len`/`get`/`get_or_use`/`contains`) had no path check at
  all, so a ternary of two storage vectors ICEd in storage_lowering
  (#29428) and a ternary of two mappings produced invalid bytecode that
  failed late at disassembly.
- Write ops already had an `is_local_path` check, but emitted the
  "external vectors/mappings" diagnostic for a local ternary receiver,
  which is misleading.

Add an `Expression::Path` pre-check to all eleven arms and emit a new
`ETYC0372191` for non-path receivers. The existing
"external vectors/mappings" diagnostic now only fires when the receiver
is an actual external path, which is what its wording describes.

Fixes #29428.
@mohammadfawaz mohammadfawaz force-pushed the fix/29428-ternary-storage-receiver branch from 8cc7db7 to a9bc243 Compare May 20, 2026 19:17
@mohammadfawaz mohammadfawaz merged commit 3a5e20c into master May 20, 2026
7 checks passed
@mohammadfawaz mohammadfawaz deleted the fix/29428-ternary-storage-receiver branch May 20, 2026 19:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐛 bug Something isn't working 🧱 Core Compiler Anything related to the core compiler including parsing, analysis, transforms, codegen, etc.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] ICE with error message: error: internal compiler error: unexpected panic note: we would appreciate a bug report:

2 participants