diff --git a/build.zig.zon b/build.zig.zon index 5aa0d6aea..1939767fe 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -10,7 +10,7 @@ // nix flake update --commit-lock-file // ``` // If you do not use Nix, a ZLS maintainer can take care of this. - .minimum_zig_version = "0.18.0-dev.897+117fd40fb", + .minimum_zig_version = "0.18.0-dev.1005+75d48dfff", // Must be kept in sync with the `deps.nix` for the Nix flake. // If you do not use Nix, a ZLS maintainer can take care of this. .dependencies = .{ diff --git a/flake.lock b/flake.lock index 57ed38ed0..41eaa719f 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1793865203, - "narHash": "sha256-/cpdPHaySDIyCgZI6EWngiM6jK3YLUNzv1b7lTzy6Bk=", + "lastModified": 1794165970, + "narHash": "sha256-XuAV2cUwaod3Bt4XFVqiXz3v1w2ex16W6Sv4S7EWres=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "c56a87d8e41ce69bd2af57eb35dcc117a9dfca33", + "rev": "ac588ef1c914865dad517b337ea0eb9694a4021c", "type": "github" }, "original": { @@ -29,11 +29,11 @@ ] }, "locked": { - "lastModified": 1794077684, - "narHash": "sha256-ahaUJnLCPHgUzPQbNpsCl9cHJnrr3GifNbgJREytNHA=", + "lastModified": 1794400348, + "narHash": "sha256-ge/Hg9mrl90G8qBWrX0XjV1t0XVRduCg8vT63KVJEPo=", "owner": "silversquirl", "repo": "zig-flake", - "rev": "a8f437885740ed8a1541f4cb87e0d3b65848ae9c", + "rev": "a16d0a105ba8f33a35b04ef67194e35784022a66", "type": "github" }, "original": { diff --git a/src/DocumentScope.zig b/src/DocumentScope.zig index 9de594101..d24f24cf7 100644 --- a/src/DocumentScope.zig +++ b/src/DocumentScope.zig @@ -241,11 +241,11 @@ pub const Scope = struct { } }; - pub const Data = packed union { + pub const Data = bitpack union { ast_node: Ast.Node.Index, }; - pub const SmallLoc = packed struct { + pub const SmallLoc = bitpack struct { start: u32, end: u32, }; @@ -270,7 +270,7 @@ pub const Scope = struct { }, }; - data: packed struct(u64) { + data: bitpack struct(u64) { tag: Tag, is_child_scopes_small: bool, is_child_decls_small: bool, diff --git a/src/TrigramStore.zig b/src/TrigramStore.zig index 637baaf0f..982579cbf 100644 --- a/src/TrigramStore.zig +++ b/src/TrigramStore.zig @@ -517,7 +517,7 @@ const CuckooFilter = struct { index_2: BucketIndex, pub fn initFromTrigram(trigram: Trigram, len: u32) Triplet { - const split: packed struct { + const split: bitpack struct { fingerprint: Fingerprint, padding: u24, index_1: u32, diff --git a/src/analyser/InternPool.zig b/src/analyser/InternPool.zig index 1cef0eeaf..e050203cc 100644 --- a/src/analyser/InternPool.zig +++ b/src/analyser/InternPool.zig @@ -74,7 +74,7 @@ pub const Key = union(enum) { flags: Flags, packed_offset: PackedOffset = .{ .bit_offset = 0, .host_size = 0 }, - pub const Flags = packed struct(u32) { + pub const Flags = bitpack struct(u32) { size: std.lang.Type.Pointer.Size, is_const: bool = false, is_volatile: bool = false, @@ -84,7 +84,7 @@ pub const Key = union(enum) { alignment: u16 = 0, }; - pub const PackedOffset = packed struct(u32) { + pub const PackedOffset = bitpack struct(u32) { bit_offset: u16, host_size: u16, }; @@ -123,7 +123,7 @@ pub const Key = union(enum) { return_type: Index, flags: Flags = .{}, - pub const Flags = packed struct(u32) { + pub const Flags = bitpack struct(u32) { calling_convention: std.lang.CallingConvention.Tag = .auto, is_generic: bool = false, is_var_args: bool = false, @@ -197,7 +197,7 @@ pub const Key = union(enum) { } }; - const F64Value = packed struct { + const F64Value = bitpack struct { a: u32, b: u32, @@ -210,7 +210,7 @@ pub const Key = union(enum) { } }; - const F80Value = packed struct { + const F80Value = bitpack struct { a: u32, b: u32, c: u32, @@ -226,7 +226,7 @@ pub const Key = union(enum) { } }; - const F128Value = packed struct { + const F128Value = bitpack struct { a: u32, b: u32, c: u32, @@ -3307,7 +3307,7 @@ pub fn isUnsignedInt(ip: *InternPool, ty: Index, target: std.Target) bool { }; } -/// Asserts the type is an integer, enum, error set, packed struct, or vector of one of them. +/// Asserts the type is an integer, enum, error set, bitpack struct, or vector of one of them. pub fn intInfo(ip: *InternPool, ty: Index, target: std.Target) std.lang.Type.Int { var index = ty; while (true) switch (index) { @@ -3349,7 +3349,7 @@ pub fn intInfo(ip: *InternPool, ty: Index, target: std.Target) std.lang.Type.Int }, .struct_type => |struct_index| { const struct_info = ip.getStruct(struct_index); - assert(struct_info.layout == .@"packed"); + assert(struct_info.layout == .@"bitpack"); index = struct_info.backing_int_ty; }, // TODO revisit this when error sets support custom int types (comment taken from zig codebase) diff --git a/src/configuration.zig b/src/configuration.zig index bf09947eb..dc8edf60b 100644 --- a/src/configuration.zig +++ b/src/configuration.zig @@ -638,9 +638,9 @@ pub const UnresolvedConfig = blk: { break :blk @Struct(.auto, null, struct_info.field_names, &field_types, &field_attrs); }; -/// A packed struct where every field name is copied from `Config` but the field type is `bool`. +/// A bitpack struct where every field name is copied from `Config` but the field type is `bool`. pub const DidConfigChange = @Struct( - .@"packed", + .@"bitpack", null, @typeInfo(Config).@"struct".field_names, &@splat(bool), diff --git a/src/features/semantic_tokens.zig b/src/features/semantic_tokens.zig index 149348a94..81cebdab2 100644 --- a/src/features/semantic_tokens.zig +++ b/src/features/semantic_tokens.zig @@ -46,7 +46,7 @@ pub const TokenType = enum(u32) { keywordLiteral, }; -pub const TokenModifiers = packed struct(u16) { +pub const TokenModifiers = bitpack struct(u16) { declaration: bool = false, definition: bool = false, readonly: bool = false, diff --git a/src/tools/langref.html.in b/src/tools/langref.html.in index 19f9d8322..52ef64297 100644 --- a/src/tools/langref.html.in +++ b/src/tools/langref.html.in @@ -755,12 +755,21 @@ \u{NNNNNN} - hexadecimal Unicode scalar value UTF-8 encoded (1 or more digits) + hexadecimal Unicode code point (1 or more digits) -

