For private `define-values` in classes with multiple variables, don't
eagerly throw type errors in the synthesis step. Instead, wait
until the later checking step when the environment will be correctly
set up.
When the initial synthesis typecheck fails, yield type Any for
the environment. If the typecheck should really fail, this is ok. If
not, then the user can add a type annotation.
A better long-term strategy is to change the handling of environments
so that the type environment gets refined as definitions are checked.
This way all annotations that the user writes are factored into the
initial environment and unannotated variables will have their types
synthesized.
Most unit forms are supported, including most of the "infer" forms that
infer imports/exports/linkages from the current context.
Notably, none of the structural linking forms for units are supported, and
`define-unit-binding` is also currently unsupported.
Only parse and use the type annotations if they are present on
all fold variables. This matches the default for other forms in TR.
Also, this will usually result in a "insufficient type information"
message which is more helpful than if TR chose some default type.
Closes PR 15138
Closes PR 14893
The `identifier-binding` function is now senstive to the "macro
introduction" scope that's on an indentifier provided to a currently
expanding macro. Unit tests for TR need to use
`syntax-local-intorduce` to remove it, in the same way that `tc-setup`
already does.
Also, recognize a class expansion when it's wrapped with
`#%expression`, since `class` now expands that way sometimes.
This patch addresses two issues with `typed/racket/class`:
1. For multiple private fields declared with `define-values`, type
information does not propagate from the values produced by the
initialization expression to the declared fields. This breaks soundness
of private fields: A field can be annotated with a type that does not
contain the field's initial value.
This was resolved by keeping a table of temporary bindings introduced in
the expansion of the initializer along with their types. The field
setter's type is then checked against that of the corresponding
temporary.
2. The class body typechecker assumes that the `expr` of
a `define-values` clause will expand to a bare `(values vs ...)`.
This was resolved by generalizing the template for matching an expanded
`define-values` initializer and extracting the type information from the
`expr` instead of each element in `(vs ...)`.
Previously the restriction didn't account for traversing
the object type with the given path. This also relies on
the previous commit that adds subtyping on filters.
(because this change seems to introduce filters which
only differ by an unrolling of a recursive type, but
the old subtyping only worked for identical types)
This makes a type like
(-> Any Boolean : #:+ Integer)
a subtype of a type like
(-> Any Boolean : #:+ Number)
For not filters, the direction is reversed.