A package function that destructures its options object, such as
makeClass({ Base, name }), now specializes per call site like positional
parameters: each destructured name binds the static type of the matching
property, so a class passed as { Base } keeps its static type and
class extends Base builds a constructible subclass.
Fixes#938
Co-authored-by: phall <25888173+phall1@users.noreply.github.com>
The shard balance check needs measured costs for at least 90% of the
corpus programs. Add plain and sanitized costs for 5970, 5971 and 5972,
timed locally and scaled to the CI runner by comparable net programs.
After socket.setEncoding("utf8"), Node passes strings to 'data'
listeners, while @types/node types the chunk as a Buffer. An inline
listener whose chunk is typed Buffer (annotated or inferred) received a
Buffer. When a program can call setEncoding on a socket, such listeners
now take the chunk as a checked dynamic value, so console.log, typeof,
string methods and concatenation behave as in Node, and Buffer-only
methods throw Node's TypeError. Programs without setEncoding on a socket
compile to the same IR as before.
Chunks from net sockets (including socket.read()), http messages and
upgrade heads, child_process output, dgram messages, http2 streams and
TLS sessions were byte arrays without the Buffer brand. String
conversion of them joined the byte values ("112,105,110,103") instead
of decoding UTF-8, so `body += chunk` and template literals differed
from Node. They are now Buffers, as in Node.
Closes#903
Co-authored-by: João Carlos Magalhães de Castro <88864312+JohnC0de@users.noreply.github.com>
An override whose return type is part of the base method's union return
(`Meta` for `Meta | undefined`, `number` for `number | undefined`, or a
subclass of one of the union's class arms) was refused with SC1090,
although TypeScript accepts it. The override now returns through the
base's union ABI, so calls through the base type receive the value
unchanged, and calls resolved to the override narrow the result back to
its declared type.
`value.valueOf()` on a dynamic receiver was refused at compile time, a
class's own toString was not reached by `value.toString()`, and classes
could not declare a `[Symbol.toPrimitive]` method.
- `value.valueOf()` lowers to dyn.valueOf, which answers each kind's own
valueOf: a primitive itself, a Date its time value, an object with a
valueOf member that member's result, and any other object itself. A
null-prototype dictionary throws "<spelling> is not a function", and
null and undefined throw Node's property-read TypeError.
- When a boxed class declares valueOf or toString, `value.valueOf()` and
`value.toString(argument)` call the class's method for its instances
and keep the runtime call for every other value.
- Classes can declare `[Symbol.toPrimitive](hint)`. The dynamic
conversions call it with "default" for `+` and `==`, "number" for the
numeric operators and conversions, and "string" for template literals,
String() and property keys, and throw Node's TypeError when it returns
an object.
Buffer.write(text, "utf16le") zero-extended an ASCII run eight bytes per
step with shifts and masks in 64-bit words. Where the target has vector
unpacks (SSE2 on x86-64, NEON on AArch64) it now widens sixteen bytes
per step: one load, a test of the high bits, and two unpacked stores.
The word loop stays for the remaining bytes and for other targets. A
scanner that fills a Uint16Array of code units this way, as tsc-ts does
once per source file, spends about half as long in the copy.
Generic arrow properties and generic methods now have an erased runtime
value, their instance with every type parameter bound to unknown. Calls
through a round trip via any, a function result, an array element or a
class-backed interface call that value and convert the result to the
call's type, as JavaScript does. Direct calls on a known definition keep
their monomorphized path.
Fixes#905
Co-authored-by: Konstantin Mikheev <8560582+konmik@users.noreply.github.com>
- The EventEmitter leak warning reaches process 'warning' listeners on the next tick
- The events listener-count and max-listener helpers work over EventEmitter instances
- timers/promises setTimeout, setImmediate and scheduler.wait accept an AbortSignal
- timers/promises scheduler.wait and scheduler.yield are lowered
A static method that a function-local JavaScript class defines at
runtime and a program class inherits (Animal.extend("Dog")) is now
called directly with this bound to the receiver class when it captures
nothing from the factory's scope, so the subclass it builds has a static
base and constructs like Node.
Fixes#938
Co-authored-by: phall <25888173+phall1@users.noreply.github.com>
net.connect and net.createConnection dialed only IP literals and
"localhost"; any other host name failed with getaddrinfo ENOTFOUND
without a lookup, so names served by /etc/hosts or a container's DNS
(such as Docker service names) did not connect. The dial now resolves
the name with getaddrinfo using Node's hints, orders the addresses as
Node's autoSelectFamily does, and tries them in order.
Fixes#1156
Co-authored-by: Quim T. <26749475+espetro@users.noreply.github.com>
The WebAssembly and platform docs now say that wasm32-wasi builds need
zig and the @scriptc/runtime-wasm32-wasi package where the target is
introduced. A missing cross-target runtime pack still reports SC3003
with the package name and version; its hint now says that scriptc
includes the runtime pack for its own platform only, instead of
suggesting a reinstall with optional dependencies.
Fixes#717
Co-authored-by: guest271314 <4174848+guest271314@users.noreply.github.com>
m.groups on a match row compiles when the row's regex is statically
known. The row can now also be the element parameter of an inline
callback over a matchAll drain (map, forEach, filter, find, findLast,
some, every, flatMap) or Array.from's mapping function over s.matchAll(re).
In JavaScript sources such a parameter holds the row as a checked-dynamic
value without its groups, and the read is refused instead of reading
undefined.
The ESNext error lib is now part of the type world, and Error.isError(value)
compiles. A catch binding tests its payload against the Error class, an
unknown value tests the checked-dynamic error encoding, and a union tests its
runtime tag against the arms whose class extends Error. Other values answer
statically: true for instances of Error and its subclasses, false for
everything else, including objects that only have an error's shape. The
argument is always evaluated. Unions with unknown arms are refused.
Object.groupBy and Map.groupBy accepted only arrays. They now also take a
Set (its elements), a Map (its [key, value] entries) and a synchronous
generator. Sets and Maps are walked live, as forEach walks them, and a
generator is pulled one element per callback call and closed when the
callback throws. In JavaScript sources, unannotated callback parameters
take the element and its index.
Reading then, catch or finally from a promise held in a JavaScript or
checked-dynamic binding now answers the shared method values, so
typeof checks, thenable detection and "then" in p match Node. Calling a
method value uses its receiver; a receiver that is not a promise throws
Node's incompatible-receiver TypeError.
Fixes#978
Co-authored-by: Quim T. <26749475+espetro@users.noreply.github.com>
An element write whose key is asserted to a number, such as
`slots[at as number] = x` or `slots[at!] = x`, was judged by the type of
the key before the assertion. A `number | undefined` key counted as a key
that can name any string, so calls of every method in the program went
through the checked property lookup. The census now reads the type of the
key with its assertions, so these writes only mark methods with numeric
names.
Fixes#1148
Co-authored-by: Alan Leal <33952+alantriesagain@users.noreply.github.com>
Its package puts a cyclic object (cycle.self = cycle) in an array literal
with other values. The literal used to convert that checked-dynamic
object into a recursive record type and crashed; it now builds as a
checked-dynamic array that holds the object itself, so the program runs
as under Node and is no longer a known divergence.
When the program still fails to typecheck against a refused package's own
declarations, the type errors are the program's. Report them at their
locations instead of an SC2013 refusal for every imported package.
Fixes#1155
Co-authored-by: Quim T. <26749475+espetro@users.noreply.github.com>
`hot(xs[i] as number)` and `hot(stack.pop() as number)` counted as
possibly undefined, so `hot(n: number)` took a boxed `number | undefined`
parameter and callers boxed every number they passed. An assertion to a
type without undefined already checks the value and throws a TypeError
for undefined, so its result is now treated as present, like `x!`.
Fixes#985
Co-authored-by: Tim Kendall <1427378+timkendall@users.noreply.github.com>
A union arm whose object type has a required property of type never has
no values. When a conversion's source checker type proves an arm
uninhabited, the re-tag traps on that arm instead of requiring a matching
destination layout, so Result<T, never> widens into Result<T, E>.
Fixes#1170
Co-authored-by: BaoLei <50226652+blurname@users.noreply.github.com>
Promise.try(f, ...args) evaluates the arguments at the call and passes
them to f, which still runs synchronously; its result, a returned
promise or a synchronous throw settle the returned promise as in the
one-argument form. A callback with more parameters than arguments, or
an arguments list with a spread, is refused.
A switch whose discriminant is an object, array, record, function or
other reference value was refused. It now lowers like the union and
checked-dynamic switches: the discriminant is evaluated once and each
case expression, in source order and only until one matches, is compared
with it by the same strict-equality lowering as ===, which compares
references by identity. The === and !== lowering is now a function the
switch lowering shares.
Corpus 5659 printed blockList.rules and the inspected BlockList in the
order Node lists them. Node lists the address rules first, in the
iteration order of the std::unordered_map that holds them, and that order
differs between platforms, so the expected output on macOS differed from
Linux. The subnet and range rules that follow keep Node's fixed order
(newest first).
The program now sorts the address rules before printing the rules lists,
and inspects a BlockList that holds a single address rule.
Fixed tuples, readonly or mutable, lower these predicate methods like map
and flatMap: each position is read when it is visited, find, findIndex,
some and every stop at the first deciding position, and predicate results
and narrowing follow the array methods' rules.
Fixes#1171
Co-authored-by: BaoLei <50226652+blurname@users.noreply.github.com>
TypeScript class fields declared `unknown` or `object`, also with `null`
or `undefined` or as arrays of those, were refused with SC1090. They now
use the checked-dynamic storage that JavaScript class fields without a
declared type already use. This covers instance fields, static fields and
parameter properties. Fields declared `any` stay refused.
Fixes#1147
Co-authored-by: Alan Leal <33952+alantriesagain@users.noreply.github.com>