Skip to content

eliminate the BoundFn type from the language and the compiler implementations #9484

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
andrewrk opened this issue Jul 29, 2021 · 5 comments
Closed
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. stage1 The process of building from source via WebAssembly and the C backend.
Milestone

Comments

@andrewrk
Copy link
Member

Currently the Zig type system has a "BoundFn" which can be observed thusly:

test "example" {
    var a: A = .{};
    @compileLog(@TypeOf(a.b));
}

const A = struct {
    fn b() void {}
};

This type is to be removed from the language. Instead, method call syntax will be explicitly recognized in the parser. Here's an example which currently passes but will become a compile error:

test "example" {
    var a1: A = .{};
    var a2: A = .{};
    (if (true) a1.b else a2.b)();
}

const A = struct {
    fn b(a: A) void {
        _ = a;
    }
};

After this change, this will give a compile error: struct A has no field named b.

Related: #7942

Here's a diff to get you started:

diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig
index 9d432a3a0..f4daf5354 100644
--- a/lib/std/builtin.zig
+++ b/lib/std/builtin.zig
@@ -204,7 +204,6 @@ pub const TypeInfo = union(enum) {
     Enum: Enum,
     Union: Union,
     Fn: Fn,
-    BoundFn: Fn,
     Opaque: Opaque,
     Frame: Frame,
     AnyFrame: AnyFrame,
diff --git a/src/stage1/all_types.hpp b/src/stage1/all_types.hpp
index dfebc66cf..d36396c68 100644
--- a/src/stage1/all_types.hpp
+++ b/src/stage1/all_types.hpp
@@ -310,12 +310,6 @@ struct ConstErrValue {
     ZigValue *payload;
 };
 
-struct ConstBoundFnValue {
-    ZigFn *fn;
-    Stage1AirInst *first_arg;
-    AstNode *first_arg_src;
-};
-
 struct ConstArgTuple {
     size_t start_index;
     size_t end_index;
@@ -510,7 +504,6 @@ struct ZigValue {
         double x_f64;
         float128_t x_f128;
         bool x_bool;
-        ConstBoundFnValue x_bound_fn;
         ZigType *x_type;
         ZigValue *x_optional;
         ConstErrValue x_err_union;
@@ -1492,10 +1485,6 @@ struct ZigTypeFn {
     ZigType *bound_fn_parent;
 };
 
-struct ZigTypeBoundFn {
-    ZigType *fn_type;
-};
-
 // Needs to have the same memory layout as ZigTypeArray
 struct ZigTypeVector {
     // The type must be a pointer, integer, bool, or float
@@ -1528,7 +1517,6 @@ enum ZigTypeId {
     ZigTypeIdEnum,
     ZigTypeIdUnion,
     ZigTypeIdFn,
-    ZigTypeIdBoundFn,
     ZigTypeIdOpaque,
     ZigTypeIdFnFrame,
     ZigTypeIdAnyFrame,
@@ -1587,7 +1575,6 @@ struct ZigType {
         ZigTypeEnum enumeration;
         ZigTypeUnion unionation;
         ZigTypeFn fn;
-        ZigTypeBoundFn bound_fn;
         ZigTypeVector vector;
         ZigTypeOpaque opaque;
         ZigTypeFnFrame frame;
@andrewrk andrewrk added contributor friendly This issue is limited in scope and/or knowledge of Zig internals. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. accepted This proposal is planned. labels Jul 29, 2021
@andrewrk andrewrk added this to the 0.9.0 milestone Jul 29, 2021
@andrewrk andrewrk added the stage1 The process of building from source via WebAssembly and the C backend. label Jul 29, 2021
@zigazeljko
Copy link
Contributor

What is the expected implementation here?

  1. Add a new node type to parser to be used instead of the current NodeTypeFieldAccessExpr + NodeTypeFnCallExpr combo.
  2. Keep the parser unchanged and handle the NodeTypeFieldAccessExpr + NodeTypeFnCallExpr combo inside astgen.

@andrewrk
Copy link
Member Author

@zigazeljko apologies for not seeing your question earlier.

You'll need to change the parser as noted here:

Instead, method call syntax will be explicitly recognized in the parser

@edt-xx
Copy link

edt-xx commented Sep 27, 2021

Probably a stupid question, but how will zig handle a 'class fn' in a struct? eg usually you want:

fn aaa(...) type {
     var bbb:u64 = ....
     return struct {
         ....
         ST = @This();
           fn ccc(self: *ST, ... ) ...  { ... }    // the common case
           
           fn ddd(eee: ... ) u64 { ... some code depending on bbb & eee  returning a u64 ... )  // how will we express this
           ....      
 }
 
 AaaType = aaa(...);
 AaaType.ddd(..);

@dacjames
Copy link

dacjames commented Nov 8, 2021

Is anyone working on this? I've been looking for something for a first time contribution that touches the language itself (since that's my interest area).

Aside from overall simplification, what is the motivation for removing BoundFn, @andrewrk ?

@fogti
Copy link
Contributor

fogti commented Jan 28, 2022

it is normal that I arrive at the following when applying the patch in the first comment?

$ zig build --zig-lib-dir lib --verbose
Semantic Analysis [440/860] Assertion failed at /build/source/src/stage1/ir.cpp:19106 in type_info_to_type. This is a bug in the Zig compiler.thread 303768 panic: 
Unable to dump stack trace: debug info stripped
Aborted (core dumped)

compiled with zig version 0.10.0 fbe5336
with first-comment patch applied on top 0e6d218
code snippet:

        case ZigTypeIdVector: {
            // one of the following asserts fails...
            assert(payload->special == ConstValSpecialStatic);
            assert(payload->type == ir_type_info_get_type(ira, "Vector", nullptr));
            BigInt *len = get_const_field_lit_int(ira, source_node, payload, "len", 0);
            if (len == nullptr)
                return ira->codegen->invalid_inst_gen->value->type;

            ZigType *child_type = get_const_field_meta_type(ira, source_node, payload, "child", 1);
            if ((err = ir_validate_vector_elem_type(ira, source_node, child_type))) {
                return ira->codegen->invalid_inst_gen->value->type;
            }
            return get_vector_type(ira->codegen, bigint_as_u32(len), child_type);
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. stage1 The process of building from source via WebAssembly and the C backend.
Projects
None yet
Development

No branches or pull requests

5 participants