From b34f994c0ba2d87fce2a3409d6bcfa7a5ebe78ff Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 21 Jan 2022 00:49:58 -0700 Subject: stage2: type system treats fn ptr and body separately This commit updates stage2 to enforce the property that the syntax `fn()void` is a function *body* not a *pointer*. To get a pointer, the syntax `*const fn()void` is required. ZIR puts function alignment into the func instruction rather than the decl because this way it makes it into function types. LLVM backend respects function alignments. Struct and Union have methods `fieldSrcLoc` to help look up source locations of their fields. These trigger full loading, tokenization, and parsing of source files, so should only be called once it is confirmed that an error message needs to be printed. There are some nice new error hints for explaining why a type is required to be comptime, particularly for structs that contain function body types. `Type.requiresComptime` is now moved into Sema because it can fail and might need to trigger field type resolution. Comptime pointer loading takes into account types that do not have a well-defined memory layout and does not try to compute a byte offset for them. `fn()void` syntax no longer secretly makes a pointer. You get a function body type, which requires comptime. However a pointer to a function body can be runtime known (obviously). Compile errors that report "expected pointer, found ..." are factored out into convenience functions `checkPtrOperand` and `checkPtrType` and have a note about function pointers. Implemented `Value.hash` for functions, enum literals, and undefined values. stage1 is not updated to this (yet?), so some workarounds and disabled tests are needed to keep everything working. Should we update stage1 to these new type semantics? Yes probably because I don't want to add too much conditional compilation logic in the std lib for the different backends. --- src/AstGen.zig | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/AstGen.zig') diff --git a/src/AstGen.zig b/src/AstGen.zig index 114cd5f505..d75ae82e0a 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -3240,7 +3240,8 @@ fn fnDecl( const doc_comment_index = try astgen.docCommentAsString(fn_proto.firstToken()); const has_section_or_addrspace = fn_proto.ast.section_expr != 0 or fn_proto.ast.addrspace_expr != 0; - wip_members.nextDecl(is_pub, is_export, fn_proto.ast.align_expr != 0, has_section_or_addrspace); + // Alignment is passed in the func instruction in this case. + wip_members.nextDecl(is_pub, is_export, false, has_section_or_addrspace); var params_scope = &fn_gz.base; const is_var_args = is_var_args: { @@ -3380,7 +3381,7 @@ fn fnDecl( .param_block = block_inst, .body_gz = null, .cc = cc, - .align_inst = .none, // passed in the per-decl data + .align_inst = align_inst, .lib_name = lib_name, .is_var_args = is_var_args, .is_inferred_error = false, @@ -3423,7 +3424,7 @@ fn fnDecl( .ret_br = ret_br, .body_gz = &fn_gz, .cc = cc, - .align_inst = .none, // passed in the per-decl data + .align_inst = align_inst, .lib_name = lib_name, .is_var_args = is_var_args, .is_inferred_error = is_inferred_error, @@ -3449,9 +3450,6 @@ fn fnDecl( wip_members.appendToDecl(fn_name_str_index); wip_members.appendToDecl(block_inst); wip_members.appendToDecl(doc_comment_index); - if (align_inst != .none) { - wip_members.appendToDecl(@enumToInt(align_inst)); - } if (has_section_or_addrspace) { wip_members.appendToDecl(@enumToInt(section_inst)); wip_members.appendToDecl(@enumToInt(addrspace_inst)); -- cgit v1.2.3