From 4468122f82adfc17796eebf879448aa4fb71900e Mon Sep 17 00:00:00 2001
From: Sergey Fedorov <barracuda@macos-powerpc.org>
Date: Wed, 22 Jul 2026 19:45:46 +0000
Subject: [PATCH 10/30] hir_expand: MRUSTC_LIFETIME_ERRORS=warn downgrades
 lifetime errors

The lifetime inference has known false positives (e.g. `bytes` 1.11's
Bytes::from_static path). Input crates for package builds are already
rustc-validated and lifetimes don't affect codegen, so provide an
opt-out that turns the two bound-failure errors into warnings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011M9MvswSD3mEeJcBm6S8z7
---
 src/hir_expand/lifetime_infer.cpp | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/src/hir_expand/lifetime_infer.cpp b/src/hir_expand/lifetime_infer.cpp
index 36c7bfea..4b78d7dc 100644
--- a/src/hir_expand/lifetime_infer.cpp
+++ b/src/hir_expand/lifetime_infer.cpp
@@ -9,11 +9,25 @@
 #include <hir/expr.hpp>
 #include <hir_typeck/static.hpp>
 #include <algorithm>
+#include <cstdlib>  // getenv (lifetime_errors_are_warnings)
+#include <cstring>  // strcmp
 #include <hir/expr_state.hpp>
 #include "main_bindings.hpp"
 
 
 namespace {
+    /// `MRUSTC_LIFETIME_ERRORS=warn` downgrades lifetime inference failures to warnings.
+    /// The inference has known false positives (e.g. `bytes` 1.11's `from_static`), and input
+    /// crates are normally already validated by rustc, so this is a usable escape hatch when
+    /// building third-party packages.
+    bool lifetime_errors_are_warnings() {
+        static int rv = -1;
+        if( rv < 0 ) {
+            const char* e = getenv("MRUSTC_LIFETIME_ERRORS");
+            rv = (e && ::std::strcmp(e, "warn") == 0) ? 1 : 0;
+        }
+        return rv == 1;
+    }
     struct LifetimeInferState
     {
         struct LifetimeBound {
@@ -429,6 +443,10 @@ namespace {
                     WARNING(sp, W0000, "IGNORE (in constant context) : Lifetime bound " << rhs << ": " << lhs << " failed - [" << failed_bounds << "]");
                     return ;
                 }
+                if( lifetime_errors_are_warnings() ) {
+                    WARNING(sp, W0000, "IGNORE (MRUSTC_LIFETIME_ERRORS=warn) : Lifetime bound " << rhs << ": " << lhs << " failed - [" << failed_bounds << "]");
+                    return ;
+                }
                 ERROR(sp, E0000, "Lifetime bound " << rhs << ": " << lhs << " failed - [" << failed_bounds << "]");
             }
         }
@@ -2411,6 +2429,10 @@ namespace {
                                         return ;
                                     DEBUG(dst_lft << " = " << src_real << " (" << src << ") failed: " << fails);
                                 }
+                                if( lifetime_errors_are_warnings() ) {
+                                    WARNING(sp, W0000, "IGNORE (MRUSTC_LIFETIME_ERRORS=warn) : None of erased lifetime lifetime bounds [" << dst_lfts << "]: " << src_real << " (" << src << ") passed");
+                                    return ;
+                                }
                                 ERROR(sp, E0000, "None of erased lifetime lifetime bounds [" << dst_lfts << "]: " << src_real << " (" << src << ") passed");
                             }
                         }
-- 
2.43.0