Note that the maximum valid Unicode scalar value is {#syntax#}0x10ffff{#endsyntax#}.

+

+ Note that the highest Unicode code point is {#syntax#}0x10ffff{#endsyntax#}. Character + literals are integers ({#syntax#}'A'{#endsyntax#} = {#syntax#}65{#endsyntax#} and + {#syntax#}'\u{10000}'{#endsyntax#} = {#syntax#}0x10000{#endsyntax#} = {#syntax#}65536{#endsyntax#}), + and \u escapes in string literals are encoded as UTF-8 + ({#syntax#}"A"{#endsyntax#} = {#syntax#}"\u{41}"{#endsyntax#} = {#syntax#}"\x41"{#endsyntax#} + and {#syntax#}"\u{10000}"{#endsyntax#} = {#syntax#}"\xF0\x90\x80\x80"{#endsyntax#}). + \u escapes can be used for surrogate code points, which are not Unicode + scalar values or technically allowed in UTF-8 as defined by the Unicode standard, but can be useful in practice. +

{#header_close#} {#header_open|Multiline String Literals#}

@@ -1681,7 +1690,7 @@ try value == 5678{#endsyntax#}

  • {#link|Floats#}
  • {#link|bool|Primitive Types#}
  • {#link|type|Primitive Types#}
  • -
  • {#link|packed struct#}
  • +
  • {#link|bitpack struct#}
  • @@ -1885,20 +1894,77 @@ const B = error{Two}; {#header_close#} {#header_open|Precedence#} +

    + Zig features partial operator precedence: not every operator has a defined precedence with + every other operator. Mixing operators with ambiguous precedence is prohibited and parentheses + are mandatory. Consequently, valid code is typically auto-descriptive; when reading and + writing Zig code, there are very few precedence rules you'll need to remember. +

    + + {#code|operator_precedence.zig#} + + {#code|ambiguous_precedence_orelse.zig#} + +

    + There is a set of operators (prefix operators, suffix operators, etc) that have unambiguously + higher precedence than all other operators. That set of operators has the following precedence table: +

    +
    {#syntax#}x() x[] x.y x.* x.?
     a!b
     x{}
     !x -x -%x ~x &x ?x try
    -* / % *% *| ||
    -+ - ++ +% -% +| -|
    -<< >> <<|
    -& ^ | orelse catch
    +// lower precedence operators omitted{#endsyntax#}
    + +

    + For the other operators, simplified operator precedence tables are provided below, each containing only + the information that you'll need to know when reading/writing code that uses that particular category of operators. + The operators that have ambiguous precedence or semantic errors with the relevant operators have been omitted, + as have the operators with higher precedence (those shown above). +

    + +

    + For arithmetic operators: +

    + +
    {#syntax#}* / *% *| %
    ++ - +% -% +| -|
    +== != < > <= >=
    +and or{#endsyntax#}
    + +

    + For bitwise operators: +

    + +
    {#syntax#}<< <<| >> & ^ |
     == != < > <= >=
    -and
    -or
    -= *= *%= *|= /= %= += +%= +|= -= -%= -|= <<= <<|= >>= &= ^= |={#endsyntax#}
    +and or{#endsyntax#} + +

    + For null and error recovery operators: +

    + +
    {#syntax#}catch orelse{#endsyntax#}
    + +

    + For error set operators: +

    + +
    {#syntax#}||{#endsyntax#}
    + +

    + For array concatenation operators: +

    + +
    {#syntax#}++{#endsyntax#}
    + +

    + The full precedence rules can be found in the {#link|Grammar#}, which also includes an {#link|Operator Precedence Flowchart#}. +

    + {#header_close#} {#header_close#} + {#header_open|Arrays#} {#code|test_arrays.zig#} @@ -2261,20 +2327,20 @@ or the C ABI for the target.

    If well-defined in-memory layout is not required, {#link|struct#} is a better choice because it places fewer restrictions on the compiler.

    -

    See {#link|packed struct#} for a struct that has the ABI of its backing integer, +

    See {#link|bitpack struct#} for a struct that has the ABI of its backing integer, which can be useful for modeling flags.

    {#see_also|extern union|extern enum#} {#header_close#} - {#header_open|packed struct#} + {#header_open|bitpack struct#}

    - {#syntax#}packed{#endsyntax#} structs, like {#syntax#}enum{#endsyntax#}, are based on the concept - of interpreting integers differently. All packed structs have a backing integer, + {#syntax#}bitpack{#endsyntax#} structs, like {#syntax#}enum{#endsyntax#}, are based on the concept + of interpreting integers differently. All bitpack structs have a backing integer, which is implicitly determined by the total bit count of fields, or explicitly specified. - Packed structs have well-defined memory layout - exactly the same ABI as their backing integer. + Bitpack structs have well-defined memory layout - exactly the same ABI as their backing integer.

    - Each field of a packed struct is interpreted as a logical sequence of bits, arranged from + Each field of a bitpack struct is interpreted as a logical sequence of bits, arranged from least to most significant. Allowed field types:

    - This means that a {#syntax#}packed struct{#endsyntax#} can participate + This means that a {#syntax#}bitpack struct{#endsyntax#} can participate in a {#link|@bitCast#} or a {#link|@ptrCast#} to reinterpret memory. This even works at {#link|comptime#}:

    - {#code|test_packed_structs.zig#} + {#code|test_bitpack_structs.zig#}

    The backing integer can be inferred or explicitly provided. When @@ -2300,13 +2366,13 @@ or will be enforced at compile time to exactly match the total bit width of the fields:

    - {#code|test_missized_packed_struct.zig#} + {#code|test_missized_bitpack_struct.zig#}

    - A {#syntax#}packed struct{#endsyntax#} can be converted to and from its backing + A {#syntax#}bitpack struct{#endsyntax#} can be converted to and from its backing integer using {#link|@backingInt#} and {#link|@fromBackingInt#}:

    - {#code|test_packed_struct_backing_int.zig#} + {#code|test_bitpack_struct_backing_int.zig#}

    Zig allows the address to be taken of a non-byte-aligned field: @@ -2326,7 +2392,7 @@ or

    Pointers to non-ABI-aligned fields share the same address as the other fields within their host integer:

    - {#code|test_packed_struct_field_address.zig#} + {#code|test_bitpack_struct_field_address.zig#}

    This can be observed with {#link|@bitOffsetOf#} and {#link|offsetOf#}: @@ -2334,10 +2400,10 @@ or {#code|test_bitOffsetOf_offsetOf.zig#}

    - Packed structs have the same alignment as their backing integer, however, overaligned - pointers to packed structs can override this: + Bitpack structs have the same alignment as their backing integer, however, overaligned + pointers to bitpack structs can override this:

    - {#code|test_overaligned_packed_struct.zig#} + {#code|test_overaligned_bitpack_struct.zig#}

    It's also possible to set alignment of struct fields: @@ -2345,10 +2411,10 @@ or {#code|test_aligned_struct_fields.zig#}

    - Equating packed structs results in a comparison of the backing integer, + Equating bitpack structs results in a comparison of the backing integer, and only works for the {#syntax#}=={#endsyntax#} and {#syntax#}!={#endsyntax#} {#link|Operators#}.

    - {#code|test_packed_struct_equality.zig#} + {#code|test_bitpack_struct_equality.zig#}

    Field access and assignment can be understood as shorthand for bitshifts @@ -2357,7 +2423,7 @@ or input-output (MMIO). Instead of field access on {#link|volatile#} {#link|Pointers#}, construct a fully-formed new value first, then write that value to the volatile pointer.

    - {#code|packed_struct_mmio.zig#} + {#code|bitpack_struct_mmio.zig#} {#header_close#} {#header_open|Struct Naming#} @@ -2477,7 +2543,7 @@ or can be as a list of fields. Only one field can be active at a time. The in-memory representation of bare unions is not guaranteed. Bare unions cannot be used to reinterpret memory. For that, use {#link|@ptrCast#}, - or use an {#link|extern union#} or a {#link|packed union#} which have + or use an {#link|extern union#} or a {#link|bitpack union#} which have guaranteed in-memory layout. {#link|Accessing the non-active field|Wrong Union Field Access#} is safety-checked {#link|Illegal Behavior#}: @@ -2489,7 +2555,7 @@ or

    In order to use {#link|switch#} with a union, it must be a {#link|tagged union|Tagged union#} - or a {#link|packed union#}. + or a {#link|bitpack union#}.

    To initialize a union when the tag is a {#link|comptime#}-known name, see {#link|@unionInit#}. @@ -2538,16 +2604,16 @@ or {#see_also|extern struct#} {#header_close#} - {#header_open|packed union#} -

    A {#syntax#}packed union{#endsyntax#} has well-defined in-memory layout and is eligible - to be in a {#link|packed struct#}.

    -

    All fields in a packed union must have the same {#link|@bitSizeOf#}.

    + {#header_open|bitpack union#} +

    A {#syntax#}bitpack union{#endsyntax#} has well-defined in-memory layout and is eligible + to be in a {#link|bitpack struct#}.

    +

    All fields in a bitpack union must have the same {#link|@bitSizeOf#}.

    - Equating packed unions results in a comparison of the backing integer, + Equating bitpack unions results in a comparison of the backing integer, and only works for the {#syntax#}=={#endsyntax#} and {#syntax#}!={#endsyntax#} {#link|Operators#}.

    - {#code|test_packed_union_equality.zig#} + {#code|test_bitpack_union_equality.zig#} {#see_also|@backingInt|@fromBackingInt#} {#header_close#} @@ -3621,14 +3687,14 @@ void do_a_thing(struct Foo *foo) { + + +
    {#syntax#}bitpack{#endsyntax#}
    + + + The {#syntax#}bitpack{#endsyntax#} keyword before a struct definition changes the struct's in-memory layout + to the guaranteed {#syntax#}bitpack{#endsyntax#} layout. + + +
    {#syntax#}break{#endsyntax#}
    @@ -7690,18 +7767,6 @@ fn readU32Be() u32 {} - - -
    {#syntax#}packed{#endsyntax#}
    - - - The {#syntax#}packed{#endsyntax#} keyword before a struct definition changes the struct's in-memory layout - to the guaranteed {#syntax#}packed{#endsyntax#} layout. - - -
    {#syntax#}pub{#endsyntax#}
    @@ -7870,6 +7935,42 @@ fn readU32Be() u32 {} {#header_open|Appendix#} {#header_open|Grammar#} {#grammar#} + {#header_open|Operator Precedence Flowchart#} +

    + To help understand the grammar, this flowchart is provided for the operator precedence. + The bottom represents any location where an expression may occur and the topmost row represents + a parenthesized expression. An operator will have a higher precedence (and therefore be the parent) to + another node if it is strictly lower on the tree (having a directed path from one to another). This is inverted from classical precedence, but + is closer to how a recursive descent parser views the grammar. +

    +
    
    +                     ┏━━━━━━━━━━━━━━━━━━━┓   
    +                     ┃(expr)             ┃                  
    +                     ┃x() x[] x.y x.* x.?┃                  
    +                     ┃E!T                ┃                  
    +                     ┃x{}                ┃                  
    +                     ┃!x -x -%x ~x &x ?x ┃                  
    +                     ┗━━━━━━━━━▲━━━━━━━━━┛                  
    +          ┌─────────────┬──────┴───────┬───────┬──┬──┬─┐         
    +          │             │              │       │  │  │ │         
    +   ┏━━━━━━┷━━━━━┓╭Non╌Chaining╮ ╭Non╌Chaining╮┏┷┓┏┷┓┏┷┓│         
    +   ┃* *% *| / ||┃╎      %     ╎ ╎ << <<|  >> ╎┃&┃┃^┃┃|┃│         
    +   ┗━━━━━━▲━━━━━┛╰╌╌╌╌╌╌▲╌╌╌╌╌╯ ╰╌╌╌╌╌╌▲╌╌╌╌╌╯┗▲┛┗▲┛┗▲┛│         
    +       ┏━━┷━━━━━━━━━━━━━┷━┓       ┌────┴───────┴──┴──┘ │         
    +       ┃+ - +% -% +| -| ++┃       │                    │         
    +       ┗━━━━━━━━━━━▲━━━━━━┛       │                    │         
    +                  ╭┴╌Non-Chaining╌┴╮                   │         
    +                  ╎== !=  < <= >= >╎                   │         
    +                  ╰╌╌╌▲╌╌╌╌▲╌╌╌╌╌╌╌╯      ┌──────┬─────┘                
    +                    ┏━┷━┓┏━┷━┓        ┏━━━┷━━┓┏━━┷━━┓                  
    +                    ┃and┃┃or ┃        ┃orelse┃┃catch┃                  
    +                    ┗━▲━┛┗━▲━┛        ┗━━━▲━━┛┗━━▲━━┛                  
    +                   ╭╌╌┴╌╌╌╌┴╌╌╌╌╌╌╌╌╌╌╌╌╌╌┴╌╌╌╌╌╌┴╌╮ 
    +                   ╎    Any expression location    ╎ 
    +                   ╰╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ 
    +                                                              
    +      
    + {#header_close#} {#header_close#} {#header_open|Zen#}