mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-02 07:43:42 +08:00
Inside a nested function, a read of a captured handle `let` narrowed to the handle whenever it was a member receiver. A function declared before the first write reads the binding as `any`, so the narrowed handle reached member reads typed `any`, and an optional read (`c?.remoteAddress`) compiled to an unconditional SC1090 throw. js-dyn-server, whose listener reads `server.listening` inside the callback passed to createServer, hit the same path. The read now narrows only when the checker types it as the handle. An optional member read keeps the tagged value, so undefined short-circuits and the handle arm narrows; other reads take the checked-dynamic value. The lowerer's closureDynLets collection is a checked journal table. Corpus evolving-let-socket-optional-reads.cjs reads and calls members through `?.` on a captured socket before and after its first write.
21 lines
680 B
JavaScript
21 lines
680 B
JavaScript
'use strict';
|
|
// Optional reads and calls on a captured `let` socket, before and after
|
|
// its first write: undefined short-circuits, the socket answers.
|
|
const net = require('net');
|
|
let c;
|
|
const server = net.createServer((s) => s.end());
|
|
function report(label) {
|
|
console.log(label, c?.remoteAddress, c?.address()?.family, c?.remotePort > 0);
|
|
}
|
|
report('before');
|
|
const early = () => console.log('arrow before', c?.remoteAddress ?? 'none');
|
|
early();
|
|
server.listen(0, '127.0.0.1', () => {
|
|
c = net.connect(server.address().port, '127.0.0.1', () => {
|
|
report('after');
|
|
console.log('inside', c?.remoteAddress, c?.address()?.family);
|
|
c.end();
|
|
server.close();
|
|
});
|
|
});
|