Auto merge of #148871 - WaffleLapkin:never-simplifications, r=lcnr
Remove context dependant `!` fallback ... and minor cleanup. r? lcnr
This commit is contained in:
commit
d645a4c9c5
39 changed files with 307 additions and 713 deletions
|
|
@ -189,6 +189,8 @@ declare_features! (
|
|||
Some("subsumed by `#![feature(allocator_internals)]`")),
|
||||
/// Allows use of unary negate on unsigned integers, e.g., -e for e: u8
|
||||
(removed, negate_unsigned, "1.0.0", Some(29645), None),
|
||||
/// Allows diverging expressions to fall back to `!` rather than `()`.
|
||||
(removed, never_type_fallback, "CURRENT_RUSTC_VERSION", Some(65992), Some("removed in favor of unconditional fallback"), 148871),
|
||||
/// Allows `#[no_coverage]` on functions.
|
||||
/// The feature was renamed to `coverage_attribute` and the attribute to `#[coverage(on|off)]`
|
||||
(removed, no_coverage, "1.74.0", Some(84605), Some("renamed to `coverage_attribute`"), 114656),
|
||||
|
|
|
|||
|
|
@ -594,8 +594,6 @@ declare_features! (
|
|||
(incomplete, never_patterns, "1.76.0", Some(118155)),
|
||||
/// Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more.
|
||||
(unstable, never_type, "1.13.0", Some(35121)),
|
||||
/// Allows diverging expressions to fall back to `!` rather than `()`.
|
||||
(unstable, never_type_fallback, "1.41.0", Some(65992)),
|
||||
/// Switch `..` syntax to use the new (`Copy + IntoIterator`) range types.
|
||||
(unstable, new_range, "1.86.0", Some(123741)),
|
||||
/// Allows `#![no_core]`.
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
|
|||
// so we can just make the hidden type be `!`.
|
||||
// For backwards compatibility reasons, we fall back to
|
||||
// `()` until we the diverging default is changed.
|
||||
EarlyBinder::bind(Ty::new_diverging_default(tcx))
|
||||
EarlyBinder::bind(tcx.types.unit)
|
||||
}
|
||||
}
|
||||
DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(owner_def_id) {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@ use std::cell::OnceCell;
|
|||
use std::ops::ControlFlow;
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::graph::iterate::DepthFirstSearch;
|
||||
use rustc_data_structures::graph::vec_graph::VecGraph;
|
||||
use rustc_data_structures::graph::{self};
|
||||
use rustc_data_structures::unord::{UnordBag, UnordMap, UnordSet};
|
||||
use rustc_data_structures::unord::{UnordMap, UnordSet};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::HirId;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
|
|
@ -18,15 +17,12 @@ use rustc_span::{DUMMY_SP, Span};
|
|||
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::typeck_root_ctxt::InferVarInfo;
|
||||
use crate::{FnCtxt, errors};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub(crate) enum DivergingFallbackBehavior {
|
||||
/// Always fallback to `()` (aka "always spontaneous decay")
|
||||
ToUnit,
|
||||
/// Sometimes fallback to `!`, but mainly fallback to `()` so that most of the crates are not broken.
|
||||
ContextDependent,
|
||||
/// Always fallback to `!` (which should be equivalent to never falling back + not making
|
||||
/// never-to-any coercions unless necessary)
|
||||
ToNever,
|
||||
|
|
@ -35,8 +31,8 @@ pub(crate) enum DivergingFallbackBehavior {
|
|||
}
|
||||
|
||||
impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||
/// Performs type inference fallback, setting `FnCtxt::fallback_has_occurred`
|
||||
/// if fallback has occurred.
|
||||
/// Performs type inference fallback, setting [`FnCtxt::diverging_fallback_has_occurred`]
|
||||
/// if the never type fallback has occurred.
|
||||
pub(super) fn type_inference_fallback(&self) {
|
||||
debug!(
|
||||
"type-inference-fallback start obligations: {:#?}",
|
||||
|
|
@ -53,34 +49,10 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
|||
|
||||
let fallback_occurred = self.fallback_types();
|
||||
|
||||
if !fallback_occurred {
|
||||
return;
|
||||
if fallback_occurred {
|
||||
// if fallback occurred, previously stalled goals may make progress again
|
||||
self.select_obligations_where_possible(|_| {});
|
||||
}
|
||||
|
||||
// We now see if we can make progress. This might cause us to
|
||||
// unify inference variables for opaque types, since we may
|
||||
// have unified some other type variables during the first
|
||||
// phase of fallback. This means that we only replace
|
||||
// inference variables with their underlying opaque types as a
|
||||
// last resort.
|
||||
//
|
||||
// In code like this:
|
||||
//
|
||||
// ```rust
|
||||
// type MyType = impl Copy;
|
||||
// fn produce() -> MyType { true }
|
||||
// fn bad_produce() -> MyType { panic!() }
|
||||
// ```
|
||||
//
|
||||
// we want to unify the opaque inference variable in `bad_produce`
|
||||
// with the diverging fallback for `panic!` (e.g. `()` or `!`).
|
||||
// This will produce a nice error message about conflicting concrete
|
||||
// types for `MyType`.
|
||||
//
|
||||
// If we had tried to fallback the opaque inference variable to `MyType`,
|
||||
// we will generate a confusing type-check error that does not explicitly
|
||||
// refer to opaque types.
|
||||
self.select_obligations_where_possible(|_| {});
|
||||
}
|
||||
|
||||
fn fallback_types(&self) -> bool {
|
||||
|
|
@ -91,8 +63,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
|||
return false;
|
||||
}
|
||||
|
||||
let diverging_fallback = self
|
||||
.calculate_diverging_fallback(&unresolved_variables, self.diverging_fallback_behavior);
|
||||
let (diverging_fallback, diverging_fallback_ty) =
|
||||
self.calculate_diverging_fallback(&unresolved_variables);
|
||||
|
||||
// We do fallback in two passes, to try to generate
|
||||
// better error messages.
|
||||
|
|
@ -100,31 +72,33 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
|||
let mut fallback_occurred = false;
|
||||
for ty in unresolved_variables {
|
||||
debug!("unsolved_variable = {:?}", ty);
|
||||
fallback_occurred |= self.fallback_if_possible(ty, &diverging_fallback);
|
||||
fallback_occurred |=
|
||||
self.fallback_if_possible(ty, &diverging_fallback, diverging_fallback_ty);
|
||||
}
|
||||
|
||||
fallback_occurred
|
||||
}
|
||||
|
||||
// Tries to apply a fallback to `ty` if it is an unsolved variable.
|
||||
//
|
||||
// - Unconstrained ints are replaced with `i32`.
|
||||
//
|
||||
// - Unconstrained floats are replaced with `f64`.
|
||||
//
|
||||
// - Non-numerics may get replaced with `()` or `!`, depending on
|
||||
// how they were categorized by `calculate_diverging_fallback`
|
||||
// (and the setting of `#![feature(never_type_fallback)]`).
|
||||
//
|
||||
// Fallback becomes very dubious if we have encountered
|
||||
// type-checking errors. In that case, fallback to Error.
|
||||
//
|
||||
// Sets `FnCtxt::fallback_has_occurred` if fallback is performed
|
||||
// during this call.
|
||||
/// Tries to apply a fallback to `ty` if it is an unsolved variable.
|
||||
///
|
||||
/// - Unconstrained ints are replaced with `i32`.
|
||||
///
|
||||
/// - Unconstrained floats are replaced with `f64`.
|
||||
///
|
||||
/// - Non-numerics may get replaced with `()` or `!`, depending on how they
|
||||
/// were categorized by [`Self::calculate_diverging_fallback`], crate's
|
||||
/// edition, and the setting of `#![rustc_never_type_options(fallback = ...)]`.
|
||||
///
|
||||
/// Fallback becomes very dubious if we have encountered
|
||||
/// type-checking errors. In that case, fallback to Error.
|
||||
///
|
||||
/// Sets [`FnCtxt::diverging_fallback_has_occurred`] if never type fallback
|
||||
/// is performed during this call.
|
||||
fn fallback_if_possible(
|
||||
&self,
|
||||
ty: Ty<'tcx>,
|
||||
diverging_fallback: &UnordMap<Ty<'tcx>, Ty<'tcx>>,
|
||||
diverging_fallback: &UnordSet<Ty<'tcx>>,
|
||||
diverging_fallback_ty: Ty<'tcx>,
|
||||
) -> bool {
|
||||
// Careful: we do NOT shallow-resolve `ty`. We know that `ty`
|
||||
// is an unsolved variable, and we determine its fallback
|
||||
|
|
@ -148,93 +122,34 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
|||
_ if let Some(e) = self.tainted_by_errors() => Ty::new_error(self.tcx, e),
|
||||
ty::Infer(ty::IntVar(_)) => self.tcx.types.i32,
|
||||
ty::Infer(ty::FloatVar(_)) => self.tcx.types.f64,
|
||||
_ => match diverging_fallback.get(&ty) {
|
||||
Some(&fallback_ty) => fallback_ty,
|
||||
None => return false,
|
||||
},
|
||||
_ if diverging_fallback.contains(&ty) => {
|
||||
self.diverging_fallback_has_occurred.set(true);
|
||||
diverging_fallback_ty
|
||||
}
|
||||
_ => return false,
|
||||
};
|
||||
debug!("fallback_if_possible(ty={:?}): defaulting to `{:?}`", ty, fallback);
|
||||
|
||||
let span = ty.ty_vid().map_or(DUMMY_SP, |vid| self.infcx.type_var_origin(vid).span);
|
||||
self.demand_eqtype(span, ty, fallback);
|
||||
self.fallback_has_occurred.set(true);
|
||||
true
|
||||
}
|
||||
|
||||
/// The "diverging fallback" system is rather complicated. This is
|
||||
/// a result of our need to balance 'do the right thing' with
|
||||
/// backwards compatibility.
|
||||
///
|
||||
/// "Diverging" type variables are variables created when we
|
||||
/// coerce a `!` type into an unbound type variable `?X`. If they
|
||||
/// never wind up being constrained, the "right and natural" thing
|
||||
/// is that `?X` should "fallback" to `!`. This means that e.g. an
|
||||
/// expression like `Some(return)` will ultimately wind up with a
|
||||
/// type like `Option<!>` (presuming it is not assigned or
|
||||
/// constrained to have some other type).
|
||||
///
|
||||
/// However, the fallback used to be `()` (before the `!` type was
|
||||
/// added). Moreover, there are cases where the `!` type 'leaks
|
||||
/// out' from dead code into type variables that affect live
|
||||
/// code. The most common case is something like this:
|
||||
///
|
||||
/// ```rust
|
||||
/// # fn foo() -> i32 { 4 }
|
||||
/// match foo() {
|
||||
/// 22 => Default::default(), // call this type `?D`
|
||||
/// _ => return, // return has type `!`
|
||||
/// } // call the type of this match `?M`
|
||||
/// ```
|
||||
///
|
||||
/// Here, coercing the type `!` into `?M` will create a diverging
|
||||
/// type variable `?X` where `?X <: ?M`. We also have that `?D <:
|
||||
/// ?M`. If `?M` winds up unconstrained, then `?X` will
|
||||
/// fallback. If it falls back to `!`, then all the type variables
|
||||
/// will wind up equal to `!` -- this includes the type `?D`
|
||||
/// (since `!` doesn't implement `Default`, we wind up a "trait
|
||||
/// not implemented" error in code like this). But since the
|
||||
/// original fallback was `()`, this code used to compile with `?D
|
||||
/// = ()`. This is somewhat surprising, since `Default::default()`
|
||||
/// on its own would give an error because the types are
|
||||
/// insufficiently constrained.
|
||||
///
|
||||
/// Our solution to this dilemma is to modify diverging variables
|
||||
/// so that they can *either* fallback to `!` (the default) or to
|
||||
/// `()` (the backwards compatibility case). We decide which
|
||||
/// fallback to use based on whether there is a coercion pattern
|
||||
/// like this:
|
||||
///
|
||||
/// ```ignore (not-rust)
|
||||
/// ?Diverging -> ?V
|
||||
/// ?NonDiverging -> ?V
|
||||
/// ?V != ?NonDiverging
|
||||
/// ```
|
||||
///
|
||||
/// Here `?Diverging` represents some diverging type variable and
|
||||
/// `?NonDiverging` represents some non-diverging type
|
||||
/// variable. `?V` can be any type variable (diverging or not), so
|
||||
/// long as it is not equal to `?NonDiverging`.
|
||||
///
|
||||
/// Intuitively, what we are looking for is a case where a
|
||||
/// "non-diverging" type variable (like `?M` in our example above)
|
||||
/// is coerced *into* some variable `?V` that would otherwise
|
||||
/// fallback to `!`. In that case, we make `?V` fallback to `!`,
|
||||
/// along with anything that would flow into `?V`.
|
||||
///
|
||||
/// The algorithm we use:
|
||||
/// * Identify all variables that are coerced *into* by a
|
||||
/// diverging variable. Do this by iterating over each
|
||||
/// diverging, unsolved variable and finding all variables
|
||||
/// reachable from there. Call that set `D`.
|
||||
/// * Walk over all unsolved, non-diverging variables, and find
|
||||
/// any variable that has an edge into `D`.
|
||||
fn calculate_diverging_fallback(
|
||||
&self,
|
||||
unresolved_variables: &[Ty<'tcx>],
|
||||
behavior: DivergingFallbackBehavior,
|
||||
) -> UnordMap<Ty<'tcx>, Ty<'tcx>> {
|
||||
) -> (UnordSet<Ty<'tcx>>, Ty<'tcx>) {
|
||||
debug!("calculate_diverging_fallback({:?})", unresolved_variables);
|
||||
|
||||
let diverging_fallback_ty = match self.diverging_fallback_behavior {
|
||||
DivergingFallbackBehavior::ToUnit => self.tcx.types.unit,
|
||||
DivergingFallbackBehavior::ToNever => self.tcx.types.never,
|
||||
DivergingFallbackBehavior::NoFallback => {
|
||||
// the type doesn't matter, since no fallback will occur
|
||||
return (UnordSet::new(), self.tcx.types.unit);
|
||||
}
|
||||
};
|
||||
|
||||
// Construct a coercion graph where an edge `A -> B` indicates
|
||||
// a type variable is that is coerced
|
||||
let coercion_graph = self.create_coercion_graph();
|
||||
|
|
@ -267,9 +182,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
|||
// type variable. These will typically default to `!`, unless
|
||||
// we find later that they are *also* reachable from some
|
||||
// other type variable outside this set.
|
||||
let mut roots_reachable_from_diverging = DepthFirstSearch::new(&coercion_graph);
|
||||
let mut diverging_vids = vec![];
|
||||
let mut non_diverging_vids = vec![];
|
||||
for unsolved_vid in unsolved_vids {
|
||||
let root_vid = self.root_var(unsolved_vid);
|
||||
debug!(
|
||||
|
|
@ -280,54 +193,21 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
|||
);
|
||||
if diverging_roots.contains(&root_vid) {
|
||||
diverging_vids.push(unsolved_vid);
|
||||
roots_reachable_from_diverging.push_start_node(root_vid);
|
||||
|
||||
debug!(
|
||||
"calculate_diverging_fallback: root_vid={:?} reaches {:?}",
|
||||
root_vid,
|
||||
graph::depth_first_search(&coercion_graph, root_vid).collect::<Vec<_>>()
|
||||
);
|
||||
|
||||
// drain the iterator to visit all nodes reachable from this node
|
||||
roots_reachable_from_diverging.complete_search();
|
||||
} else {
|
||||
non_diverging_vids.push(unsolved_vid);
|
||||
}
|
||||
}
|
||||
|
||||
debug!(
|
||||
"calculate_diverging_fallback: roots_reachable_from_diverging={:?}",
|
||||
roots_reachable_from_diverging,
|
||||
);
|
||||
|
||||
// Find all type variables N0 that are not reachable from a
|
||||
// diverging variable, and then compute the set reachable from
|
||||
// N0, which we call N. These are the *non-diverging* type
|
||||
// variables. (Note that this set consists of "root variables".)
|
||||
let mut roots_reachable_from_non_diverging = DepthFirstSearch::new(&coercion_graph);
|
||||
for &non_diverging_vid in &non_diverging_vids {
|
||||
let root_vid = self.root_var(non_diverging_vid);
|
||||
if roots_reachable_from_diverging.visited(root_vid) {
|
||||
continue;
|
||||
}
|
||||
roots_reachable_from_non_diverging.push_start_node(root_vid);
|
||||
roots_reachable_from_non_diverging.complete_search();
|
||||
}
|
||||
debug!(
|
||||
"calculate_diverging_fallback: roots_reachable_from_non_diverging={:?}",
|
||||
roots_reachable_from_non_diverging,
|
||||
);
|
||||
|
||||
debug!("obligations: {:#?}", self.fulfillment_cx.borrow_mut().pending_obligations());
|
||||
|
||||
// For each diverging variable, figure out whether it can
|
||||
// reach a member of N. If so, it falls back to `()`. Else
|
||||
// `!`.
|
||||
let mut diverging_fallback = UnordMap::with_capacity(diverging_vids.len());
|
||||
let mut diverging_fallback = UnordSet::with_capacity(diverging_vids.len());
|
||||
let unsafe_infer_vars = OnceCell::new();
|
||||
|
||||
self.lint_obligations_broken_by_never_type_fallback_change(
|
||||
behavior,
|
||||
&diverging_vids,
|
||||
&coercion_graph,
|
||||
);
|
||||
|
|
@ -335,90 +215,17 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
|||
for &diverging_vid in &diverging_vids {
|
||||
let diverging_ty = Ty::new_var(self.tcx, diverging_vid);
|
||||
let root_vid = self.root_var(diverging_vid);
|
||||
let can_reach_non_diverging = graph::depth_first_search(&coercion_graph, root_vid)
|
||||
.any(|n| roots_reachable_from_non_diverging.visited(n));
|
||||
|
||||
let infer_var_infos: UnordBag<_> = self
|
||||
.infer_var_info
|
||||
.borrow()
|
||||
.items()
|
||||
.filter(|&(vid, _)| self.infcx.root_var(*vid) == root_vid)
|
||||
.map(|(_, info)| *info)
|
||||
.collect();
|
||||
self.lint_never_type_fallback_flowing_into_unsafe_code(
|
||||
&unsafe_infer_vars,
|
||||
&coercion_graph,
|
||||
root_vid,
|
||||
);
|
||||
|
||||
let found_infer_var_info = InferVarInfo {
|
||||
self_in_trait: infer_var_infos.items().any(|info| info.self_in_trait),
|
||||
output: infer_var_infos.items().any(|info| info.output),
|
||||
};
|
||||
|
||||
let mut fallback_to = |ty| {
|
||||
self.lint_never_type_fallback_flowing_into_unsafe_code(
|
||||
&unsafe_infer_vars,
|
||||
&coercion_graph,
|
||||
root_vid,
|
||||
);
|
||||
|
||||
diverging_fallback.insert(diverging_ty, ty);
|
||||
};
|
||||
|
||||
match behavior {
|
||||
DivergingFallbackBehavior::ToUnit => {
|
||||
debug!("fallback to () - legacy: {:?}", diverging_vid);
|
||||
fallback_to(self.tcx.types.unit);
|
||||
}
|
||||
DivergingFallbackBehavior::ContextDependent => {
|
||||
if found_infer_var_info.self_in_trait && found_infer_var_info.output {
|
||||
// This case falls back to () to ensure that the code pattern in
|
||||
// tests/ui/never_type/fallback-closure-ret.rs continues to
|
||||
// compile when never_type_fallback is enabled.
|
||||
//
|
||||
// This rule is not readily explainable from first principles,
|
||||
// but is rather intended as a patchwork fix to ensure code
|
||||
// which compiles before the stabilization of never type
|
||||
// fallback continues to work.
|
||||
//
|
||||
// Typically this pattern is encountered in a function taking a
|
||||
// closure as a parameter, where the return type of that closure
|
||||
// (checked by `relationship.output`) is expected to implement
|
||||
// some trait (checked by `relationship.self_in_trait`). This
|
||||
// can come up in non-closure cases too, so we do not limit this
|
||||
// rule to specifically `FnOnce`.
|
||||
//
|
||||
// When the closure's body is something like `panic!()`, the
|
||||
// return type would normally be inferred to `!`. However, it
|
||||
// needs to fall back to `()` in order to still compile, as the
|
||||
// trait is specifically implemented for `()` but not `!`.
|
||||
//
|
||||
// For details on the requirements for these relationships to be
|
||||
// set, see the relationship finding module in
|
||||
// compiler/rustc_trait_selection/src/traits/relationships.rs.
|
||||
debug!("fallback to () - found trait and projection: {:?}", diverging_vid);
|
||||
fallback_to(self.tcx.types.unit);
|
||||
} else if can_reach_non_diverging {
|
||||
debug!("fallback to () - reached non-diverging: {:?}", diverging_vid);
|
||||
fallback_to(self.tcx.types.unit);
|
||||
} else {
|
||||
debug!("fallback to ! - all diverging: {:?}", diverging_vid);
|
||||
fallback_to(self.tcx.types.never);
|
||||
}
|
||||
}
|
||||
DivergingFallbackBehavior::ToNever => {
|
||||
debug!(
|
||||
"fallback to ! - `rustc_never_type_mode = \"fallback_to_never\")`: {:?}",
|
||||
diverging_vid
|
||||
);
|
||||
fallback_to(self.tcx.types.never);
|
||||
}
|
||||
DivergingFallbackBehavior::NoFallback => {
|
||||
debug!(
|
||||
"no fallback - `rustc_never_type_mode = \"no_fallback\"`: {:?}",
|
||||
diverging_vid
|
||||
);
|
||||
}
|
||||
}
|
||||
diverging_fallback.insert(diverging_ty);
|
||||
}
|
||||
|
||||
diverging_fallback
|
||||
(diverging_fallback, diverging_fallback_ty)
|
||||
}
|
||||
|
||||
fn lint_never_type_fallback_flowing_into_unsafe_code(
|
||||
|
|
@ -470,11 +277,10 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
|||
|
||||
fn lint_obligations_broken_by_never_type_fallback_change(
|
||||
&self,
|
||||
behavior: DivergingFallbackBehavior,
|
||||
diverging_vids: &[ty::TyVid],
|
||||
coercions: &VecGraph<ty::TyVid, true>,
|
||||
) {
|
||||
let DivergingFallbackBehavior::ToUnit = behavior else { return };
|
||||
let DivergingFallbackBehavior::ToUnit = self.diverging_fallback_behavior else { return };
|
||||
|
||||
// Fallback happens if and only if there are diverging variables
|
||||
if diverging_vids.is_empty() {
|
||||
|
|
|
|||
|
|
@ -115,7 +115,9 @@ pub(crate) struct FnCtxt<'a, 'tcx> {
|
|||
|
||||
pub(super) root_ctxt: &'a TypeckRootCtxt<'tcx>,
|
||||
|
||||
pub(super) fallback_has_occurred: Cell<bool>,
|
||||
/// True if a divirging inference variable has been set to `()`/`!` because
|
||||
/// of never type fallback. This is only used for diagnostics.
|
||||
pub(super) diverging_fallback_has_occurred: Cell<bool>,
|
||||
|
||||
pub(super) diverging_fallback_behavior: DivergingFallbackBehavior,
|
||||
pub(super) diverging_block_behavior: DivergingBlockBehavior,
|
||||
|
|
@ -153,7 +155,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
by_id: Default::default(),
|
||||
}),
|
||||
root_ctxt,
|
||||
fallback_has_occurred: Cell::new(false),
|
||||
diverging_fallback_has_occurred: Cell::new(false),
|
||||
diverging_fallback_behavior,
|
||||
diverging_block_behavior,
|
||||
trait_ascriptions: Default::default(),
|
||||
|
|
@ -190,7 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
TypeErrCtxt {
|
||||
infcx: &self.infcx,
|
||||
typeck_results: Some(self.typeck_results.borrow()),
|
||||
fallback_has_occurred: self.fallback_has_occurred.get(),
|
||||
diverging_fallback_has_occurred: self.diverging_fallback_has_occurred.get(),
|
||||
normalize_fn_sig: Box::new(|fn_sig| {
|
||||
if fn_sig.has_escaping_bound_vars() {
|
||||
return fn_sig;
|
||||
|
|
@ -505,11 +507,6 @@ fn default_fallback(tcx: TyCtxt<'_>) -> DivergingFallbackBehavior {
|
|||
return DivergingFallbackBehavior::ToNever;
|
||||
}
|
||||
|
||||
// `feature(never_type_fallback)`: fallback to `!` or `()` trying to not break stuff
|
||||
if tcx.features().never_type_fallback() {
|
||||
return DivergingFallbackBehavior::ContextDependent;
|
||||
}
|
||||
|
||||
// Otherwise: fallback to `()`
|
||||
DivergingFallbackBehavior::ToUnit
|
||||
}
|
||||
|
|
@ -536,7 +533,6 @@ fn parse_never_type_options_attr(
|
|||
let mode = item.value_str().unwrap();
|
||||
match mode {
|
||||
sym::unit => fallback = Some(DivergingFallbackBehavior::ToUnit),
|
||||
sym::niko => fallback = Some(DivergingFallbackBehavior::ContextDependent),
|
||||
sym::never => fallback = Some(DivergingFallbackBehavior::ToNever),
|
||||
sym::no => fallback = Some(DivergingFallbackBehavior::NoFallback),
|
||||
_ => {
|
||||
|
|
|
|||
|
|
@ -1,35 +1,19 @@
|
|||
use std::cell::{Cell, RefCell};
|
||||
use std::ops::Deref;
|
||||
|
||||
use rustc_data_structures::unord::{UnordMap, UnordSet};
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::{self as hir, HirId, HirIdMap, LangItem};
|
||||
use rustc_hir::{self as hir, HirId, HirIdMap};
|
||||
use rustc_infer::infer::{InferCtxt, InferOk, OpaqueTypeStorageEntries, TyCtxtInferExt};
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypingMode};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::def_id::LocalDefIdMap;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::{
|
||||
self, FulfillmentError, PredicateObligation, TraitEngine, TraitEngineExt as _,
|
||||
};
|
||||
use tracing::{debug, instrument};
|
||||
use rustc_trait_selection::traits::{self, FulfillmentError, TraitEngine, TraitEngineExt as _};
|
||||
use tracing::instrument;
|
||||
|
||||
use super::callee::DeferredCallResolution;
|
||||
|
||||
#[derive(Debug, Default, Copy, Clone)]
|
||||
pub(crate) struct InferVarInfo {
|
||||
/// This is true if we identified that this Ty (`?T`) is found in a `?T: Foo`
|
||||
/// obligation, where:
|
||||
///
|
||||
/// * `Foo` is not `Sized`
|
||||
/// * `(): Foo` may be satisfied
|
||||
pub self_in_trait: bool,
|
||||
/// This is true if we identified that this Ty (`?T`) is found in a `<_ as
|
||||
/// _>::AssocType = ?T`
|
||||
pub output: bool,
|
||||
}
|
||||
|
||||
/// Data shared between a "typeck root" and its nested bodies,
|
||||
/// e.g. closures defined within the function. For example:
|
||||
/// ```ignore (illustrative)
|
||||
|
|
@ -83,8 +67,6 @@ pub(crate) struct TypeckRootCtxt<'tcx> {
|
|||
/// we record that type variable here. This is later used to inform
|
||||
/// fallback. See the `fallback` module for details.
|
||||
pub(super) diverging_type_vars: RefCell<UnordSet<Ty<'tcx>>>,
|
||||
|
||||
pub(super) infer_var_info: RefCell<UnordMap<ty::TyVid, InferVarInfo>>,
|
||||
}
|
||||
|
||||
impl<'tcx> Deref for TypeckRootCtxt<'tcx> {
|
||||
|
|
@ -119,7 +101,6 @@ impl<'tcx> TypeckRootCtxt<'tcx> {
|
|||
deferred_asm_checks: RefCell::new(Vec::new()),
|
||||
deferred_repeat_expr_checks: RefCell::new(Vec::new()),
|
||||
diverging_type_vars: RefCell::new(Default::default()),
|
||||
infer_var_info: RefCell::new(Default::default()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -129,8 +110,6 @@ impl<'tcx> TypeckRootCtxt<'tcx> {
|
|||
span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
|
||||
}
|
||||
|
||||
self.update_infer_var_info(&obligation);
|
||||
|
||||
self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
|
||||
}
|
||||
|
||||
|
|
@ -147,46 +126,4 @@ impl<'tcx> TypeckRootCtxt<'tcx> {
|
|||
self.register_predicates(infer_ok.obligations);
|
||||
infer_ok.value
|
||||
}
|
||||
|
||||
fn update_infer_var_info(&self, obligation: &PredicateObligation<'tcx>) {
|
||||
let infer_var_info = &mut self.infer_var_info.borrow_mut();
|
||||
|
||||
// (*) binder skipped
|
||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(tpred)) =
|
||||
obligation.predicate.kind().skip_binder()
|
||||
&& let Some(ty) =
|
||||
self.shallow_resolve(tpred.self_ty()).ty_vid().map(|t| self.root_var(t))
|
||||
&& !self.tcx.is_lang_item(tpred.trait_ref.def_id, LangItem::Sized)
|
||||
{
|
||||
let new_self_ty = self.tcx.types.unit;
|
||||
|
||||
// Then construct a new obligation with Self = () added
|
||||
// to the ParamEnv, and see if it holds.
|
||||
let o = obligation.with(
|
||||
self.tcx,
|
||||
obligation.predicate.kind().rebind(
|
||||
// (*) binder moved here
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(
|
||||
tpred.with_replaced_self_ty(self.tcx, new_self_ty),
|
||||
)),
|
||||
),
|
||||
);
|
||||
// Don't report overflow errors. Otherwise equivalent to may_hold.
|
||||
if let Ok(result) = self.probe(|_| self.evaluate_obligation(&o))
|
||||
&& result.may_apply()
|
||||
{
|
||||
infer_var_info.entry(ty).or_default().self_in_trait = true;
|
||||
}
|
||||
}
|
||||
|
||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) =
|
||||
obligation.predicate.kind().skip_binder()
|
||||
// If the projection predicate (Foo::Bar == X) has X as a non-TyVid,
|
||||
// we need to make it into one.
|
||||
&& let Some(vid) = predicate.term.as_type().and_then(|ty| ty.ty_vid())
|
||||
{
|
||||
debug!("infer_var_info: {:?}.output = true", vid);
|
||||
infer_var_info.entry(vid).or_default().output = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -878,11 +878,6 @@ impl<'tcx> Ty<'tcx> {
|
|||
Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, tcx.types.str_)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn new_diverging_default(tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
if tcx.features().never_type_fallback() { tcx.types.never } else { tcx.types.unit }
|
||||
}
|
||||
|
||||
// lang and diagnostic tys
|
||||
|
||||
fn new_generic_adt(tcx: TyCtxt<'tcx>, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx> {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ pub struct TypeErrCtxt<'a, 'tcx> {
|
|||
pub infcx: &'a InferCtxt<'tcx>,
|
||||
|
||||
pub typeck_results: Option<std::cell::Ref<'a, ty::TypeckResults<'tcx>>>,
|
||||
pub fallback_has_occurred: bool,
|
||||
pub diverging_fallback_has_occurred: bool,
|
||||
|
||||
pub normalize_fn_sig: Box<dyn Fn(ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx> + 'a>,
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
TypeErrCtxt {
|
||||
infcx: self,
|
||||
typeck_results: None,
|
||||
fallback_has_occurred: false,
|
||||
diverging_fallback_has_occurred: false,
|
||||
normalize_fn_sig: Box::new(|fn_sig| fn_sig),
|
||||
autoderef_steps: Box::new(|ty| {
|
||||
debug_assert!(false, "shouldn't be using autoderef_steps outside of typeck");
|
||||
|
|
|
|||
|
|
@ -541,7 +541,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
// variable that used to fallback to `()` now falling back to `!`. Issue a
|
||||
// note informing about the change in behaviour.
|
||||
if leaf_trait_predicate.skip_binder().self_ty().is_never()
|
||||
&& self.fallback_has_occurred
|
||||
&& self.diverging_fallback_has_occurred
|
||||
{
|
||||
let predicate = leaf_trait_predicate.map_bound(|trait_pred| {
|
||||
trait_pred.with_replaced_self_ty(self.tcx, tcx.types.unit)
|
||||
|
|
@ -550,8 +550,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
if self.predicate_may_hold(&unit_obligation) {
|
||||
err.note(
|
||||
"this error might have been caused by changes to \
|
||||
Rust's type-inference algorithm (see issue #48950 \
|
||||
<https://github.com/rust-lang/rust/issues/48950> \
|
||||
Rust's type-inference algorithm (see issue #148922 \
|
||||
<https://github.com/rust-lang/rust/issues/148922> \
|
||||
for more information)",
|
||||
);
|
||||
err.help("you might have intended to use the type `()` here instead");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//@ run-pass
|
||||
//@ edition: 2024
|
||||
|
||||
#![feature(never_type, never_type_fallback)]
|
||||
#![feature(never_type)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
|
||||
#![allow(unreachable_patterns)]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
|
||||
--> $DIR/coerce-issue-49593-box-never.rs:18:5
|
||||
--> $DIR/coerce-issue-49593-box-never.rs:17:5
|
||||
|
|
||||
LL | Box::<_ /* ! */>::new(x)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
||||
|
|
@ -7,7 +7,7 @@ LL | Box::<_ /* ! */>::new(x)
|
|||
= note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
|
||||
|
||||
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
|
||||
--> $DIR/coerce-issue-49593-box-never.rs:24:5
|
||||
--> $DIR/coerce-issue-49593-box-never.rs:23:5
|
||||
|
|
||||
LL | raw_ptr_box::<_ /* ! */>(x)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
//@ revisions: nofallback fallback
|
||||
//@[fallback] edition: 2024
|
||||
//@[fallback] check-pass
|
||||
|
||||
#![feature(never_type)]
|
||||
#![cfg_attr(fallback, feature(never_type_fallback))]
|
||||
#![allow(unreachable_code)]
|
||||
|
||||
use std::error::Error;
|
||||
use std::mem;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ error[E0277]: the trait bound `!: Default` is not satisfied
|
|||
LL | true => Default::default(),
|
||||
| ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
|
||||
|
|
||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
|
||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
|
||||
= help: you might have intended to use the type `()` here instead
|
||||
|
||||
error[E0277]: the trait bound `!: Default` is not satisfied
|
||||
|
|
@ -13,7 +13,7 @@ error[E0277]: the trait bound `!: Default` is not satisfied
|
|||
LL | deserialize()?;
|
||||
| ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
|
||||
|
|
||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
|
||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
|
||||
= help: you might have intended to use the type `()` here instead
|
||||
note: required by a bound in `deserialize`
|
||||
--> $DIR/never-type-fallback-breaking.rs:31:23
|
||||
|
|
@ -50,7 +50,7 @@ error[E0277]: the trait bound `!: Default` is not satisfied
|
|||
LL | takes_apit(|| Default::default())?;
|
||||
| ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
|
||||
|
|
||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
|
||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
|
||||
= help: you might have intended to use the type `()` here instead
|
||||
|
||||
error[E0277]: the trait bound `!: Default` is not satisfied
|
||||
|
|
@ -61,7 +61,7 @@ LL | takes_apit2(mk()?);
|
|||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
|
||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
|
||||
= help: you might have intended to use the type `()` here instead
|
||||
note: required by a bound in `takes_apit2`
|
||||
--> $DIR/never-type-fallback-breaking.rs:69:25
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied
|
||||
--> $DIR/defaulted-never-note.rs:31:9
|
||||
--> $DIR/defaulted-never-note.rs:27:9
|
||||
|
|
||||
LL | foo(_x);
|
||||
| --- ^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!`
|
||||
|
|
@ -7,14 +7,14 @@ LL | foo(_x);
|
|||
| required by a bound introduced by this call
|
||||
|
|
||||
help: the trait `ImplementedForUnitButNotNever` is implemented for `()`
|
||||
--> $DIR/defaulted-never-note.rs:24:1
|
||||
--> $DIR/defaulted-never-note.rs:20:1
|
||||
|
|
||||
LL | impl ImplementedForUnitButNotNever for () {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
|
||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
|
||||
= help: you might have intended to use the type `()` here instead
|
||||
note: required by a bound in `foo`
|
||||
--> $DIR/defaulted-never-note.rs:26:11
|
||||
--> $DIR/defaulted-never-note.rs:22:11
|
||||
|
|
||||
LL | fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
Future incompatibility report: Future breakage diagnostic:
|
||||
warning: this function depends on never type fallback being `()`
|
||||
--> $DIR/defaulted-never-note.rs:29:1
|
||||
--> $DIR/defaulted-never-note.rs:25:1
|
||||
|
|
||||
LL | fn smeg() {
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: specify the types explicitly
|
||||
note: in edition 2024, the requirement `!: ImplementedForUnitButNotNever` will fail
|
||||
--> $DIR/defaulted-never-note.rs:31:9
|
||||
--> $DIR/defaulted-never-note.rs:27:9
|
||||
|
|
||||
LL | foo(_x);
|
||||
| ^^
|
||||
|
|
|
|||
|
|
@ -1,13 +1,9 @@
|
|||
//@ revisions: nofallback fallback
|
||||
//@[fallback] edition: 2024
|
||||
//@[nofallback] run-pass
|
||||
//@[fallback] check-fail
|
||||
|
||||
// We need to opt into the `never_type_fallback` feature
|
||||
// to trigger the requirement that this is testing.
|
||||
#![cfg_attr(fallback, feature(never_type, never_type_fallback))]
|
||||
|
||||
#![allow(unused)]
|
||||
#![expect(dependency_on_unit_never_type_fallback)]
|
||||
#![expect(dependency_on_unit_never_type_fallback, unused)]
|
||||
|
||||
trait Deserialize: Sized {
|
||||
fn deserialize() -> Result<Self, String>;
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
Future incompatibility report: Future breakage diagnostic:
|
||||
warning: this function depends on never type fallback being `()`
|
||||
--> $DIR/diverging-fallback-control-flow.rs:32:1
|
||||
|
|
||||
LL | fn assignment() {
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: specify the types explicitly
|
||||
note: in edition 2024, the requirement `!: UnitDefault` will fail
|
||||
--> $DIR/diverging-fallback-control-flow.rs:36:13
|
||||
|
|
||||
LL | x = UnitDefault::default();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: use `()` annotations to avoid fallback changes
|
||||
|
|
||||
LL | let x: ();
|
||||
| ++++
|
||||
|
||||
Future breakage diagnostic:
|
||||
warning: this function depends on never type fallback being `()`
|
||||
--> $DIR/diverging-fallback-control-flow.rs:42:1
|
||||
|
|
||||
LL | fn assignment_rev() {
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: specify the types explicitly
|
||||
note: in edition 2024, the requirement `!: UnitDefault` will fail
|
||||
--> $DIR/diverging-fallback-control-flow.rs:48:13
|
||||
|
|
||||
LL | x = UnitDefault::default();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: use `()` annotations to avoid fallback changes
|
||||
|
|
||||
LL | let x: ();
|
||||
| ++++
|
||||
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
//@ revisions: nofallback fallback
|
||||
//@ check-pass
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_assignments)]
|
||||
#![allow(unused_variables)]
|
||||
#![allow(unreachable_code)]
|
||||
#![cfg_attr(nofallback, expect(dependency_on_unit_never_type_fallback))]
|
||||
|
||||
// Test various cases where we permit an unconstrained variable
|
||||
// to fallback based on control-flow. In all of these cases,
|
||||
// the type variable winds up being the target of both a `!` coercion
|
||||
// and a coercion from a non-`!` variable, and hence falls back to `()`.
|
||||
#![cfg_attr(fallback, feature(never_type, never_type_fallback))]
|
||||
|
||||
trait UnitDefault {
|
||||
fn default() -> Self;
|
||||
}
|
||||
|
||||
impl UnitDefault for u32 {
|
||||
fn default() -> Self {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl UnitDefault for () {
|
||||
fn default() -> () {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
||||
fn assignment() {
|
||||
let x;
|
||||
|
||||
if true {
|
||||
x = UnitDefault::default();
|
||||
} else {
|
||||
x = return;
|
||||
}
|
||||
}
|
||||
|
||||
fn assignment_rev() {
|
||||
let x;
|
||||
|
||||
if true {
|
||||
x = return;
|
||||
} else {
|
||||
x = UnitDefault::default();
|
||||
}
|
||||
}
|
||||
|
||||
fn if_then_else() {
|
||||
let _x: () = if true {
|
||||
UnitDefault::default()
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
fn if_then_else_rev() {
|
||||
let _x: () = if true {
|
||||
return;
|
||||
} else {
|
||||
UnitDefault::default()
|
||||
};
|
||||
}
|
||||
|
||||
fn match_arm() {
|
||||
let _x: () = match Ok(UnitDefault::default()) {
|
||||
Ok(v) => v,
|
||||
Err(()) => return,
|
||||
};
|
||||
}
|
||||
|
||||
fn match_arm_rev() {
|
||||
let _x: () = match Ok(UnitDefault::default()) {
|
||||
Err(()) => return,
|
||||
Ok(v) => v,
|
||||
};
|
||||
}
|
||||
|
||||
fn loop_break() {
|
||||
let _x: () = loop {
|
||||
if false {
|
||||
break return;
|
||||
} else {
|
||||
break UnitDefault::default();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn loop_break_rev() {
|
||||
let _x: () = loop {
|
||||
if false {
|
||||
break return;
|
||||
} else {
|
||||
break UnitDefault::default();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -13,7 +13,7 @@ LL | impl Test for i32 {}
|
|||
| ^^^^^^^^^^^^^^^^^ `i32`
|
||||
LL | impl Test for () {}
|
||||
| ^^^^^^^^^^^^^^^^ `()`
|
||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
|
||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
|
||||
= help: you might have intended to use the type `()` here instead
|
||||
note: required by a bound in `unconstrained_arg`
|
||||
--> $DIR/diverging-fallback-no-leak.rs:13:25
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//@ revisions: nofallback fallback
|
||||
//@[fallback] edition: 2024
|
||||
//@[nofallback] check-pass
|
||||
|
||||
#![cfg_attr(fallback, feature(never_type, never_type_fallback))]
|
||||
#![cfg_attr(nofallback, expect(dependency_on_unit_never_type_fallback))]
|
||||
|
||||
fn make_unit() {}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
error[E0277]: the trait bound `!: UnitReturn` is not satisfied
|
||||
--> $DIR/diverging-fallback-unconstrained-return.rs:37:23
|
||||
|
|
||||
LL | let _ = if true { unconstrained_return() } else { panic!() };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `UnitReturn` is not implemented for `!`
|
||||
|
|
||||
help: the following other types implement trait `UnitReturn`
|
||||
--> $DIR/diverging-fallback-unconstrained-return.rs:15:1
|
||||
|
|
||||
LL | impl UnitReturn for i32 {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ `i32`
|
||||
LL | impl UnitReturn for () {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ `()`
|
||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
|
||||
= help: you might have intended to use the type `()` here instead
|
||||
note: required by a bound in `unconstrained_return`
|
||||
--> $DIR/diverging-fallback-unconstrained-return.rs:18:28
|
||||
|
|
||||
LL | fn unconstrained_return<T: UnitReturn>() -> T {
|
||||
| ^^^^^^^^^^ required by this bound in `unconstrained_return`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
error: this function depends on never type fallback being `()`
|
||||
--> $DIR/diverging-fallback-unconstrained-return.rs:28:1
|
||||
--> $DIR/diverging-fallback-unconstrained-return.rs:26:1
|
||||
|
|
||||
LL | fn main() {
|
||||
| ^^^^^^^^^
|
||||
|
|
@ -8,7 +8,7 @@ LL | fn main() {
|
|||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
|
||||
= help: specify the types explicitly
|
||||
note: in edition 2024, the requirement `!: UnitReturn` will fail
|
||||
--> $DIR/diverging-fallback-unconstrained-return.rs:39:23
|
||||
--> $DIR/diverging-fallback-unconstrained-return.rs:37:23
|
||||
|
|
||||
LL | let _ = if true { unconstrained_return() } else { panic!() };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -22,7 +22,7 @@ error: aborting due to 1 previous error
|
|||
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
error: this function depends on never type fallback being `()`
|
||||
--> $DIR/diverging-fallback-unconstrained-return.rs:28:1
|
||||
--> $DIR/diverging-fallback-unconstrained-return.rs:26:1
|
||||
|
|
||||
LL | fn main() {
|
||||
| ^^^^^^^^^
|
||||
|
|
@ -31,7 +31,7 @@ LL | fn main() {
|
|||
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
|
||||
= help: specify the types explicitly
|
||||
note: in edition 2024, the requirement `!: UnitReturn` will fail
|
||||
--> $DIR/diverging-fallback-unconstrained-return.rs:39:23
|
||||
--> $DIR/diverging-fallback-unconstrained-return.rs:37:23
|
||||
|
|
||||
LL | let _ = if true { unconstrained_return() } else { panic!() };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -4,12 +4,10 @@
|
|||
// in the objc crate, where changing the fallback from `!` to `()`
|
||||
// resulted in unsoundness.
|
||||
//
|
||||
//@[fallback] check-pass
|
||||
|
||||
//@ revisions: nofallback fallback
|
||||
//@[fallback] edition: 2024
|
||||
|
||||
#![cfg_attr(fallback, feature(never_type, never_type_fallback))]
|
||||
#![allow(unit_bindings)]
|
||||
#![expect(unit_bindings)]
|
||||
|
||||
fn make_unit() {}
|
||||
|
||||
|
|
@ -36,5 +34,5 @@ fn main() {
|
|||
// idea was to change that fallback to `!`, but that would have resulted
|
||||
// in this code no longer compiling (or worse, in some cases it injected
|
||||
// unsound results).
|
||||
let _ = if true { unconstrained_return() } else { panic!() };
|
||||
let _ = if true { unconstrained_return() } else { panic!() }; //[fallback]~ error: the trait bound `!: UnitReturn` is not satisfied
|
||||
}
|
||||
|
|
|
|||
24
tests/ui/never_type/fallback-closure-ret.fallback.stderr
Normal file
24
tests/ui/never_type/fallback-closure-ret.fallback.stderr
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
error[E0277]: the trait bound `!: Bar` is not satisfied
|
||||
--> $DIR/fallback-closure-ret.rs:18:5
|
||||
|
|
||||
LL | foo(|| panic!());
|
||||
| ^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `!`
|
||||
|
|
||||
help: the following other types implement trait `Bar`
|
||||
--> $DIR/fallback-closure-ret.rs:12:1
|
||||
|
|
||||
LL | impl Bar for () {}
|
||||
| ^^^^^^^^^^^^^^^ `()`
|
||||
LL | impl Bar for u32 {}
|
||||
| ^^^^^^^^^^^^^^^^ `u32`
|
||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
|
||||
= help: you might have intended to use the type `()` here instead
|
||||
note: required by a bound in `foo`
|
||||
--> $DIR/fallback-closure-ret.rs:15:11
|
||||
|
|
||||
LL | fn foo<R: Bar>(_: impl Fn() -> R) {}
|
||||
| ^^^ required by this bound in `foo`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
Future incompatibility report: Future breakage diagnostic:
|
||||
warning: this function depends on never type fallback being `()`
|
||||
--> $DIR/fallback-closure-ret.rs:22:1
|
||||
--> $DIR/fallback-closure-ret.rs:17:1
|
||||
|
|
||||
LL | fn main() {
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: specify the types explicitly
|
||||
note: in edition 2024, the requirement `!: Bar` will fail
|
||||
--> $DIR/fallback-closure-ret.rs:23:5
|
||||
--> $DIR/fallback-closure-ret.rs:18:5
|
||||
|
|
||||
LL | foo(|| panic!());
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,16 +1,11 @@
|
|||
// This test verifies that never type fallback preserves the following code in a
|
||||
// compiling state. This pattern is fairly common in the wild, notably seen in
|
||||
// wasmtime v0.16. Typically this is some closure wrapper that expects a
|
||||
// collection of 'known' signatures, and -> ! is not included in that set.
|
||||
//
|
||||
// This test is specifically targeted by the unit type fallback when
|
||||
// encountering a set of obligations like `?T: Foo` and `Trait::Projection =
|
||||
// ?T`. In the code below, these are `R: Bar` and `Fn::Output = R`.
|
||||
// This test used to test that this pattern is not broken by context dependant
|
||||
// never type fallback. However, it got removed, so now this is an example of
|
||||
// expected breakage from the never type fallback change.
|
||||
//
|
||||
//@ revisions: nofallback fallback
|
||||
//@ check-pass
|
||||
//@[nofallback] check-pass
|
||||
//@[fallback] edition: 2024
|
||||
|
||||
#![cfg_attr(fallback, feature(never_type_fallback))]
|
||||
#![cfg_attr(nofallback, expect(dependency_on_unit_never_type_fallback))]
|
||||
|
||||
trait Bar {}
|
||||
|
|
@ -20,5 +15,5 @@ impl Bar for u32 {}
|
|||
fn foo<R: Bar>(_: impl Fn() -> R) {}
|
||||
|
||||
fn main() {
|
||||
foo(|| panic!());
|
||||
foo(|| panic!()); //[fallback]~ error: the trait bound `!: Bar` is not satisfied
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0271]: expected `{closure@fallback-closure-wrap.rs:18:40}` to return `()`, but it returns `!`
|
||||
--> $DIR/fallback-closure-wrap.rs:19:9
|
||||
error[E0271]: expected `{closure@fallback-closure-wrap.rs:17:40}` to return `()`, but it returns `!`
|
||||
--> $DIR/fallback-closure-wrap.rs:18:9
|
||||
|
|
||||
LL | let error = Closure::wrap(Box::new(move || {
|
||||
| ------- this closure
|
||||
|
|
@ -8,7 +8,7 @@ LL | panic!("Can't connect to server.");
|
|||
|
|
||||
= note: expected unit type `()`
|
||||
found type `!`
|
||||
= note: required for the cast from `Box<{closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47}>` to `Box<dyn FnMut()>`
|
||||
= note: required for the cast from `Box<{closure@$DIR/fallback-closure-wrap.rs:17:40: 17:47}>` to `Box<dyn FnMut()>`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -7,11 +7,10 @@
|
|||
// awareness.
|
||||
//
|
||||
//@ revisions: nofallback fallback
|
||||
//@[fallback] edition: 2024
|
||||
//@[nofallback] check-pass
|
||||
//@[fallback] check-fail
|
||||
|
||||
#![cfg_attr(fallback, feature(never_type_fallback))]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
// This is a feature gate test for `never_type_fallback`.
|
||||
// It works by using a scenario where the type fall backs to `()` rather than ´!`
|
||||
// in the case where `#![feature(never_type_fallback)]` would change it to `!`.
|
||||
|
||||
fn main() {}
|
||||
|
||||
trait T {}
|
||||
|
||||
fn should_ret_unit() {
|
||||
foo(panic!()) //~ ERROR
|
||||
}
|
||||
|
||||
fn foo(_: impl T) {}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
error[E0277]: the trait bound `(): T` is not satisfied
|
||||
--> $DIR/feature-gate-never_type_fallback.rs:10:9
|
||||
|
|
||||
LL | foo(panic!())
|
||||
| --- ^^^^^^^^ the trait `T` is not implemented for `()`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/feature-gate-never_type_fallback.rs:7:1
|
||||
|
|
||||
LL | trait T {}
|
||||
| ^^^^^^^
|
||||
note: required by a bound in `foo`
|
||||
--> $DIR/feature-gate-never_type_fallback.rs:13:16
|
||||
|
|
||||
LL | fn foo(_: impl T) {}
|
||||
| ^ required by this bound in `foo`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
error[E0277]: the trait bound `E: From<()>` is not satisfied
|
||||
--> $DIR/never-value-fallback-issue-66757.rs:28:6
|
||||
--> $DIR/never-value-fallback-issue-66757.rs:27:6
|
||||
|
|
||||
LL | <E as From<_>>::from(never);
|
||||
| ^ unsatisfied trait bound
|
||||
|
|
||||
help: the trait `From<()>` is not implemented for `E`
|
||||
but trait `From<!>` is implemented for it
|
||||
--> $DIR/never-value-fallback-issue-66757.rs:17:1
|
||||
--> $DIR/never-value-fallback-issue-66757.rs:16:1
|
||||
|
|
||||
LL | impl From<!> for E {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -5,13 +5,12 @@
|
|||
// doesn't fallback to `()` but rather `!`.
|
||||
//
|
||||
//@ revisions: nofallback fallback
|
||||
//@[fallback] edition: 2024
|
||||
//@[fallback] run-pass
|
||||
//@[nofallback] check-fail
|
||||
|
||||
#![feature(never_type)]
|
||||
|
||||
#![cfg_attr(fallback, feature(never_type_fallback))]
|
||||
|
||||
struct E;
|
||||
|
||||
impl From<!> for E {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:49:9
|
||||
--> $DIR/empty-types.rs:48:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -9,13 +9,13 @@ LL | _ => {}
|
|||
|
|
||||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
note: the lint level is defined here
|
||||
--> $DIR/empty-types.rs:15:9
|
||||
--> $DIR/empty-types.rs:14:9
|
||||
|
|
||||
LL | #![deny(unreachable_patterns)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:52:9
|
||||
--> $DIR/empty-types.rs:51:9
|
||||
|
|
||||
LL | _x => {}
|
||||
| ^^------
|
||||
|
|
@ -26,7 +26,7 @@ LL | _x => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `&!` is non-empty
|
||||
--> $DIR/empty-types.rs:56:11
|
||||
--> $DIR/empty-types.rs:55:11
|
||||
|
|
||||
LL | match ref_never {}
|
||||
| ^^^^^^^^^
|
||||
|
|
@ -41,7 +41,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:70:9
|
||||
--> $DIR/empty-types.rs:69:9
|
||||
|
|
||||
LL | (_, _) => {}
|
||||
| ^^^^^^------
|
||||
|
|
@ -52,7 +52,7 @@ LL | (_, _) => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:76:9
|
||||
--> $DIR/empty-types.rs:75:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -63,7 +63,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:79:9
|
||||
--> $DIR/empty-types.rs:78:9
|
||||
|
|
||||
LL | (_, _) => {}
|
||||
| ^^^^^^------
|
||||
|
|
@ -74,7 +74,7 @@ LL | (_, _) => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:83:9
|
||||
--> $DIR/empty-types.rs:82:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -85,7 +85,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
|
||||
--> $DIR/empty-types.rs:87:11
|
||||
--> $DIR/empty-types.rs:86:11
|
||||
|
|
||||
LL | match res_u32_never {}
|
||||
| ^^^^^^^^^^^^^ pattern `Ok(_)` not covered
|
||||
|
|
@ -104,7 +104,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:94:9
|
||||
--> $DIR/empty-types.rs:93:9
|
||||
|
|
||||
LL | Err(_) => {}
|
||||
| ^^^^^^------
|
||||
|
|
@ -115,7 +115,7 @@ LL | Err(_) => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:99:9
|
||||
--> $DIR/empty-types.rs:98:9
|
||||
|
|
||||
LL | Err(_) => {}
|
||||
| ^^^^^^------
|
||||
|
|
@ -126,7 +126,7 @@ LL | Err(_) => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
|
||||
--> $DIR/empty-types.rs:96:11
|
||||
--> $DIR/empty-types.rs:95:11
|
||||
|
|
||||
LL | match res_u32_never {
|
||||
| ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered
|
||||
|
|
@ -144,7 +144,7 @@ LL ~ Ok(1_u32..=u32::MAX) => todo!()
|
|||
|
|
||||
|
||||
error[E0005]: refutable pattern in local binding
|
||||
--> $DIR/empty-types.rs:102:9
|
||||
--> $DIR/empty-types.rs:101:9
|
||||
|
|
||||
LL | let Ok(_x) = res_u32_never.as_ref();
|
||||
| ^^^^^^ pattern `Err(_)` not covered
|
||||
|
|
@ -158,7 +158,7 @@ LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() };
|
|||
| ++++++++++++++++
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:112:9
|
||||
--> $DIR/empty-types.rs:111:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -169,7 +169,18 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:115:9
|
||||
--> $DIR/empty-types.rs:114:9
|
||||
|
|
||||
LL | Ok(_) => {}
|
||||
| ^^^^^------
|
||||
| |
|
||||
| matches no values because `Result<!, !>` is uninhabited
|
||||
| help: remove the match arm
|
||||
|
|
||||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:117:9
|
||||
|
|
||||
LL | Ok(_) => {}
|
||||
| ^^^^^------
|
||||
|
|
@ -182,17 +193,6 @@ LL | Ok(_) => {}
|
|||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:118:9
|
||||
|
|
||||
LL | Ok(_) => {}
|
||||
| ^^^^^------
|
||||
| |
|
||||
| matches no values because `Result<!, !>` is uninhabited
|
||||
| help: remove the match arm
|
||||
|
|
||||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:119:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
| |
|
||||
|
|
@ -202,7 +202,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:122:9
|
||||
--> $DIR/empty-types.rs:121:9
|
||||
|
|
||||
LL | Ok(_) => {}
|
||||
| ^^^^^------
|
||||
|
|
@ -213,7 +213,7 @@ LL | Ok(_) => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:123:9
|
||||
--> $DIR/empty-types.rs:122:9
|
||||
|
|
||||
LL | Err(_) => {}
|
||||
| ^^^^^^------
|
||||
|
|
@ -224,7 +224,7 @@ LL | Err(_) => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:132:13
|
||||
--> $DIR/empty-types.rs:131:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -235,7 +235,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:135:13
|
||||
--> $DIR/empty-types.rs:134:13
|
||||
|
|
||||
LL | _ if false => {}
|
||||
| ^---------------
|
||||
|
|
@ -246,7 +246,7 @@ LL | _ if false => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:143:13
|
||||
--> $DIR/empty-types.rs:142:13
|
||||
|
|
||||
LL | Some(_) => {}
|
||||
| ^^^^^^^------
|
||||
|
|
@ -257,7 +257,7 @@ LL | Some(_) => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:147:13
|
||||
--> $DIR/empty-types.rs:146:13
|
||||
|
|
||||
LL | None => {}
|
||||
| ---- matches all the relevant values
|
||||
|
|
@ -265,7 +265,7 @@ LL | _ => {}
|
|||
| ^ no value can reach this
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:199:13
|
||||
--> $DIR/empty-types.rs:198:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -276,7 +276,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:204:13
|
||||
--> $DIR/empty-types.rs:203:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -287,7 +287,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:209:13
|
||||
--> $DIR/empty-types.rs:208:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -298,7 +298,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:214:13
|
||||
--> $DIR/empty-types.rs:213:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -309,7 +309,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:220:13
|
||||
--> $DIR/empty-types.rs:219:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -320,7 +320,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:281:9
|
||||
--> $DIR/empty-types.rs:280:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -331,7 +331,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:284:9
|
||||
--> $DIR/empty-types.rs:283:9
|
||||
|
|
||||
LL | (_, _) => {}
|
||||
| ^^^^^^------
|
||||
|
|
@ -342,7 +342,7 @@ LL | (_, _) => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:287:9
|
||||
--> $DIR/empty-types.rs:286:9
|
||||
|
|
||||
LL | Ok(_) => {}
|
||||
| ^^^^^------
|
||||
|
|
@ -353,7 +353,7 @@ LL | Ok(_) => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:288:9
|
||||
--> $DIR/empty-types.rs:287:9
|
||||
|
|
||||
LL | Err(_) => {}
|
||||
| ^^^^^^------
|
||||
|
|
@ -364,7 +364,7 @@ LL | Err(_) => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
|
||||
--> $DIR/empty-types.rs:327:11
|
||||
--> $DIR/empty-types.rs:326:11
|
||||
|
|
||||
LL | match slice_never {}
|
||||
| ^^^^^^^^^^^
|
||||
|
|
@ -378,7 +378,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `&[]` not covered
|
||||
--> $DIR/empty-types.rs:338:11
|
||||
--> $DIR/empty-types.rs:337:11
|
||||
|
|
||||
LL | match slice_never {
|
||||
| ^^^^^^^^^^^ pattern `&[]` not covered
|
||||
|
|
@ -391,7 +391,7 @@ LL + &[] => todo!()
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `&[]` not covered
|
||||
--> $DIR/empty-types.rs:352:11
|
||||
--> $DIR/empty-types.rs:351:11
|
||||
|
|
||||
LL | match slice_never {
|
||||
| ^^^^^^^^^^^ pattern `&[]` not covered
|
||||
|
|
@ -405,7 +405,7 @@ LL + &[] => todo!()
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
|
||||
--> $DIR/empty-types.rs:359:11
|
||||
--> $DIR/empty-types.rs:358:11
|
||||
|
|
||||
LL | match *slice_never {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
@ -419,7 +419,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:368:9
|
||||
--> $DIR/empty-types.rs:367:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -430,7 +430,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:371:9
|
||||
--> $DIR/empty-types.rs:370:9
|
||||
|
|
||||
LL | [_, _, _] => {}
|
||||
| ^^^^^^^^^------
|
||||
|
|
@ -441,7 +441,7 @@ LL | [_, _, _] => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:374:9
|
||||
--> $DIR/empty-types.rs:373:9
|
||||
|
|
||||
LL | [_, ..] => {}
|
||||
| ^^^^^^^------
|
||||
|
|
@ -452,7 +452,7 @@ LL | [_, ..] => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
|
||||
--> $DIR/empty-types.rs:388:11
|
||||
--> $DIR/empty-types.rs:387:11
|
||||
|
|
||||
LL | match array_0_never {}
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
@ -466,7 +466,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:395:9
|
||||
--> $DIR/empty-types.rs:394:9
|
||||
|
|
||||
LL | [] => {}
|
||||
| -- matches all the relevant values
|
||||
|
|
@ -474,7 +474,7 @@ LL | _ => {}
|
|||
| ^ no value can reach this
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `[]` not covered
|
||||
--> $DIR/empty-types.rs:397:11
|
||||
--> $DIR/empty-types.rs:396:11
|
||||
|
|
||||
LL | match array_0_never {
|
||||
| ^^^^^^^^^^^^^ pattern `[]` not covered
|
||||
|
|
@ -488,7 +488,7 @@ LL + [] => todo!()
|
|||
|
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:416:9
|
||||
--> $DIR/empty-types.rs:415:9
|
||||
|
|
||||
LL | Some(_) => {}
|
||||
| ^^^^^^^------
|
||||
|
|
@ -499,7 +499,7 @@ LL | Some(_) => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:421:9
|
||||
--> $DIR/empty-types.rs:420:9
|
||||
|
|
||||
LL | Some(_a) => {}
|
||||
| ^^^^^^^^------
|
||||
|
|
@ -510,7 +510,7 @@ LL | Some(_a) => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:426:9
|
||||
--> $DIR/empty-types.rs:425:9
|
||||
|
|
||||
LL | None => {}
|
||||
| ---- matches all the relevant values
|
||||
|
|
@ -519,7 +519,7 @@ LL | _ => {}
|
|||
| ^ no value can reach this
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:431:9
|
||||
--> $DIR/empty-types.rs:430:9
|
||||
|
|
||||
LL | None => {}
|
||||
| ---- matches all the relevant values
|
||||
|
|
@ -528,7 +528,7 @@ LL | _a => {}
|
|||
| ^^ no value can reach this
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:603:9
|
||||
--> $DIR/empty-types.rs:602:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -539,7 +539,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:606:9
|
||||
--> $DIR/empty-types.rs:605:9
|
||||
|
|
||||
LL | _x => {}
|
||||
| ^^------
|
||||
|
|
@ -550,7 +550,7 @@ LL | _x => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:609:9
|
||||
--> $DIR/empty-types.rs:608:9
|
||||
|
|
||||
LL | _ if false => {}
|
||||
| ^---------------
|
||||
|
|
@ -561,7 +561,7 @@ LL | _ if false => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:612:9
|
||||
--> $DIR/empty-types.rs:611:9
|
||||
|
|
||||
LL | _x if false => {}
|
||||
| ^^---------------
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
warning: the feature `never_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/empty-types.rs:12:33
|
||||
--> $DIR/empty-types.rs:11:33
|
||||
|
|
||||
LL | #![cfg_attr(never_pats, feature(never_patterns))]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
@ -8,7 +8,7 @@ LL | #![cfg_attr(never_pats, feature(never_patterns))]
|
|||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:49:9
|
||||
--> $DIR/empty-types.rs:48:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -18,13 +18,13 @@ LL | _ => {}
|
|||
|
|
||||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
note: the lint level is defined here
|
||||
--> $DIR/empty-types.rs:15:9
|
||||
--> $DIR/empty-types.rs:14:9
|
||||
|
|
||||
LL | #![deny(unreachable_patterns)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:52:9
|
||||
--> $DIR/empty-types.rs:51:9
|
||||
|
|
||||
LL | _x => {}
|
||||
| ^^------
|
||||
|
|
@ -35,7 +35,7 @@ LL | _x => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `&!` is non-empty
|
||||
--> $DIR/empty-types.rs:56:11
|
||||
--> $DIR/empty-types.rs:55:11
|
||||
|
|
||||
LL | match ref_never {}
|
||||
| ^^^^^^^^^
|
||||
|
|
@ -50,7 +50,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:83:9
|
||||
--> $DIR/empty-types.rs:82:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -61,7 +61,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
|
||||
--> $DIR/empty-types.rs:87:11
|
||||
--> $DIR/empty-types.rs:86:11
|
||||
|
|
||||
LL | match res_u32_never {}
|
||||
| ^^^^^^^^^^^^^ pattern `Ok(_)` not covered
|
||||
|
|
@ -80,7 +80,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
|
||||
--> $DIR/empty-types.rs:96:11
|
||||
--> $DIR/empty-types.rs:95:11
|
||||
|
|
||||
LL | match res_u32_never {
|
||||
| ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered
|
||||
|
|
@ -98,7 +98,7 @@ LL ~ Ok(1_u32..=u32::MAX) => todo!()
|
|||
|
|
||||
|
||||
error[E0005]: refutable pattern in local binding
|
||||
--> $DIR/empty-types.rs:102:9
|
||||
--> $DIR/empty-types.rs:101:9
|
||||
|
|
||||
LL | let Ok(_x) = res_u32_never.as_ref();
|
||||
| ^^^^^^ pattern `Err(_)` not covered
|
||||
|
|
@ -112,7 +112,7 @@ LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() };
|
|||
| ++++++++++++++++
|
||||
|
||||
error[E0005]: refutable pattern in local binding
|
||||
--> $DIR/empty-types.rs:106:9
|
||||
--> $DIR/empty-types.rs:105:9
|
||||
|
|
||||
LL | let Ok(_x) = &res_u32_never;
|
||||
| ^^^^^^ pattern `&Err(!)` not covered
|
||||
|
|
@ -126,7 +126,7 @@ LL | let Ok(_x) = &res_u32_never else { todo!() };
|
|||
| ++++++++++++++++
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:132:13
|
||||
--> $DIR/empty-types.rs:131:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -137,7 +137,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:135:13
|
||||
--> $DIR/empty-types.rs:134:13
|
||||
|
|
||||
LL | _ if false => {}
|
||||
| ^---------------
|
||||
|
|
@ -148,7 +148,7 @@ LL | _ if false => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Some(!)` not covered
|
||||
--> $DIR/empty-types.rs:156:15
|
||||
--> $DIR/empty-types.rs:155:15
|
||||
|
|
||||
LL | match *ref_opt_void {
|
||||
| ^^^^^^^^^^^^^ pattern `Some(!)` not covered
|
||||
|
|
@ -167,7 +167,7 @@ LL + Some(!)
|
|||
|
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:199:13
|
||||
--> $DIR/empty-types.rs:198:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -178,7 +178,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:204:13
|
||||
--> $DIR/empty-types.rs:203:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -189,7 +189,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:209:13
|
||||
--> $DIR/empty-types.rs:208:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -200,7 +200,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:214:13
|
||||
--> $DIR/empty-types.rs:213:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -211,7 +211,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:220:13
|
||||
--> $DIR/empty-types.rs:219:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -222,7 +222,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:281:9
|
||||
--> $DIR/empty-types.rs:280:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -233,7 +233,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error[E0005]: refutable pattern in local binding
|
||||
--> $DIR/empty-types.rs:297:13
|
||||
--> $DIR/empty-types.rs:296:13
|
||||
|
|
||||
LL | let Ok(_) = *ptr_result_never_err;
|
||||
| ^^^^^ pattern `Err(!)` not covered
|
||||
|
|
@ -247,7 +247,7 @@ LL | if let Ok(_) = *ptr_result_never_err { todo!() };
|
|||
| ++ +++++++++++
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
|
||||
--> $DIR/empty-types.rs:316:11
|
||||
--> $DIR/empty-types.rs:315:11
|
||||
|
|
||||
LL | match *x {}
|
||||
| ^^
|
||||
|
|
@ -261,7 +261,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty
|
||||
--> $DIR/empty-types.rs:318:11
|
||||
--> $DIR/empty-types.rs:317:11
|
||||
|
|
||||
LL | match *x {}
|
||||
| ^^
|
||||
|
|
@ -275,7 +275,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Ok(!)` and `Err(!)` not covered
|
||||
--> $DIR/empty-types.rs:320:11
|
||||
--> $DIR/empty-types.rs:319:11
|
||||
|
|
||||
LL | match *x {}
|
||||
| ^^ patterns `Ok(!)` and `Err(!)` not covered
|
||||
|
|
@ -297,7 +297,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty
|
||||
--> $DIR/empty-types.rs:322:11
|
||||
--> $DIR/empty-types.rs:321:11
|
||||
|
|
||||
LL | match *x {}
|
||||
| ^^
|
||||
|
|
@ -311,7 +311,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
|
||||
--> $DIR/empty-types.rs:327:11
|
||||
--> $DIR/empty-types.rs:326:11
|
||||
|
|
||||
LL | match slice_never {}
|
||||
| ^^^^^^^^^^^
|
||||
|
|
@ -325,7 +325,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `&[!, ..]` not covered
|
||||
--> $DIR/empty-types.rs:329:11
|
||||
--> $DIR/empty-types.rs:328:11
|
||||
|
|
||||
LL | match slice_never {
|
||||
| ^^^^^^^^^^^ pattern `&[!, ..]` not covered
|
||||
|
|
@ -339,7 +339,7 @@ LL + &[!, ..]
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `&[]`, `&[!]` and `&[!, !]` not covered
|
||||
--> $DIR/empty-types.rs:338:11
|
||||
--> $DIR/empty-types.rs:337:11
|
||||
|
|
||||
LL | match slice_never {
|
||||
| ^^^^^^^^^^^ patterns `&[]`, `&[!]` and `&[!, !]` not covered
|
||||
|
|
@ -352,7 +352,7 @@ LL + &[] | &[!] | &[!, !] => todo!()
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `&[]` and `&[!, ..]` not covered
|
||||
--> $DIR/empty-types.rs:352:11
|
||||
--> $DIR/empty-types.rs:351:11
|
||||
|
|
||||
LL | match slice_never {
|
||||
| ^^^^^^^^^^^ patterns `&[]` and `&[!, ..]` not covered
|
||||
|
|
@ -366,7 +366,7 @@ LL + &[] | &[!, ..] => todo!()
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
|
||||
--> $DIR/empty-types.rs:359:11
|
||||
--> $DIR/empty-types.rs:358:11
|
||||
|
|
||||
LL | match *slice_never {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
@ -380,7 +380,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
|
||||
--> $DIR/empty-types.rs:388:11
|
||||
--> $DIR/empty-types.rs:387:11
|
||||
|
|
||||
LL | match array_0_never {}
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
@ -394,7 +394,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:395:9
|
||||
--> $DIR/empty-types.rs:394:9
|
||||
|
|
||||
LL | [] => {}
|
||||
| -- matches all the relevant values
|
||||
|
|
@ -402,7 +402,7 @@ LL | _ => {}
|
|||
| ^ no value can reach this
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `[]` not covered
|
||||
--> $DIR/empty-types.rs:397:11
|
||||
--> $DIR/empty-types.rs:396:11
|
||||
|
|
||||
LL | match array_0_never {
|
||||
| ^^^^^^^^^^^^^ pattern `[]` not covered
|
||||
|
|
@ -416,7 +416,7 @@ LL + [] => todo!()
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `&Some(!)` not covered
|
||||
--> $DIR/empty-types.rs:451:11
|
||||
--> $DIR/empty-types.rs:450:11
|
||||
|
|
||||
LL | match ref_opt_never {
|
||||
| ^^^^^^^^^^^^^ pattern `&Some(!)` not covered
|
||||
|
|
@ -435,7 +435,7 @@ LL + &Some(!)
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Some(!)` not covered
|
||||
--> $DIR/empty-types.rs:492:11
|
||||
--> $DIR/empty-types.rs:491:11
|
||||
|
|
||||
LL | match *ref_opt_never {
|
||||
| ^^^^^^^^^^^^^^ pattern `Some(!)` not covered
|
||||
|
|
@ -454,7 +454,7 @@ LL + Some(!)
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Err(!)` not covered
|
||||
--> $DIR/empty-types.rs:540:11
|
||||
--> $DIR/empty-types.rs:539:11
|
||||
|
|
||||
LL | match *ref_res_never {
|
||||
| ^^^^^^^^^^^^^^ pattern `Err(!)` not covered
|
||||
|
|
@ -473,7 +473,7 @@ LL + Err(!)
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Err(!)` not covered
|
||||
--> $DIR/empty-types.rs:551:11
|
||||
--> $DIR/empty-types.rs:550:11
|
||||
|
|
||||
LL | match *ref_res_never {
|
||||
| ^^^^^^^^^^^^^^ pattern `Err(!)` not covered
|
||||
|
|
@ -492,7 +492,7 @@ LL + Err(!)
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
|
||||
--> $DIR/empty-types.rs:570:11
|
||||
--> $DIR/empty-types.rs:569:11
|
||||
|
|
||||
LL | match *ref_tuple_half_never {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -506,7 +506,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:603:9
|
||||
--> $DIR/empty-types.rs:602:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -517,7 +517,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:606:9
|
||||
--> $DIR/empty-types.rs:605:9
|
||||
|
|
||||
LL | _x => {}
|
||||
| ^^------
|
||||
|
|
@ -528,7 +528,7 @@ LL | _x => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:609:9
|
||||
--> $DIR/empty-types.rs:608:9
|
||||
|
|
||||
LL | _ if false => {}
|
||||
| ^---------------
|
||||
|
|
@ -539,7 +539,7 @@ LL | _ if false => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:612:9
|
||||
--> $DIR/empty-types.rs:611:9
|
||||
|
|
||||
LL | _x if false => {}
|
||||
| ^^---------------
|
||||
|
|
@ -550,7 +550,7 @@ LL | _x if false => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `&!` not covered
|
||||
--> $DIR/empty-types.rs:637:11
|
||||
--> $DIR/empty-types.rs:636:11
|
||||
|
|
||||
LL | match ref_never {
|
||||
| ^^^^^^^^^ pattern `&!` not covered
|
||||
|
|
@ -566,7 +566,7 @@ LL + &!
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Ok(!)` not covered
|
||||
--> $DIR/empty-types.rs:653:11
|
||||
--> $DIR/empty-types.rs:652:11
|
||||
|
|
||||
LL | match *ref_result_never {
|
||||
| ^^^^^^^^^^^^^^^^^ pattern `Ok(!)` not covered
|
||||
|
|
@ -585,7 +585,7 @@ LL + Ok(!)
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Some(!)` not covered
|
||||
--> $DIR/empty-types.rs:673:11
|
||||
--> $DIR/empty-types.rs:672:11
|
||||
|
|
||||
LL | match *x {
|
||||
| ^^ pattern `Some(!)` not covered
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:49:9
|
||||
--> $DIR/empty-types.rs:48:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -9,13 +9,13 @@ LL | _ => {}
|
|||
|
|
||||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
note: the lint level is defined here
|
||||
--> $DIR/empty-types.rs:15:9
|
||||
--> $DIR/empty-types.rs:14:9
|
||||
|
|
||||
LL | #![deny(unreachable_patterns)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:52:9
|
||||
--> $DIR/empty-types.rs:51:9
|
||||
|
|
||||
LL | _x => {}
|
||||
| ^^------
|
||||
|
|
@ -26,7 +26,7 @@ LL | _x => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `&!` is non-empty
|
||||
--> $DIR/empty-types.rs:56:11
|
||||
--> $DIR/empty-types.rs:55:11
|
||||
|
|
||||
LL | match ref_never {}
|
||||
| ^^^^^^^^^
|
||||
|
|
@ -41,7 +41,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:83:9
|
||||
--> $DIR/empty-types.rs:82:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -52,7 +52,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
|
||||
--> $DIR/empty-types.rs:87:11
|
||||
--> $DIR/empty-types.rs:86:11
|
||||
|
|
||||
LL | match res_u32_never {}
|
||||
| ^^^^^^^^^^^^^ pattern `Ok(_)` not covered
|
||||
|
|
@ -71,7 +71,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
|
||||
--> $DIR/empty-types.rs:96:11
|
||||
--> $DIR/empty-types.rs:95:11
|
||||
|
|
||||
LL | match res_u32_never {
|
||||
| ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered
|
||||
|
|
@ -89,7 +89,7 @@ LL ~ Ok(1_u32..=u32::MAX) => todo!()
|
|||
|
|
||||
|
||||
error[E0005]: refutable pattern in local binding
|
||||
--> $DIR/empty-types.rs:102:9
|
||||
--> $DIR/empty-types.rs:101:9
|
||||
|
|
||||
LL | let Ok(_x) = res_u32_never.as_ref();
|
||||
| ^^^^^^ pattern `Err(_)` not covered
|
||||
|
|
@ -103,7 +103,7 @@ LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() };
|
|||
| ++++++++++++++++
|
||||
|
||||
error[E0005]: refutable pattern in local binding
|
||||
--> $DIR/empty-types.rs:106:9
|
||||
--> $DIR/empty-types.rs:105:9
|
||||
|
|
||||
LL | let Ok(_x) = &res_u32_never;
|
||||
| ^^^^^^ pattern `&Err(_)` not covered
|
||||
|
|
@ -117,7 +117,7 @@ LL | let Ok(_x) = &res_u32_never else { todo!() };
|
|||
| ++++++++++++++++
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:132:13
|
||||
--> $DIR/empty-types.rs:131:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -128,7 +128,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:135:13
|
||||
--> $DIR/empty-types.rs:134:13
|
||||
|
|
||||
LL | _ if false => {}
|
||||
| ^---------------
|
||||
|
|
@ -139,7 +139,7 @@ LL | _ if false => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
|
||||
--> $DIR/empty-types.rs:156:15
|
||||
--> $DIR/empty-types.rs:155:15
|
||||
|
|
||||
LL | match *ref_opt_void {
|
||||
| ^^^^^^^^^^^^^ pattern `Some(_)` not covered
|
||||
|
|
@ -158,7 +158,7 @@ LL + Some(_) => todo!()
|
|||
|
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:199:13
|
||||
--> $DIR/empty-types.rs:198:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -169,7 +169,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:204:13
|
||||
--> $DIR/empty-types.rs:203:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -180,7 +180,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:209:13
|
||||
--> $DIR/empty-types.rs:208:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -191,7 +191,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:214:13
|
||||
--> $DIR/empty-types.rs:213:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -202,7 +202,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:220:13
|
||||
--> $DIR/empty-types.rs:219:13
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -213,7 +213,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:281:9
|
||||
--> $DIR/empty-types.rs:280:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -224,7 +224,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error[E0005]: refutable pattern in local binding
|
||||
--> $DIR/empty-types.rs:297:13
|
||||
--> $DIR/empty-types.rs:296:13
|
||||
|
|
||||
LL | let Ok(_) = *ptr_result_never_err;
|
||||
| ^^^^^ pattern `Err(_)` not covered
|
||||
|
|
@ -238,7 +238,7 @@ LL | if let Ok(_) = *ptr_result_never_err { todo!() };
|
|||
| ++ +++++++++++
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
|
||||
--> $DIR/empty-types.rs:316:11
|
||||
--> $DIR/empty-types.rs:315:11
|
||||
|
|
||||
LL | match *x {}
|
||||
| ^^
|
||||
|
|
@ -252,7 +252,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty
|
||||
--> $DIR/empty-types.rs:318:11
|
||||
--> $DIR/empty-types.rs:317:11
|
||||
|
|
||||
LL | match *x {}
|
||||
| ^^
|
||||
|
|
@ -266,7 +266,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered
|
||||
--> $DIR/empty-types.rs:320:11
|
||||
--> $DIR/empty-types.rs:319:11
|
||||
|
|
||||
LL | match *x {}
|
||||
| ^^ patterns `Ok(_)` and `Err(_)` not covered
|
||||
|
|
@ -288,7 +288,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty
|
||||
--> $DIR/empty-types.rs:322:11
|
||||
--> $DIR/empty-types.rs:321:11
|
||||
|
|
||||
LL | match *x {}
|
||||
| ^^
|
||||
|
|
@ -302,7 +302,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
|
||||
--> $DIR/empty-types.rs:327:11
|
||||
--> $DIR/empty-types.rs:326:11
|
||||
|
|
||||
LL | match slice_never {}
|
||||
| ^^^^^^^^^^^
|
||||
|
|
@ -316,7 +316,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
|
||||
--> $DIR/empty-types.rs:329:11
|
||||
--> $DIR/empty-types.rs:328:11
|
||||
|
|
||||
LL | match slice_never {
|
||||
| ^^^^^^^^^^^ pattern `&[_, ..]` not covered
|
||||
|
|
@ -330,7 +330,7 @@ LL + &[_, ..] => todo!()
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `&[]`, `&[_]` and `&[_, _]` not covered
|
||||
--> $DIR/empty-types.rs:338:11
|
||||
--> $DIR/empty-types.rs:337:11
|
||||
|
|
||||
LL | match slice_never {
|
||||
| ^^^^^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _]` not covered
|
||||
|
|
@ -343,7 +343,7 @@ LL + &[] | &[_] | &[_, _] => todo!()
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `&[]` and `&[_, ..]` not covered
|
||||
--> $DIR/empty-types.rs:352:11
|
||||
--> $DIR/empty-types.rs:351:11
|
||||
|
|
||||
LL | match slice_never {
|
||||
| ^^^^^^^^^^^ patterns `&[]` and `&[_, ..]` not covered
|
||||
|
|
@ -357,7 +357,7 @@ LL + &[] | &[_, ..] => todo!()
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
|
||||
--> $DIR/empty-types.rs:359:11
|
||||
--> $DIR/empty-types.rs:358:11
|
||||
|
|
||||
LL | match *slice_never {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
@ -371,7 +371,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
|
||||
--> $DIR/empty-types.rs:388:11
|
||||
--> $DIR/empty-types.rs:387:11
|
||||
|
|
||||
LL | match array_0_never {}
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
@ -385,7 +385,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:395:9
|
||||
--> $DIR/empty-types.rs:394:9
|
||||
|
|
||||
LL | [] => {}
|
||||
| -- matches all the relevant values
|
||||
|
|
@ -393,7 +393,7 @@ LL | _ => {}
|
|||
| ^ no value can reach this
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `[]` not covered
|
||||
--> $DIR/empty-types.rs:397:11
|
||||
--> $DIR/empty-types.rs:396:11
|
||||
|
|
||||
LL | match array_0_never {
|
||||
| ^^^^^^^^^^^^^ pattern `[]` not covered
|
||||
|
|
@ -407,7 +407,7 @@ LL + [] => todo!()
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `&Some(_)` not covered
|
||||
--> $DIR/empty-types.rs:451:11
|
||||
--> $DIR/empty-types.rs:450:11
|
||||
|
|
||||
LL | match ref_opt_never {
|
||||
| ^^^^^^^^^^^^^ pattern `&Some(_)` not covered
|
||||
|
|
@ -426,7 +426,7 @@ LL + &Some(_) => todo!()
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
|
||||
--> $DIR/empty-types.rs:492:11
|
||||
--> $DIR/empty-types.rs:491:11
|
||||
|
|
||||
LL | match *ref_opt_never {
|
||||
| ^^^^^^^^^^^^^^ pattern `Some(_)` not covered
|
||||
|
|
@ -445,7 +445,7 @@ LL + Some(_) => todo!()
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Err(_)` not covered
|
||||
--> $DIR/empty-types.rs:540:11
|
||||
--> $DIR/empty-types.rs:539:11
|
||||
|
|
||||
LL | match *ref_res_never {
|
||||
| ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
|
||||
|
|
@ -464,7 +464,7 @@ LL + Err(_) => todo!()
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Err(_)` not covered
|
||||
--> $DIR/empty-types.rs:551:11
|
||||
--> $DIR/empty-types.rs:550:11
|
||||
|
|
||||
LL | match *ref_res_never {
|
||||
| ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
|
||||
|
|
@ -483,7 +483,7 @@ LL + Err(_) => todo!()
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
|
||||
--> $DIR/empty-types.rs:570:11
|
||||
--> $DIR/empty-types.rs:569:11
|
||||
|
|
||||
LL | match *ref_tuple_half_never {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -497,7 +497,7 @@ LL ~ }
|
|||
|
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:603:9
|
||||
--> $DIR/empty-types.rs:602:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^------
|
||||
|
|
@ -508,7 +508,7 @@ LL | _ => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:606:9
|
||||
--> $DIR/empty-types.rs:605:9
|
||||
|
|
||||
LL | _x => {}
|
||||
| ^^------
|
||||
|
|
@ -519,7 +519,7 @@ LL | _x => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:609:9
|
||||
--> $DIR/empty-types.rs:608:9
|
||||
|
|
||||
LL | _ if false => {}
|
||||
| ^---------------
|
||||
|
|
@ -530,7 +530,7 @@ LL | _ if false => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/empty-types.rs:612:9
|
||||
--> $DIR/empty-types.rs:611:9
|
||||
|
|
||||
LL | _x if false => {}
|
||||
| ^^---------------
|
||||
|
|
@ -541,7 +541,7 @@ LL | _x if false => {}
|
|||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `&_` not covered
|
||||
--> $DIR/empty-types.rs:637:11
|
||||
--> $DIR/empty-types.rs:636:11
|
||||
|
|
||||
LL | match ref_never {
|
||||
| ^^^^^^^^^ pattern `&_` not covered
|
||||
|
|
@ -557,7 +557,7 @@ LL + &_ => todo!()
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
|
||||
--> $DIR/empty-types.rs:653:11
|
||||
--> $DIR/empty-types.rs:652:11
|
||||
|
|
||||
LL | match *ref_result_never {
|
||||
| ^^^^^^^^^^^^^^^^^ pattern `Ok(_)` not covered
|
||||
|
|
@ -576,7 +576,7 @@ LL + Ok(_) => todo!()
|
|||
|
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
|
||||
--> $DIR/empty-types.rs:673:11
|
||||
--> $DIR/empty-types.rs:672:11
|
||||
|
|
||||
LL | match *x {
|
||||
| ^^ pattern `Some(_)` not covered
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
//@ revisions: normal exhaustive_patterns never_pats
|
||||
//@ edition: 2024
|
||||
//
|
||||
// This tests correct handling of empty types in exhaustiveness checking.
|
||||
//
|
||||
|
|
@ -6,8 +7,6 @@
|
|||
// valid data, namely dereferences and union field accesses. In these cases, empty arms can
|
||||
// generally not be omitted, except with `exhaustive_patterns` which ignores this..
|
||||
#![feature(never_type)]
|
||||
// This feature is useful to avoid `!` falling back to `()` all the time.
|
||||
#![feature(never_type_fallback)]
|
||||
#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
|
||||
#![cfg_attr(never_pats, feature(never_patterns))]
|
||||
//[never_pats]~^ WARN the feature `never_patterns` is incomplete
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
//@ check-pass
|
||||
//@ edition: 2024
|
||||
//@ aux-build:empty.rs
|
||||
//
|
||||
// This tests plays with matching and uninhabited types. This also serves as a test for the
|
||||
// `Ty::is_inhabited_from` function.
|
||||
#![feature(never_type)]
|
||||
#![feature(never_type_fallback)]
|
||||
#![deny(unreachable_patterns)]
|
||||
|
||||
macro_rules! assert_empty {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#![feature(exhaustive_patterns)]
|
||||
#![feature(never_type, never_type_fallback)]
|
||||
#![allow(unreachable_code)]
|
||||
#![deny(unreachable_patterns)]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
error: unreachable pattern
|
||||
--> $DIR/unreachable-loop-patterns.rs:17:9
|
||||
--> $DIR/unreachable-loop-patterns.rs:16:9
|
||||
|
|
||||
LL | for _ in unimplemented!() as Void {}
|
||||
| ^ matches no values because `Void` is uninhabited
|
||||
|
|
||||
= note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unreachable-loop-patterns.rs:4:9
|
||||
--> $DIR/unreachable-loop-patterns.rs:3:9
|
||||
|
|
||||
LL | #![deny(unreachable_patterns)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue