Skip to content

Commit e44a6c3

Browse files
committed
remove support for context dependant ! fallback
The code supporting it is extremely confusing. At the same time, we have no plans to use this scheme, so there is no value in supporting it.
1 parent cf8a955 commit e44a6c3

File tree

2 files changed

+3
-98
lines changed

2 files changed

+3
-98
lines changed

compiler/rustc_hir_typeck/src/fallback.rs

Lines changed: 3 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ use std::cell::OnceCell;
22
use std::ops::ControlFlow;
33

44
use rustc_data_structures::fx::FxHashSet;
5-
use rustc_data_structures::graph::iterate::DepthFirstSearch;
65
use rustc_data_structures::graph::vec_graph::VecGraph;
76
use rustc_data_structures::graph::{self};
8-
use rustc_data_structures::unord::{UnordBag, UnordMap, UnordSet};
7+
use rustc_data_structures::unord::{UnordMap, UnordSet};
98
use rustc_hir as hir;
109
use rustc_hir::HirId;
1110
use rustc_hir::def::{DefKind, Res};
@@ -18,15 +17,12 @@ use rustc_span::{DUMMY_SP, Span};
1817
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
1918
use tracing::debug;
2019

21-
use crate::typeck_root_ctxt::InferVarInfo;
2220
use crate::{FnCtxt, errors};
2321

2422
#[derive(Copy, Clone)]
2523
pub(crate) enum DivergingFallbackBehavior {
2624
/// Always fallback to `()` (aka "always spontaneous decay")
2725
ToUnit,
28-
/// Sometimes fallback to `!`, but mainly fallback to `()` so that most of the crates are not broken.
29-
ContextDependent,
3026
/// Always fallback to `!` (which should be equivalent to never falling back + not making
3127
/// never-to-any coercions unless necessary)
3228
ToNever,
@@ -267,9 +263,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
267263
// type variable. These will typically default to `!`, unless
268264
// we find later that they are *also* reachable from some
269265
// other type variable outside this set.
270-
let mut roots_reachable_from_diverging = DepthFirstSearch::new(&coercion_graph);
271266
let mut diverging_vids = vec![];
272-
let mut non_diverging_vids = vec![];
273267
for unsolved_vid in unsolved_vids {
274268
let root_vid = self.root_var(unsolved_vid);
275269
debug!(
@@ -280,49 +274,17 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
280274
);
281275
if diverging_roots.contains(&root_vid) {
282276
diverging_vids.push(unsolved_vid);
283-
roots_reachable_from_diverging.push_start_node(root_vid);
284277

285278
debug!(
286279
"calculate_diverging_fallback: root_vid={:?} reaches {:?}",
287280
root_vid,
288281
graph::depth_first_search(&coercion_graph, root_vid).collect::<Vec<_>>()
289282
);
290-
291-
// drain the iterator to visit all nodes reachable from this node
292-
roots_reachable_from_diverging.complete_search();
293-
} else {
294-
non_diverging_vids.push(unsolved_vid);
295283
}
296284
}
297285

298-
debug!(
299-
"calculate_diverging_fallback: roots_reachable_from_diverging={:?}",
300-
roots_reachable_from_diverging,
301-
);
302-
303-
// Find all type variables N0 that are not reachable from a
304-
// diverging variable, and then compute the set reachable from
305-
// N0, which we call N. These are the *non-diverging* type
306-
// variables. (Note that this set consists of "root variables".)
307-
let mut roots_reachable_from_non_diverging = DepthFirstSearch::new(&coercion_graph);
308-
for &non_diverging_vid in &non_diverging_vids {
309-
let root_vid = self.root_var(non_diverging_vid);
310-
if roots_reachable_from_diverging.visited(root_vid) {
311-
continue;
312-
}
313-
roots_reachable_from_non_diverging.push_start_node(root_vid);
314-
roots_reachable_from_non_diverging.complete_search();
315-
}
316-
debug!(
317-
"calculate_diverging_fallback: roots_reachable_from_non_diverging={:?}",
318-
roots_reachable_from_non_diverging,
319-
);
320-
321286
debug!("obligations: {:#?}", self.fulfillment_cx.borrow_mut().pending_obligations());
322287

323-
// For each diverging variable, figure out whether it can
324-
// reach a member of N. If so, it falls back to `()`. Else
325-
// `!`.
326288
let mut diverging_fallback = UnordMap::with_capacity(diverging_vids.len());
327289
let unsafe_infer_vars = OnceCell::new();
328290

@@ -335,21 +297,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
335297
for &diverging_vid in &diverging_vids {
336298
let diverging_ty = Ty::new_var(self.tcx, diverging_vid);
337299
let root_vid = self.root_var(diverging_vid);
338-
let can_reach_non_diverging = graph::depth_first_search(&coercion_graph, root_vid)
339-
.any(|n| roots_reachable_from_non_diverging.visited(n));
340-
341-
let infer_var_infos: UnordBag<_> = self
342-
.infer_var_info
343-
.borrow()
344-
.items()
345-
.filter(|&(vid, _)| self.infcx.root_var(*vid) == root_vid)
346-
.map(|(_, info)| *info)
347-
.collect();
348-
349-
let found_infer_var_info = InferVarInfo {
350-
self_in_trait: infer_var_infos.items().any(|info| info.self_in_trait),
351-
output: infer_var_infos.items().any(|info| info.output),
352-
};
353300

354301
let mut fallback_to = |ty| {
355302
self.lint_never_type_fallback_flowing_into_unsafe_code(
@@ -366,52 +313,16 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
366313
debug!("fallback to () - legacy: {:?}", diverging_vid);
367314
fallback_to(self.tcx.types.unit);
368315
}
369-
DivergingFallbackBehavior::ContextDependent => {
370-
if found_infer_var_info.self_in_trait && found_infer_var_info.output {
371-
// This case falls back to () to ensure that the code pattern in
372-
// tests/ui/never_type/fallback-closure-ret.rs continues to
373-
// compile when never_type_fallback is enabled.
374-
//
375-
// This rule is not readily explainable from first principles,
376-
// but is rather intended as a patchwork fix to ensure code
377-
// which compiles before the stabilization of never type
378-
// fallback continues to work.
379-
//
380-
// Typically this pattern is encountered in a function taking a
381-
// closure as a parameter, where the return type of that closure
382-
// (checked by `relationship.output`) is expected to implement
383-
// some trait (checked by `relationship.self_in_trait`). This
384-
// can come up in non-closure cases too, so we do not limit this
385-
// rule to specifically `FnOnce`.
386-
//
387-
// When the closure's body is something like `panic!()`, the
388-
// return type would normally be inferred to `!`. However, it
389-
// needs to fall back to `()` in order to still compile, as the
390-
// trait is specifically implemented for `()` but not `!`.
391-
//
392-
// For details on the requirements for these relationships to be
393-
// set, see the relationship finding module in
394-
// compiler/rustc_trait_selection/src/traits/relationships.rs.
395-
debug!("fallback to () - found trait and projection: {:?}", diverging_vid);
396-
fallback_to(self.tcx.types.unit);
397-
} else if can_reach_non_diverging {
398-
debug!("fallback to () - reached non-diverging: {:?}", diverging_vid);
399-
fallback_to(self.tcx.types.unit);
400-
} else {
401-
debug!("fallback to ! - all diverging: {:?}", diverging_vid);
402-
fallback_to(self.tcx.types.never);
403-
}
404-
}
405316
DivergingFallbackBehavior::ToNever => {
406317
debug!(
407-
"fallback to ! - `rustc_never_type_mode = \"fallback_to_never\")`: {:?}",
318+
"fallback to ! - `rustc_never_type_options::falback = \"never\")`: {:?}",
408319
diverging_vid
409320
);
410321
fallback_to(self.tcx.types.never);
411322
}
412323
DivergingFallbackBehavior::NoFallback => {
413324
debug!(
414-
"no fallback - `rustc_never_type_mode = \"no_fallback\"`: {:?}",
325+
"no fallback - `rustc_never_type_options::fallback = \"no\"`: {:?}",
415326
diverging_vid
416327
);
417328
}

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -505,11 +505,6 @@ fn default_fallback(tcx: TyCtxt<'_>) -> DivergingFallbackBehavior {
505505
return DivergingFallbackBehavior::ToNever;
506506
}
507507

508-
// `feature(never_type_fallback)`: fallback to `!` or `()` trying to not break stuff
509-
if tcx.features().never_type_fallback() {
510-
return DivergingFallbackBehavior::ContextDependent;
511-
}
512-
513508
// Otherwise: fallback to `()`
514509
DivergingFallbackBehavior::ToUnit
515510
}
@@ -536,7 +531,6 @@ fn parse_never_type_options_attr(
536531
let mode = item.value_str().unwrap();
537532
match mode {
538533
sym::unit => fallback = Some(DivergingFallbackBehavior::ToUnit),
539-
sym::niko => fallback = Some(DivergingFallbackBehavior::ContextDependent),
540534
sym::never => fallback = Some(DivergingFallbackBehavior::ToNever),
541535
sym::no => fallback = Some(DivergingFallbackBehavior::NoFallback),
542536
_ => {

0 commit comments

Comments
 (0)