| ... | @@ -3149,18 +3149,23 @@ pub fn processExports(pt: Zcu.PerThread) !void { | ... | @@ -3149,18 +3149,23 @@ pub fn processExports(pt: Zcu.PerThread) !void { |
| 3149 | } | 3149 | } |
| 3150 | } | 3150 | } |
| 3151 | | 3151 | |
| | 3152 | // If there are compile errors, we won't call `updateExports`. Not only would it be redundant |
| | 3153 | // work, but the linker may not have seen an exported `Nav` due to a compile error, so linker |
| | 3154 | // implementations would have to handle that case. This early return avoids that. |
| | 3155 | const skip_linker_work = zcu.comp.anyErrors(); |
| | 3156 | |
| 3152 | // Map symbol names to `Export` for name collision detection. | 3157 | // Map symbol names to `Export` for name collision detection. |
| 3153 | var symbol_exports: SymbolExports = .{}; | 3158 | var symbol_exports: SymbolExports = .{}; |
| 3154 | defer symbol_exports.deinit(gpa); | 3159 | defer symbol_exports.deinit(gpa); |
| 3155 | | 3160 | |
| 3156 | for (nav_exports.keys(), nav_exports.values()) |exported_nav, exports_list| { | 3161 | for (nav_exports.keys(), nav_exports.values()) |exported_nav, exports_list| { |
| 3157 | const exported: Zcu.Exported = .{ .nav = exported_nav }; | 3162 | const exported: Zcu.Exported = .{ .nav = exported_nav }; |
| 3158 | try pt.processExportsInner(&symbol_exports, exported, exports_list.items); | 3163 | try pt.processExportsInner(&symbol_exports, exported, exports_list.items, skip_linker_work); |
| 3159 | } | 3164 | } |
| 3160 | | 3165 | |
| 3161 | for (uav_exports.keys(), uav_exports.values()) |exported_uav, exports_list| { | 3166 | for (uav_exports.keys(), uav_exports.values()) |exported_uav, exports_list| { |
| 3162 | const exported: Zcu.Exported = .{ .uav = exported_uav }; | 3167 | const exported: Zcu.Exported = .{ .uav = exported_uav }; |
| 3163 | try pt.processExportsInner(&symbol_exports, exported, exports_list.items); | 3168 | try pt.processExportsInner(&symbol_exports, exported, exports_list.items, skip_linker_work); |
| 3164 | } | 3169 | } |
| 3165 | } | 3170 | } |
| 3166 | | 3171 | |
| ... | @@ -3171,6 +3176,7 @@ fn processExportsInner( | ... | @@ -3171,6 +3176,7 @@ fn processExportsInner( |
| 3171 | symbol_exports: *SymbolExports, | 3176 | symbol_exports: *SymbolExports, |
| 3172 | exported: Zcu.Exported, | 3177 | exported: Zcu.Exported, |
| 3173 | export_indices: []const Zcu.Export.Index, | 3178 | export_indices: []const Zcu.Export.Index, |
| | 3179 | skip_linker_work: bool, |
| 3174 | ) error{OutOfMemory}!void { | 3180 | ) error{OutOfMemory}!void { |
| 3175 | const zcu = pt.zcu; | 3181 | const zcu = pt.zcu; |
| 3176 | const gpa = zcu.gpa; | 3182 | const gpa = zcu.gpa; |
| ... | @@ -3216,13 +3222,14 @@ fn processExportsInner( | ... | @@ -3216,13 +3222,14 @@ fn processExportsInner( |
| 3216 | } | 3222 | } |
| 3217 | break :failed false; | 3223 | break :failed false; |
| 3218 | }) { | 3224 | }) { |
| 3219 | // This `Decl` is failed, so was never sent to codegen. | 3225 | // This `Nav` is failed, so was never sent to codegen. There should be a compile error. |
| 3220 | // TODO: we should probably tell the backend to delete any old exports of this `Decl`? | 3226 | assert(skip_linker_work); |
| 3221 | return; | | |
| 3222 | }, | 3227 | }, |
| 3223 | .uav => {}, | 3228 | .uav => {}, |
| 3224 | } | 3229 | } |
| 3225 | | 3230 | |
| | 3231 | if (skip_linker_work) return; |
| | 3232 | |
| 3226 | if (zcu.llvm_object) |llvm_object| { | 3233 | if (zcu.llvm_object) |llvm_object| { |
| 3227 | try zcu.handleUpdateExports(export_indices, llvm_object.updateExports(pt, exported, export_indices)); | 3234 | try zcu.handleUpdateExports(export_indices, llvm_object.updateExports(pt, exported, export_indices)); |
| 3228 | } else if (zcu.comp.bin_file) |lf| { | 3235 | } else if (zcu.comp.bin_file) |lf| { |