Conversation
Introduce TYPE_UNKNOWN constant in compiler/common.casa, both bound to the string "any". All compiler-internal sentinel uses (stack underflow placeholder, types_match, unify_type, bind_type_var, is_type_variable, bind_fn_param, check_push_var, type_satisfies_trait, check_method_call, signature_matches, and related helpers) now reference TYPE_UNKNOWN. ANY_TYPE remains as a string-equal alias for the duration of the migration so user-visible "any" keyword behaviour is unchanged. Part of #147
Declare Eq (eq required, ne default), Ord (lt required, le/gt/ge defaults derived from lt), and Word (empty marker) in lib/std.casa. Display already existed and is left in place. Eq impls: int (already had), bool, char, str (already had), cstr, ptr. Ord impls: int, char. Lexicographic str comparison is intentionally out of scope. Word is satisfied structurally by every type today; bound enforcement for single-slot-only types lands with US-008. Part of #147
- Add CasaTrait.supertraits: List[TraitBound] and parser support for trait Sub: Super (+ Super2) syntax - collect_trait_methods walks trait + transitive supertraits - build_hidden_trait_methods, inject_trait_fn_ptrs, type_satisfies_trait, simulate_trait_exec, check_method_call, check_abstract_methods_present all use the expanded list so K::eq dispatches via Eq supertrait - lib/std.casa: trait Hashable: Eq removes duplicated eq method - Fix double-decrement bug in inject_trait_fn_ptrs verify loop that silently skipped the method after a default in the iteration order Closes #150
Surface signature switches from `any -> str` to the explicit generic form `[T] T -> str`. Behaviour is unchanged: typeof pops a value of any type and prints its static type name. The check_typeof body already reads the popped slot's concrete type for the bytecode annotation, so no functional changes were needed there. Updated: - LSP hover string for OpValue::Typeof - docs/intrinsics.md `typeof` signature - tests/compiler/test_typeof.casa: added typecheck and bytecode coverage for typeof on array literals. Part of #147
Migration: drop the cast (the binding annotation already provides the type) or write the concrete type instead.
Replace `any`-based hover strings for drop/dup/swap/over/rot with
explicit `[T]` / `[T1 T2]` / `[T1 T2 T3]` generic surface forms in
LSP, intrinsics docs, and functions-and-lambdas docs. The typechecker
side was already polymorphic — `check_stack_ops` pops/pushes the
actual stack types — so the compiler change is hover-only. Adds a
polymorphic stack-shaped `keep_top[T1 T2] T1 T2 -> T1 { swap drop }`
example with two type instantiations, plus LSP hover tests for over
and rot.
Closes #151
Replace `any` value-type slots in store8/16/32/64 and syscall1..6 with a `Word` marker-trait bound. `check_memory` and `check_syscalls` now thread `function_opt` through and validate each popped value/arg type via `assert_word_bound`. Concrete types are accepted (every single-slot value satisfies `Word` today); type variables without an explicit bound are deferred to the call site; type variables whose declared bound does not extend `Word` are rejected with a clear migration message. Hashable and Display now extend `Word` as supertraits so existing stdlib generics (`Map[K V]` with `K: Hashable`, `Display` impls) keep compiling unchanged. Adds `bound_implies_word` to walk supertraits. LSP hover, intrinsics docs, traits docs, and the standard-library trait table reflect the new signatures. Closes #154
…tch fallback
- parse_type now raises a Syntax error for bare `any`; the redundant guard in get_op_type_cast is gone (parse_type covers casts too).
- Removed the ANY_TYPE constant alias and the `any` entries in is_builtin_type and the builtins set.
- Removed find_method_by_name and the TYPE_UNKNOWN-receiver fallback in check_method_call. Method dispatch on an unresolved type now produces a real "method not found" error.
- Removed the TYPE_UNKNOWN early-return in is_type_variable; the two call sites already guard against the sentinel.
- Replaced dot-method lambdas `{ .is_alpha }` etc. in lib/parser.casa and examples/parser.casa with explicit function references like `&char::is_alpha`, since those lambdas relied on the removed dispatch fallback.
- Test assertions and headers swapped from the literal "any" string to the TYPE_UNKNOWN constant.
- Docs pruned of `any` references; `fn[any -> str]` rewritten as `fn[T -> str]`, `drop: any -> None` as `drop: [T] T -> None`, etc.
Closes #158, #147.
Non-lambda functions previously synthesized an inferred parameter on stack underflow, masking real bugs. Now report STACK_UNDERFLOW once the declared parameter budget is consumed; lambdas still infer on demand. Cascaded slots are tagged with a `TYPE_ERROR` placeholder that `types_match` treats as a wildcard to prevent spurious follow-on diagnostics within the same op.
Stack underflow diagnostics now name the slot the operation needed instead of generic "expected a value": - Trait dispatch (`print`, `==`, `<`): "value with trait `T`" — was "trait `T`", which read as if the trait itself was on the stack. - Stack intrinsics (`drop`, `dup`, `swap`, `over`, `rot`): "value for `op`" or "argument N of `op`" with N counting from the top. Rename the cascade placeholder from `<error>` (TYPE_ERROR) to `<missing>` (TYPE_MISSING) so user-facing messages communicate "this slot was tainted by an earlier error, fix that first" rather than the internal sentinel. Document `STACK_UNDERFLOW` and the new `Cascade Errors` section in docs/errors.md. Cross-referenced from `TYPE_MISMATCH` so a user seeing `got <missing>` knows to look upstream.
Replace the parse-time `any`-specific syntax error with a general type-existence check at the TypeCast op in run_type_check_ops. The validator covers builtins, registered structs/enums, declared signature type variables, parameterized types (recurses into params), and `fn` types. Unknown identifiers — `foo`, single-letter `T` outside a generic function, or nested unknowns like `List[Foo]` — now raise a uniform `type \`X\` does not exist` syntax error.
Skip the main-source intermediate compile so the workflow accepts syntax not yet on main (supertraits in lib/std.casa). Restore the two-stage flow after merge.
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.
Summary
Replaces the
anywildcard type with generics + trait bounds (Eq, Ord, Display, Word) end-to-end. After this branch, theanykeyword is rejected at parse time, theANY_TYPEconstant is gone, and the method-dispatch fallback for unknown receivers is replaced by a real "method not found" error.Eleven slices, each behind a green CI pin (casafmt, self-host fixed point, full compiler+example test suites):
typeofto[T] T -> str#155 — US-004: typeof retyped to[T] T -> str[]literal: lazy element-type inference, error if unresolved #156 — US-005: empty[]literal lazy element-type inference(any)cast at parse time; migrate test_type_annotations.casa #157 — US-006: reject(any)cast at parse time[T]generics[T: Word]#154 — US-008: store* / syscall* migrated to[T: Word]printto[T: Display]constraint #152 — US-009: print migrated to[T: Display][T: Eq]and comparison ops to[T: Ord]#153 — US-010: ==/!= bounded by[T: Eq], ordering bounded by[T: Ord]anykeyword, ANY_TYPE alias, and method-dispatch fallback #158 — US-011: deleteanykeyword, ANY_TYPE alias, and method-dispatch fallbackPart of #147.
Follow-up: error message polish
After the trait migration exposed terser diagnostics, two follow-up commits clean up the underflow path:
value with trait \Display`,argument 1 of `rot``) instead of the generic "expected a value"<error>→<missing>so user-facing text reads "earlier error tainted this slot"STACK_UNDERFLOWandCascade Errorssections indocs/errors.mdTest plan
./casafmtclean on all changed.casafiles./casac → stage1 → stage2 → stage3,cmp stage2.s stage3.sidenticaltests/test_compiler.sh < /dev/null— 27 suites pass (incl. newtest_underflow_messages)tests/test_examples.sh— 40 examples passrg '\bany\b' compiler/ lib/returns only the rejection check insyntax.casa:211any