added 1) -Wimplicit-rettype warning, 2) explicitly annotated most of the standard library#34
Merged
Conversation
Bootstraps the compiler's first non-fatal diagnostic path (seed for session-2's multiple-errors-per-run work) and adds an opt-in warning for module-level functions whose return type is left to inference -- a load-bearing viability filter in overload resolution (resolve-2 near-miss). - Ast.fx: compile_warning now counts into all_compile_warns (reset in init_all); the pre-existing unused-value/@parallel warnings fold in too. - Compiler.fx: end-of-run "N warning(s) generated" summary; under -Werror a nonzero count fails process_all's exit path. - Options.fx: -Wimplicit-rettype, -Wall (umbrella), -Werror. (options_t layout propagates into 9 bootstrap modules, as with print_resolve.) - Ast_typecheck.fx: the check fires once per source DefFun, detecting a missing annotation signature-level (fresh TypVar(ref None) captured before check_deffun resolves it) so it also covers generic templates, which are never body-checked at their definition site. Root modules only; exempts nested funcs, lambdas, @ccode, and auto-generated constructors. test/negative/220_implicit_rettype locks the message format + the -Werror promotion (new `// flags:` header in the T3 harness lets a warning case exercise the required nonzero exit). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… files) Explicit return types on every module-level function in the annotated stdlib scope -- all of lib/ except the application libraries NN/, Onnx/, Protobuf/, OpenCV.fx (Vadim's call). Method: the compiler is the oracle -- compile with -Wall, re-spell the inferred type it prints (only transform: strip the @NNN gensym), insert `): <type>` (tools/retann.py). A wrong annotation fails typecheck, so behavior cannot silently change; the -pr-resolve census guards overload resolution. 248 concrete inferred types inserted mechanically; 310 generics annotated by family convention (string->string, print->void, predicates->bool, size->int, pass-throughs-> the bound var, conversions-> fixed element type, numeric folds -> the type the body computes). Judgment cases (see docs/annotate2_report.md): the width-varying Builtins tuple-norms get a fresh scalar var ': 't3' (safe -- arg-pinned); floor/ceil/trunc/round return int (FB-019). Census unchanged: 351/344/7/0, (name|winner|outcome) multiset identical to the WP-1 baseline -- resolution-neutral. Bootstrap regen touches NO stdlib module (return annotations erase in K-form -> byte-identical C). test/negative/212 golden refreshed: the __negate__ candidate now prints 't [+] not <unknown>. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- tools/rettype_gate.sh: compile every in-scope stdlib file as a root with -Wall -Werror (-no-c, a few seconds), wired into ci.yml on the gcc leg beside the operator lint. The compiler-based gate supersedes lint_op_returns.py --funs, which false-positives on nested generics (Map.mem_) it cannot see; no parked-by-decision allowlist was needed. Compiler sources are NOT gated yet -- 340 functions for annotate-3. - docs/annotate2_report.md: scope decision, WP-1 design (root-only), family conventions, judgment cases, per-commit census verdicts, annotate-3 data. - found_bugs.md: FB-018 (Array.diag uses `a` before it is defined -> unusable, only errors on instantiation), FB-019 (floor/ceil/trunc/round return int, contra CLAUDE.md -- design question). - CLAUDE.md: -W flags + gate; return-annotation spellings ((void -> T), module-self-type, (int...), fresh-var norms); census location-normalization; corrected the floor/ceil note. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Revises WP-1's root-only scope. With stdlib now annotated, root-only under-warns: it misses the user's OWN non-root modules (e.g. running test_all.fx flagged only test_all.fx, not the imported test_oop.fx). The useful distinction is stdlib vs user code, not root vs imported. - Ast.fx: `ficus_std_path` (the <ficus_root>/lib dir), set in Compiler.process_all; a module is stdlib iff its path is under it. - Ast_typecheck.has_implicit_rettype: default scope = every USER module (path not under stdlib) -- the whole project transitively; `=all` also covers stdlib. - Options.fx: `-Wimplicit-rettype=all` flag (+ W_implicit_rettype_all). - rettype_gate.sh: switched to `-Wimplicit-rettype=all -Werror` (a stdlib file compiled as root is otherwise skipped, since it IS stdlib). Proven: with one stdlib annotation removed, plain -Wimplicit-rettype stays silent while =all flags it. Ladder green (136 tests, fxtest all, determinism, sanitize), fixpoint holds, census 351/344/7/0 unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The inferred type in the warning is meant to be copy-pasted, but typ2str
appends `@NN` gensym suffixes to module-qualified type names
(`test_oop.IClone@22`, `(bool, Date.t@11)`). Strip them with a regex --
`Re.replace(Re.compile("@[0-9]+"), s, "")` -- which correctly handles
compound types (a single truncate at the first '@' would drop the trailing
`)`). This makes the compiler depend on Re (tiny wrapper over the runtime
regex; +one bootstrap module Re.c). CLAUDE.md: prefer String.fx/Re.fx over
hand-rolled string loops. Fixpoint holds; full ladder green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cleans test/ under the new user-code default scope (which covers a test
module and its imported user helpers). ~30 functions: interface methods
(`fun Rect.name(): string`), operator overloads, and the resolution-edge-case
helpers. CplxHelper's mixed operators get the fresh-var `'t3 cplx` (matching
Complex.fx); test_resolve still runs with 0 failures, so the annotations did
not perturb what it exercises. Includes Vadim's test_all.fx annotation.
retann.py: broadened DECL_RE to match methods (`fun T.m(`) and operators, with
a capture group so scan_decls lands on the parameter '(' (not a later one in
the body); get_warnings now filters to the file being processed (the default
scope emits warnings for imported user modules too).
rettype_gate.sh: added a test-suite leg. It greps for the warning instead of
using -Werror, since test files legitimately trip an unused-local warning and
a couple do not compile standalone (test_gencmp needs -I compiler; test_re2
has an unrelated pre-existing error).
fxtest all + test_resolve(0 fails) + full gate green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
An unused variant-case constructor (e.g. `B` of a locally-declared
`type ('a,'b) ct = A | B | C` in test_basic.fx) tripped the "local function
'B' is declared but not used" warning. It is compiler-generated, not a
function the user wrote, so the warning is noise. Skip it when
is_constructor(kf_flags) holds; genuine unused local functions still warn.
Fixpoint holds; full ladder green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rrbvec, Dynvec.t ...)
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.
What & why
Extends annotate-1 (return annotations on all 106 generic stdlib operators)
to functions, and adds the compiler's first non-fatal warning subsystem.
A generic function's return annotation is a load-bearing viability filter in
overload resolution (the resolve-2 near-miss: a free return type unifies with
any expected type and lets a candidate invade foreign contexts). Explicit
signatures are also the firewall for future type-error recovery, LSP, and
interface-only compilation. Design:
docs/language_changes_brief.md§1.7;full write-up:
docs/annotate2_report.md.WP-1 — warning subsystem +
-Wimplicit-rettypecompile_warningis now counted; the driver prints an end-of-runN warning(s) generatedsummary, and-Werrorfolds a nonzero count into afailing exit. Seed for session-2's multiple-errors-per-run work.
-Wimplicit-rettype,-Wimplicit-rettype=all,-Wall,-Werror.DefFun, detecting a missing annotation at thesignature level (a fresh
TypVar(ref None)captured before typechecking),so it covers generic templates too. Exempts nested funcs, lambdas,
@ccode, and auto-generated constructors.<ficus_root>/lib) —a whole multi-file project, not just the file on the command line;
=allalso covers stdlib (how the stdlib self-gates).WP-2 — the sweep (559 functions, 24 stdlib files)
Every module-level function in
lib/except the application libraries NN/,Onnx/, Protobuf/,
OpenCV.fxnow spells its return type. Method: the compileris the oracle (
tools/retann.py— read the inferred type the warning prints,re-spell it, insert
): <type>); a wrong annotation fails typecheck, so behaviorcan't silently change.
Resolution-neutral:
-pr-resolvecensus overcompiler/fx.fxstays351/344/7/0 with the (name|winner|outcome) multiset identical to the WP-1
baseline. Return annotations erase in K-form → the bootstrap regen touched no
stdlib module (byte-identical generated C).
WP-3 — CI gate
tools/rettype_gate.sh(gcc/ubuntu leg) gates the annotated stdlib(
-Wimplicit-rettype=all -Werror) and the test suite. Supersedeslint_op_returns.py --funs(which false-positives on nested generics likeMap.mem_); the operator lint stays as a separate guard. Compiler sources arenot gated yet — 340 functions for a future annotate-3.
Also in this PR
test/cleaned & gated (~30 fns: interface methods, operators, resolutionhelpers).
test_resolvestill passes with 0 failures.@NNgensyms stripped from the warning's inferred type (copy-paste fix),via
Re.replace— the compiler now depends onRe(+1 tiny bootstrap module).K_remove_unused: no longer warns about an unused auto-generatedconstructor (e.g. a variant case) — only explicit local functions warn.
Verification
make && test_all(136 pass) ·fxtest all·determinism·sanitize·bootstrap fixpoint holds · census unchanged. Fenced findings for review:
FB-018 (
Array.diag(d:'t[])usesabefore it's defined), FB-019(
floor/ceil/trunc/roundreturnint, contra CLAUDE.md — design question).