Generic inference (#2475)

* Change generic symbol resolution.
* Infer generic parameters lhs -> rhs: `List{int} x = list::NOHEAP`.
* Regression: Compiler segfault when assigning struct literal with too few members #2483
This commit is contained in:
Christoffer Lerno
2025-09-16 18:05:21 +02:00
committed by GitHub
parent 8342ac80d3
commit 92aefb15f8
28 changed files with 563 additions and 214 deletions

View File

@@ -1,5 +1,7 @@
module std::io;
import std::math;
import std::core::env;
interface InStream
{
@@ -260,6 +262,16 @@ macro ushort? read_be_ushort(stream)
return (ushort)(hi_byte << 8 | lo_byte);
}
<*
@require @is_instream(stream)
*>
macro ushort? read_le_ushort(stream)
{
char lo_byte = stream.read_byte()!;
char hi_byte = stream.read_byte()!;
return (ushort)(hi_byte << 8 | lo_byte);
}
<*
@require @is_instream(stream)
*>
@@ -268,6 +280,14 @@ macro short? read_be_short(stream)
return read_be_ushort(stream);
}
<*
@require @is_instream(stream)
*>
macro short? read_le_short(stream)
{
return read_le_ushort(stream);
}
<*
@require @is_outstream(stream)
*>
@@ -277,6 +297,15 @@ macro void? write_be_short(stream, ushort s)
stream.write_byte((char)s)!;
}
<*
@require @is_outstream(stream)
*>
macro void? write_le_short(stream, ushort s)
{
stream.write_byte((char)s)!;
stream.write_byte((char)(s >> 8))!;
}
<*
@require @is_instream(stream)
*>
@@ -288,6 +317,17 @@ macro uint? read_be_uint(stream)
return val + stream.read_byte()!;
}
<*
@require @is_instream(stream)
*>
macro uint? read_le_uint(stream)
{
uint val = stream.read_byte()!;
val += stream.read_byte()! << 8;
val += stream.read_byte()! << 16;
return val + stream.read_byte()! << 24;
}
<*
@require @is_instream(stream)
*>
@@ -296,6 +336,14 @@ macro int? read_be_int(stream)
return read_be_uint(stream);
}
<*
@require @is_instream(stream)
*>
macro int? read_le_int(stream)
{
return read_le_uint(stream);
}
<*
@require @is_outstream(stream)
*>
@@ -307,6 +355,17 @@ macro void? write_be_int(stream, uint s)
stream.write_byte((char)s)!;
}
<*
@require @is_outstream(stream)
*>
macro void? write_le_int(stream, uint s)
{
stream.write_byte((char)s)!;
stream.write_byte((char)(s >> 8))!;
stream.write_byte((char)(s >> 16))!;
stream.write_byte((char)(s >> 24))!;
}
<*
@require @is_instream(stream)
*>
@@ -322,6 +381,21 @@ macro ulong? read_be_ulong(stream)
return val + stream.read_byte()!;
}
<*
@require @is_instream(stream)
*>
macro ulong? read_le_ulong(stream)
{
ulong val = (ulong)stream.read_byte()!;
val += (ulong)stream.read_byte()! << 8;
val += (ulong)stream.read_byte()! << 16;
val += (ulong)stream.read_byte()! << 24;
val += (ulong)stream.read_byte()! << 32;
val += (ulong)stream.read_byte()! << 40;
val += (ulong)stream.read_byte()! << 48;
return val + (ulong)stream.read_byte()! << 56;
}
<*
@require @is_instream(stream)
*>
@@ -330,6 +404,14 @@ macro long? read_be_long(stream)
return read_be_ulong(stream);
}
<*
@require @is_instream(stream)
*>
macro long? read_le_long(stream)
{
return read_le_ulong(stream);
}
<*
@require @is_outstream(stream)
*>
@@ -345,6 +427,21 @@ macro void? write_be_long(stream, ulong s)
stream.write_byte((char)s)!;
}
<*
@require @is_outstream(stream)
*>
macro void? write_le_long(stream, ulong s)
{
stream.write_byte((char)s)!;
stream.write_byte((char)(s >> 8))!;
stream.write_byte((char)(s >> 16))!;
stream.write_byte((char)(s >> 24))!;
stream.write_byte((char)(s >> 32))!;
stream.write_byte((char)(s >> 40))!;
stream.write_byte((char)(s >> 48))!;
stream.write_byte((char)(s >> 56))!;
}
<*
@require @is_instream(stream)
*>
@@ -368,6 +465,29 @@ macro uint128? read_be_uint128(stream)
return val + stream.read_byte()!;
}
<*
@require @is_instream(stream)
*>
macro uint128? read_le_uint128(stream)
{
uint128 val = stream.read_byte()!;
val += (uint128)stream.read_byte()! << 8;
val += (uint128)stream.read_byte()! << 16;
val += (uint128)stream.read_byte()! << 24;
val += (uint128)stream.read_byte()! << 32;
val += (uint128)stream.read_byte()! << 40;
val += (uint128)stream.read_byte()! << 48;
val += (uint128)stream.read_byte()! << 56;
val += (uint128)stream.read_byte()! << 64;
val += (uint128)stream.read_byte()! << 72;
val += (uint128)stream.read_byte()! << 80;
val += (uint128)stream.read_byte()! << 88;
val += (uint128)stream.read_byte()! << 96;
val += (uint128)stream.read_byte()! << 104;
val += (uint128)stream.read_byte()! << 112;
return val + (uint128)stream.read_byte()! << 120;
}
<*
@require @is_instream(stream)
*>
@@ -376,6 +496,14 @@ macro int128? read_be_int128(stream)
return read_be_uint128(stream);
}
<*
@require @is_instream(stream)
*>
macro int128? read_le_int128(stream)
{
return read_le_uint128(stream);
}
<*
@require @is_outstream(stream)
*>
@@ -399,6 +527,30 @@ macro void? write_be_int128(stream, uint128 s)
stream.write_byte((char)s)!;
}
<*
@require @is_outstream(stream)
*>
macro void? write_le_int128(stream, uint128 s)
{
stream.write_byte((char)s)!;
stream.write_byte((char)(s >> 8))!;
stream.write_byte((char)(s >> 16))!;
stream.write_byte((char)(s >> 24))!;
stream.write_byte((char)(s >> 32))!;
stream.write_byte((char)(s >> 40))!;
stream.write_byte((char)(s >> 48))!;
stream.write_byte((char)(s >> 56))!;
stream.write_byte((char)(s >> 64))!;
stream.write_byte((char)(s >> 72))!;
stream.write_byte((char)(s >> 80))!;
stream.write_byte((char)(s >> 88))!;
stream.write_byte((char)(s >> 96))!;
stream.write_byte((char)(s >> 104))!;
stream.write_byte((char)(s >> 112))!;
stream.write_byte((char)(s >> 120))!;
}
<*
@require @is_outstream(stream)
@require data.len < 256 : "Data exceeded 255"
@@ -443,6 +595,34 @@ macro char[]? read_short_bytearray(stream, Allocator allocator)
return data;
}
<*
@require @is_instream(stream)
*>
macro void? skip(stream, usz bytes)
{
if (!bytes) return;
$switch:
$case !$defined(stream.seek):
for (usz i = 0; i < bytes; i++)
{
stream.read()!;
}
return;
$case $typeof(stream) == InStream:
if (!&stream.seek)
{
for (usz i = 0; i < bytes; i++)
{
stream.read()!;
}
return;
}
stream.seek(bytes, CURSOR)!;
$default:
stream.seek(bytes, CURSOR)!;
$endswitch
}
<*
Wrap bytes for reading using io functions.
*>