about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fallback.rs18
-rw-r--r--compiler/rustc_span/src/symbol.rs1
3 files changed, 18 insertions, 3 deletions
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index a5f8b0b270f..e5a29f3a846 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -581,7 +581,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
 
     rustc_attr!(
-        rustc_never_type_mode, Normal, template!(NameValueStr: "fallback_to_unit|fallback_to_niko|no_fallback"), ErrorFollowing,
+        rustc_never_type_mode, Normal, template!(NameValueStr: "fallback_to_unit|fallback_to_niko|fallback_to_never|no_fallback"), ErrorFollowing,
         @only_local: true,
         "`rustc_never_type_fallback` is used to experiment with never type fallback and work on \
          never type stabilization, and will never be stable"
diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs
index 5206e79177b..c16e941d4c5 100644
--- a/compiler/rustc_hir_typeck/src/fallback.rs
+++ b/compiler/rustc_hir_typeck/src/fallback.rs
@@ -14,6 +14,9 @@ enum DivergingFallbackBehavior {
     FallbackToUnit,
     /// Sometimes fallback to `!`, but mainly fallback to `()` so that most of the crates are not broken.
     FallbackToNiko,
+    /// Always fallback to `!` (which should be equivalent to never falling back + not making
+    /// never-to-any coercions unless necessary)
+    FallbackToNever,
     /// Don't fallback at all
     NoFallback,
 }
@@ -107,9 +110,10 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         match mode {
             sym::fallback_to_unit => DivergingFallbackBehavior::FallbackToUnit,
             sym::fallback_to_niko => DivergingFallbackBehavior::FallbackToNiko,
+            sym::fallback_to_never => DivergingFallbackBehavior::FallbackToNever,
             sym::no_fallback => DivergingFallbackBehavior::NoFallback,
             _ => {
-                self.tcx.dcx().span_err(span, format!("unknown never type mode: `{mode}` (supported: `fallback_to_unit`, `fallback_to_niko`, and `no_fallback`)"));
+                self.tcx.dcx().span_err(span, format!("unknown never type mode: `{mode}` (supported: `fallback_to_unit`, `fallback_to_niko`, `fallback_to_never` and `no_fallback`)"));
 
                 DivergingFallbackBehavior::FallbackToUnit
             }
@@ -426,8 +430,18 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
                         diverging_fallback.insert(diverging_ty, self.tcx.types.never);
                     }
                 }
+                FallbackToNever => {
+                    debug!(
+                        "fallback to ! - `rustc_never_type_mode = \"fallback_to_never\")`: {:?}",
+                        diverging_vid
+                    );
+                    diverging_fallback.insert(diverging_ty, self.tcx.types.never);
+                }
                 NoFallback => {
-                    debug!("no fallback - `rustc_never_type_mode = "no_fallback"`: {:?}", diverging_vid);
+                    debug!(
+                        "no fallback - `rustc_never_type_mode = \"no_fallback\"`: {:?}",
+                        diverging_vid
+                    );
                 }
             }
         }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 0df5e7873c2..e43c9533382 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -815,6 +815,7 @@ symbols! {
         fadd_algebraic,
         fadd_fast,
         fake_variadic,
+        fallback_to_never,
         fallback_to_niko,
         fallback_to_unit,
         fdiv_algebraic,