Commit 91eb1af917

Andrew Kelley <andrew@ziglang.org>
2022-04-03 04:12:08
stage2: more resilient error handling
* If more than one error is reported for the same Decl, the first error message is kept and the second one discarded. * Prevent functions from being sent to codegen backends if there were any errors resolving any of their parameter types or return type.
1 parent 3432e66
Changed files (2)
src/Module.zig
@@ -4854,7 +4854,12 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) Sem
         error.GenericPoison => unreachable,
         error.ComptimeReturn => unreachable,
         error.ComptimeBreak => unreachable,
-        error.AnalysisFail => {},
+        error.AnalysisFail => {
+            // In this case our function depends on a type that had a compile error.
+            // We should not try to lower this function.
+            decl.analysis = .dependency_failure;
+            return error.AnalysisFail;
+        },
         else => |e| return e,
     };
 
@@ -4867,7 +4872,12 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: Allocator) Sem
             error.GenericPoison => unreachable,
             error.ComptimeReturn => unreachable,
             error.ComptimeBreak => unreachable,
-            error.AnalysisFail => {},
+            error.AnalysisFail => {
+                // In this case our function depends on a type that had a compile error.
+                // We should not try to lower this function.
+                decl.analysis = .dependency_failure;
+                return error.AnalysisFail;
+            },
             else => |e| return e,
         };
     }
src/Sema.zig
@@ -1639,7 +1639,13 @@ fn failWithOwnedErrorMsg(sema: *Sema, block: *Block, err_msg: *Module.ErrorMsg)
         sema.owner_decl.analysis = .sema_failure;
         sema.owner_decl.generation = mod.generation;
     }
-    mod.failed_decls.putAssumeCapacityNoClobber(sema.owner_decl, err_msg);
+    const gop = mod.failed_decls.getOrPutAssumeCapacity(sema.owner_decl);
+    if (gop.found_existing) {
+        // If there are multiple errors for the same Decl, prefer the first one added.
+        err_msg.destroy(mod.gpa);
+    } else {
+        gop.value_ptr.* = err_msg;
+    }
     return error.AnalysisFail;
 }