Fix string method dispatch misrouting to effects by value content#33
Merged
Conversation
Method calls on a string literal whose content began with an
effect/capability name (Net, Fs, Console, Clock, Rand, Env, Map, Set)
were misrouted to that effect, throwing at runtime (E4004/E4006) even
though `astra check` reported no errors. Root cause: effect namespaces
and ordinary strings shared the `Value::Text` representation, and
`call_method` decided "is this an effect?" by inspecting the string's
content (`name.starts_with("Net")`), so e.g. `"Netback".to_lower()`
dispatched to the Net effect.
Give effect namespaces a distinct `Value::Effect(String)` variant so
method dispatch keys off the receiver's type, never its string value.
Effect identifiers evaluate to `Value::Effect`; `call_method` reaches an
effect handler only for `Value::Effect` receivers, matching the exact
name. Every other receiver (including all `Value::Text`) resolves by
type via `call_value_method`.
Adds regression tests covering every string method, every effect name as
a string prefix, exact-match strings, the previously-passing cases, and
confirmation that real effect identifiers still dispatch. Documents the
decision in ADR-008.
Also fixes 6 pre-existing clippy lints (sort_by_key, collapsible match
guards in lsp/typechecker) so the pre-commit hook passes without bypass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Calling a method on a string literal whose content began with an effect/capability name (
Net,Fs,Console,Clock,Rand,Env,Map,Set) misrouted the call to that effect, throwing at runtime (E4004/E4006) — even thoughastra checkreported no errors.Root cause
Effect namespaces and ordinary strings shared the
Value::Textrepresentation.call_methoddecided "is this an effect?" by inspecting the string's content (name.starts_with("Net")), so anyTextvalue spelling an effect name got hijacked.Fix
New
Value::Effect(String)variant so method dispatch keys off the receiver's type, never its string value. Effect identifiers evaluate toValue::Effect;call_methodreaches an effect handler only forValue::Effectreceivers (exact-name match). Every other receiver — including allValue::Text— resolves by type viacall_value_method.Tests
Also
ADR-008.sort_by_key, collapsible match guards in lsp/typechecker) so pre-commit passes without--no-verify.🤖 Generated with Claude Code