fix(cfc): generic variable type resolution - #1840
Open
volsa wants to merge 6 commits into
Open
Conversation
Build Artifacts🐧 Linux
From workflow run 🪟 Windows
From workflow run |
An unresolved generic like a CFC temporary still typed `__ADD__T` is registered with the `Any` nature, so `get_bigger_type` saw it as both numerical and real and promoted its pairing with any integer to REAL: a builtin ADD/MUL/SUB/DIV feedback loop over DINT silently became floating point (plus a spurious E067 downcast warning). The generic side now always loses to the concrete side, which alone carries a size and class. Covered by a typesystem unit test, a `variadic_feedback` transpile snapshot, and an `add_feedback` lit test accumulating past 2^24 where a REAL regression fails numerically. Also locks the mixed fixed/variadic pin emission with a `mux_call` snapshot. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
derive_generic_types seeded its bigger-type fold with the nature's smallest possible type, so a binding whose candidates were all still unresolved generics — a CFC temporary fed only by its own feedback loop — fell back to that seed: `T: ANY_NUM` silently became USINT and the accumulator wrapped at 255. Unresolved generics no longer vote at all, and with no concrete candidate the binding now stays open, so the call keeps its generic return type and the temporary reports as E149. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The hand-made generic fixtures used `bmx:TextDeclaration` without declaring the prefix, which the compiler's namespace-agnostic reader accepts but a conforming XML parser — the IDE import — rejects. Declare `xmlns:bmx` on the root element like the pristine exports do. Co-Authored-By: Claude Fable 5 <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: The CFC implementation for stateless functions creates "temporary" variables for their return and output variable values. For example
bar := foo(in := localIn, acc => localOut)wherefooreturns aDINTvalue will transpile toHowever, for generics this is a bit tricker because generic type resolution requires first a call site bevore its types can be derived. As such the transpiler up until now generated the following for the same
fooexample assuming now both the return and output values are a generic of typeT: ANY_NUM:These "generic variables" never resolved and yielded an error when compiling.
Solution: Introduce an "inference" module, which uses the existing
TypeAnnotatorresponsible for generic type resolution. In a loop then incrementally patch these generic variables to their concrete type if the annotator has enough information to do so. Repeat until exhausted.Note: Strictly speaking this is not type inference, rather its an extension of the generic type resolver but specific for variables for CFC's use-case. A much nicer implementation would have been type inference using something similar to the "Hindley–Milner type system" algorithm also used in e.g. rustc. Thats a bigger architectural change however.