Migrate pattern matching

This commit is contained in:
mejrs 2022-12-23 21:02:23 +01:00 committed by David Tolnay
parent ef33072890
commit 31c20210b9
No known key found for this signature in database
GPG key ID: F9BA143B95FF6D82
35 changed files with 417 additions and 326 deletions

View file

@ -326,11 +326,39 @@ mir_build_overlapping_range_endpoints = multiple patterns overlap on their endpo
mir_build_overlapping_range = this range overlaps on `{$range}`...
mir_build_non_exhaustive_omitted_pattern = some variants are not matched explicitly
.label = {$count ->
.help = ensure that all variants are matched explicitly by adding the suggested match arms
.note = the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found
mir_build_uncovered = {$count ->
[1] pattern `{$witness_1}`
[2] patterns `{$witness_1}` and `{$witness_2}`
[3] patterns `{$witness_1}`, `{$witness_2}` and `{$witness_3}`
*[other] patterns `{$witness_1}`, `{$witness_2}`, `{$witness_3}` and more
*[other] patterns `{$witness_1}`, `{$witness_2}`, `{$witness_3}` and {$remainder} more
} not covered
.help = ensure that all variants are matched explicitly by adding the suggested match arms
.note = the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found
mir_build_pattern_not_covered = refutable pattern in {$origin}
.pattern_ty = the matched value is of type `{$pattern_ty}`
mir_build_inform_irrefutable = `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
mir_build_more_information = for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
mir_build_res_defined_here = {$res} defined here
mir_build_adt_defined_here = `{$ty}` defined here
mir_build_variant_defined_here = not covered
mir_build_interpreted_as_const = introduce a variable instead
mir_build_confused = missing patterns are not covered because `{$variable}` is interpreted as {$article} {$res} pattern, not a new variable
mir_build_suggest_if_let = you might want to use `if let` to ignore the {$count ->
[one] variant that isn't
*[other] variants that aren't
} matched
mir_build_suggest_let_else = alternatively, you might want to use `let else` to handle the {$count ->
[one] variant that isn't
*[other] variants that aren't
} matched

View file

@ -1,8 +1,11 @@
use crate::thir::pattern::deconstruct_pat::DeconstructedPat;
use crate::thir::pattern::MatchCheckCtxt;
use rustc_errors::Handler;
use rustc_errors::{
error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, MultiSpan,
error_code, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
IntoDiagnostic, MultiSpan, SubdiagnosticMessage,
};
use rustc_hir::def::Res;
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
use rustc_middle::thir::Pat;
use rustc_middle::ty::{self, Ty};
@ -677,7 +680,6 @@ pub struct OverlappingRangeEndpoints<'tcx> {
pub overlap: Overlap<'tcx>,
}
#[derive(Debug)]
#[derive(Subdiagnostic)]
#[label(mir_build_overlapping_range)]
pub struct Overlap<'tcx> {
@ -692,10 +694,158 @@ pub struct Overlap<'tcx> {
#[note]
pub(crate) struct NonExhaustiveOmittedPattern<'tcx> {
pub scrut_ty: Ty<'tcx>,
#[label]
pub uncovered: Span,
pub count: usize,
pub witness_1: Pat<'tcx>,
pub witness_2: Pat<'tcx>,
pub witness_3: Pat<'tcx>,
#[subdiagnostic]
pub uncovered: Uncovered<'tcx>,
}
#[derive(Subdiagnostic)]
#[label(mir_build_uncovered)]
pub(crate) struct Uncovered<'tcx> {
#[primary_span]
span: Span,
count: usize,
witness_1: Pat<'tcx>,
witness_2: Pat<'tcx>,
witness_3: Pat<'tcx>,
remainder: usize,
}
impl<'tcx> Uncovered<'tcx> {
pub fn new<'p>(
span: Span,
cx: &MatchCheckCtxt<'p, 'tcx>,
witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
) -> Self {
let witness_1 = witnesses.get(0).unwrap().to_pat(cx);
Self {
span,
count: witnesses.len(),
// Substitute dummy values if witnesses is smaller than 3. These will never be read.
witness_2: witnesses.get(1).map(|w| w.to_pat(cx)).unwrap_or_else(|| witness_1.clone()),
witness_3: witnesses.get(2).map(|w| w.to_pat(cx)).unwrap_or_else(|| witness_1.clone()),
witness_1,
remainder: witnesses.len().saturating_sub(3),
}
}
}
#[derive(Diagnostic)]
#[diag(mir_build_pattern_not_covered, code = "E0005")]
pub(crate) struct PatternNotCovered<'s, 'tcx> {
#[primary_span]
pub span: Span,
pub origin: &'s str,
#[subdiagnostic]
pub uncovered: Uncovered<'tcx>,
#[subdiagnostic]
pub inform: Option<Inform>,
#[subdiagnostic]
pub interpreted_as_const: Option<InterpretedAsConst>,
#[subdiagnostic]
pub adt_defined_here: Option<AdtDefinedHere<'tcx>>,
#[note(pattern_ty)]
pub _p: (),
pub pattern_ty: Ty<'tcx>,
#[subdiagnostic]
pub if_let_suggestion: Option<SuggestIfLet>,
#[subdiagnostic]
pub let_else_suggestion: Option<SuggestLetElse>,
#[subdiagnostic]
pub res_defined_here: Option<ResDefinedHere>,
}
#[derive(Subdiagnostic)]
#[note(mir_build_inform_irrefutable)]
#[note(mir_build_more_information)]
pub struct Inform;
pub struct AdtDefinedHere<'tcx> {
pub adt_def_span: Span,
pub ty: Ty<'tcx>,
pub variants: Vec<Variant>,
}
pub struct Variant {
pub span: Span,
}
impl<'tcx> AddToDiagnostic for AdtDefinedHere<'tcx> {
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
where
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
{
diag.set_arg("ty", self.ty);
let mut spans = MultiSpan::from(self.adt_def_span);
for Variant { span } in self.variants {
spans.push_span_label(span, rustc_errors::fluent::mir_build_variant_defined_here);
}
diag.span_note(spans, rustc_errors::fluent::mir_build_adt_defined_here);
}
}
#[derive(Subdiagnostic)]
#[label(mir_build_res_defined_here)]
pub struct ResDefinedHere {
#[primary_span]
pub def_span: Span,
pub res: Res,
}
#[derive(Subdiagnostic)]
#[suggestion(
mir_build_interpreted_as_const,
code = "{variable}_var",
applicability = "maybe-incorrect"
)]
#[label(mir_build_confused)]
pub struct InterpretedAsConst {
#[primary_span]
pub span: Span,
pub article: &'static str,
pub variable: String,
pub res: Res,
}
#[derive(Subdiagnostic)]
pub enum SuggestIfLet {
#[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")]
None {
#[suggestion_part(code = "if ")]
start_span: Span,
#[suggestion_part(code = " {{ todo!() }}")]
semi_span: Span,
count: usize,
},
#[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")]
One {
#[suggestion_part(code = "let {binding} = if ")]
start_span: Span,
#[suggestion_part(code = " {{ {binding} }} else {{ todo!() }}")]
end_span: Span,
binding: Ident,
count: usize,
},
#[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")]
More {
#[suggestion_part(code = "let ({bindings}) = if ")]
start_span: Span,
#[suggestion_part(code = " {{ ({bindings}) }} else {{ todo!() }}")]
end_span: Span,
bindings: String,
count: usize,
},
}
#[derive(Subdiagnostic)]
#[suggestion(
mir_build_suggest_let_else,
code = " else {{ todo!() }}",
applicability = "has-placeholders"
)]
pub struct SuggestLetElse {
#[primary_span]
pub end_span: Span,
pub count: usize,
}

View file

@ -10,6 +10,7 @@
#![feature(let_chains)]
#![feature(min_specialization)]
#![feature(once_cell)]
#![feature(try_blocks)]
#![recursion_limit = "256"]
#[macro_use]

View file

@ -1,3 +1,8 @@
//#![allow(unused_imports, unused_variables)]
//#![warn(rustc::untranslatable_diagnostic)]
//#![warn(rustc::diagnostic_outside_of_impl)]
use super::deconstruct_pat::{Constructor, DeconstructedPat};
use super::usefulness::{
compute_match_usefulness, MatchArm, MatchCheckCtxt, Reachability, UsefulnessReport,
@ -9,8 +14,7 @@
use rustc_arena::TypedArena;
use rustc_ast::Mutability;
use rustc_errors::{
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
MultiSpan,
struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
};
use rustc_hir as hir;
use rustc_hir::def::*;
@ -378,8 +382,8 @@ fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>
let pattern = self.lower_pattern(&mut cx, pat, &mut false);
let pattern_ty = pattern.ty();
let arms = vec![MatchArm { pat: pattern, hir_id: pat.hir_id, has_guard: false }];
let report = compute_match_usefulness(&cx, &arms, pat.hir_id, pattern_ty);
let arm = MatchArm { pat: pattern, hir_id: pat.hir_id, has_guard: false };
let report = compute_match_usefulness(&cx, &[arm], pat.hir_id, pattern_ty);
// Note: we ignore whether the pattern is unreachable (i.e. whether the type is empty). We
// only care about exhaustiveness here.
@ -390,145 +394,82 @@ fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>
return;
}
let joined_patterns = joined_uncovered_patterns(&cx, &witnesses);
let mut bindings = vec![];
let mut err = struct_span_err!(
self.tcx.sess,
pat.span,
E0005,
"refutable pattern in {}: {} not covered",
origin,
joined_patterns
);
let suggest_if_let = match &pat.kind {
hir::PatKind::Path(hir::QPath::Resolved(None, path))
if path.segments.len() == 1 && path.segments[0].args.is_none() =>
let (inform, interpreted_as_const, res_defined_here, if_let_suggestion, let_else_suggestion) =
if let hir::PatKind::Path(hir::QPath::Resolved(
None,
hir::Path {
segments: &[hir::PathSegment { args: None, res, ident, .. }],
..
},
)) = &pat.kind
{
const_not_var(&mut err, cx.tcx, pat, path);
false
}
_ => {
pat.walk(&mut |pat: &hir::Pat<'_>| {
match pat.kind {
hir::PatKind::Binding(_, _, ident, _) => {
bindings.push(ident);
(
None,
Some(InterpretedAsConst {
span: pat.span,
article: res.article(),
variable: ident.to_string().to_lowercase(),
res,
}),
try {
ResDefinedHere {
def_span: cx.tcx.hir().res_span(res)?,
res,
}
_ => {}
},
None, None,
)
} else if let Some(span) = sp && self.tcx.sess.source_map().is_span_accessible(span) {
let mut bindings = vec![];
pat.walk_always(&mut |pat: &hir::Pat<'_>| {
if let hir::PatKind::Binding(_, _, ident, _) = pat.kind {
bindings.push(ident);
}
true
});
err.span_label(pat.span, pattern_not_covered_label(&witnesses, &joined_patterns));
true
}
};
if let (Some(span), true) = (sp, suggest_if_let) {
err.note(
"`let` bindings require an \"irrefutable pattern\", like a `struct` or \
an `enum` with only one variant",
);
if self.tcx.sess.source_map().is_span_accessible(span) {
let semi_span = span.shrink_to_hi().with_lo(span.hi() - BytePos(1));
let start_span = span.shrink_to_lo();
let end_span = semi_span.shrink_to_lo();
err.multipart_suggestion(
&format!(
"you might want to use `if let` to ignore the variant{} that {} matched",
pluralize!(witnesses.len()),
match witnesses.len() {
1 => "isn't",
_ => "aren't",
},
),
vec![
match &bindings[..] {
[] => (start_span, "if ".to_string()),
[binding] => (start_span, format!("let {} = if ", binding)),
bindings => (
start_span,
format!(
"let ({}) = if ",
bindings
.iter()
.map(|ident| ident.to_string())
.collect::<Vec<_>>()
.join(", ")
),
),
},
match &bindings[..] {
[] => (semi_span, " { todo!() }".to_string()),
[binding] => {
(end_span, format!(" {{ {} }} else {{ todo!() }}", binding))
}
bindings => (
end_span,
format!(
" {{ ({}) }} else {{ todo!() }}",
bindings
.iter()
.map(|ident| ident.to_string())
.collect::<Vec<_>>()
.join(", ")
),
),
},
],
Applicability::HasPlaceholders,
);
if !bindings.is_empty() {
err.span_suggestion_verbose(
semi_span.shrink_to_lo(),
&format!(
"alternatively, you might want to use \
let else to handle the variant{} that {} matched",
pluralize!(witnesses.len()),
match witnesses.len() {
1 => "isn't",
_ => "aren't",
},
),
" else { todo!() }",
Applicability::HasPlaceholders,
);
}
let count = witnesses.len();
let if_let = match *bindings {
[] => SuggestIfLet::None{start_span, semi_span, count},
[binding] => SuggestIfLet::One{start_span, end_span, count, binding },
_ => SuggestIfLet::More{start_span, end_span, count, bindings: bindings
.iter()
.map(|ident| ident.to_string())
.collect::<Vec<_>>()
.join(", ")},
};
let let_else = if bindings.is_empty() {None} else{Some( SuggestLetElse{end_span, count })};
(sp.map(|_|Inform), None, None, Some(if_let), let_else)
} else{
(sp.map(|_|Inform), None, None, None, None)
};
let adt_defined_here = try {
let ty = pattern_ty.peel_refs();
let ty::Adt(def, _) = ty.kind() else { None? };
let adt_def_span = cx.tcx.hir().get_if_local(def.did())?.ident()?.span;
let mut variants = vec![];
for span in maybe_point_at_variant(&cx, *def, witnesses.iter().take(5)) {
variants.push(Variant { span });
}
err.note(
"for more information, visit \
https://doc.rust-lang.org/book/ch18-02-refutability.html",
);
}
AdtDefinedHere { adt_def_span, ty, variants }
};
adt_defined_here(&cx, &mut err, pattern_ty, &witnesses);
err.note(&format!("the matched value is of type `{}`", pattern_ty));
err.emit();
}
}
/// A path pattern was interpreted as a constant, not a new variable.
/// This caused an irrefutable match failure in e.g. `let`.
fn const_not_var(err: &mut Diagnostic, tcx: TyCtxt<'_>, pat: &Pat<'_>, path: &hir::Path<'_>) {
let descr = path.res.descr();
err.span_label(
pat.span,
format!("interpreted as {} {} pattern, not a new variable", path.res.article(), descr,),
);
err.span_suggestion(
pat.span,
"introduce a variable instead",
format!("{}_var", path.segments[0].ident).to_lowercase(),
// Cannot use `MachineApplicable` as it's not really *always* correct
// because there may be such an identifier in scope or the user maybe
// really wanted to match against the constant. This is quite unlikely however.
Applicability::MaybeIncorrect,
);
if let Some(span) = tcx.hir().res_span(path.res) {
err.span_label(span, format!("{} defined here", descr));
self.tcx.sess.emit_err(PatternNotCovered {
span: pat.span,
origin,
uncovered: Uncovered::new(pat.span, &cx, witnesses),
inform,
interpreted_as_const,
_p: (),
pattern_ty,
if_let_suggestion,
let_else_suggestion,
res_defined_here,
adt_defined_here,
});
}
}

View file

@ -292,7 +292,7 @@
use self::ArmType::*;
use self::Usefulness::*;
use super::deconstruct_pat::{Constructor, DeconstructedPat, Fields, SplitWildcard};
use crate::errors::NonExhaustiveOmittedPattern;
use crate::errors::{NonExhaustiveOmittedPattern, Uncovered};
use rustc_data_structures::captures::Captures;
@ -742,49 +742,6 @@ fn apply_constructor(mut self, pcx: &PatCtxt<'_, 'p, 'tcx>, ctor: &Constructor<'
}
}
/// Report that a match of a `non_exhaustive` enum marked with `non_exhaustive_omitted_patterns`
/// is not exhaustive enough.
///
/// NB: The partner lint for structs lives in `compiler/rustc_hir_analysis/src/check/pat.rs`.
fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>(
cx: &MatchCheckCtxt<'p, 'tcx>,
scrut_ty: Ty<'tcx>,
sp: Span,
hir_id: HirId,
witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
) {
let witness_1 = witnesses.get(0).unwrap().to_pat(cx);
cx.tcx.emit_spanned_lint(
NON_EXHAUSTIVE_OMITTED_PATTERNS,
hir_id,
sp,
NonExhaustiveOmittedPattern {
scrut_ty,
uncovered: sp,
count: witnesses.len(),
// Substitute dummy values if witnesses is smaller than 3.
witness_2: witnesses.get(1).map(|w| w.to_pat(cx)).unwrap_or_else(|| witness_1.clone()),
witness_3: witnesses.get(2).map(|w| w.to_pat(cx)).unwrap_or_else(|| witness_1.clone()),
witness_1,
},
);
/*
cx.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, hir_id, sp, "some variants are not matched explicitly", |lint| {
let joined_patterns = joined_uncovered_patterns(cx, &witnesses);
lint.span_label(sp, pattern_not_covered_label(&witnesses, &joined_patterns));
lint.help(
"ensure that all variants are matched explicitly by adding the suggested match arms",
);
lint.note(&format!(
"the matched value is of type `{}` and the `non_exhaustive_omitted_patterns` attribute was found",
scrut_ty,
));
lint
});
*/
}
/// Algorithm from <http://moscova.inria.fr/~maranget/papers/warn/index.html>.
/// The algorithm from the paper has been modified to correctly handle empty
/// types. The changes are:
@ -930,7 +887,19 @@ fn is_useful<'p, 'tcx>(
.collect::<Vec<_>>()
};
lint_non_exhaustive_omitted_patterns(pcx.cx, pcx.ty, pcx.span, hir_id, patterns);
// Report that a match of a `non_exhaustive` enum marked with `non_exhaustive_omitted_patterns`
// is not exhaustive enough.
//
// NB: The partner lint for structs lives in `compiler/rustc_hir_analysis/src/check/pat.rs`.
cx.tcx.emit_spanned_lint(
NON_EXHAUSTIVE_OMITTED_PATTERNS,
hir_id,
pcx.span,
NonExhaustiveOmittedPattern {
scrut_ty: pcx.ty,
uncovered: Uncovered::new(pcx.span, pcx.cx, patterns),
},
);
}
ret.extend(usefulness);

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in local binding: `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/const-match-check.rs:25:15
|
LL | A = { let 0 = 0; 0 },

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in local binding: `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/const-match-check.rs:31:24
|
LL | let x: [i32; { let 0 = 0; 0 }] = [];

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in local binding: `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/const-match-check.rs:4:22
|
LL | const X: i32 = { let 0 = 0; 0 };
@ -12,7 +12,7 @@ help: you might want to use `if let` to ignore the variants that aren't matched
LL | const X: i32 = { if let 0 = 0 { todo!() } 0 };
| ++ ~~~~~~~~~~~
error[E0005]: refutable pattern in local binding: `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/const-match-check.rs:8:23
|
LL | static Y: i32 = { let 0 = 0; 0 };
@ -26,7 +26,7 @@ help: you might want to use `if let` to ignore the variants that aren't matched
LL | static Y: i32 = { if let 0 = 0 { todo!() } 0 };
| ++ ~~~~~~~~~~~
error[E0005]: refutable pattern in local binding: `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/const-match-check.rs:13:26
|
LL | const X: i32 = { let 0 = 0; 0 };
@ -40,7 +40,7 @@ help: you might want to use `if let` to ignore the variants that aren't matched
LL | const X: i32 = { if let 0 = 0 { todo!() } 0 };
| ++ ~~~~~~~~~~~
error[E0005]: refutable pattern in local binding: `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/const-match-check.rs:19:26
|
LL | const X: i32 = { let 0 = 0; 0 };

View file

@ -9,8 +9,20 @@ mod foo {
const a: u8 = 2;
fn main() {
let a = 4; //~ ERROR refutable pattern in local binding: `0_u8..=1_u8` and `3_u8..=u8::MAX
let c = 4; //~ ERROR refutable pattern in local binding: `0_u8..=1_u8` and `3_u8..=u8::MAX
let d = 4; //~ ERROR refutable pattern in local binding: `0_u8..=1_u8` and `3_u8..=u8::MAX
let a = 4;
//~^ ERROR refutable pattern in local binding
//~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
//~| missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable
//~| HELP introduce a variable instead
let c = 4;
//~^ ERROR refutable pattern in local binding
//~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
//~| missing patterns are not covered because `c` is interpreted as a constant pattern, not a new variable
//~| HELP introduce a variable instead
let d = 4;
//~^ ERROR refutable pattern in local binding
//~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
//~| missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable
//~| HELP introduce a variable instead
fn f() {} // Check that the `NOTE`s still work with an item here (cf. issue #35115).
}

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in local binding: `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/const-pattern-irrefutable.rs:12:9
|
LL | const a: u8 = 2;
@ -7,13 +7,14 @@ LL | const a: u8 = 2;
LL | let a = 4;
| ^
| |
| interpreted as a constant pattern, not a new variable
| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
| missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable
| help: introduce a variable instead: `a_var`
|
= note: the matched value is of type `u8`
error[E0005]: refutable pattern in local binding: `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
--> $DIR/const-pattern-irrefutable.rs:13:9
error[E0005]: refutable pattern in local binding
--> $DIR/const-pattern-irrefutable.rs:17:9
|
LL | pub const b: u8 = 2;
| --------------- constant defined here
@ -21,13 +22,14 @@ LL | pub const b: u8 = 2;
LL | let c = 4;
| ^
| |
| interpreted as a constant pattern, not a new variable
| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
| missing patterns are not covered because `c` is interpreted as a constant pattern, not a new variable
| help: introduce a variable instead: `c_var`
|
= note: the matched value is of type `u8`
error[E0005]: refutable pattern in local binding: `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
--> $DIR/const-pattern-irrefutable.rs:14:9
error[E0005]: refutable pattern in local binding
--> $DIR/const-pattern-irrefutable.rs:22:9
|
LL | pub const d: u8 = 2;
| --------------- constant defined here
@ -35,7 +37,8 @@ LL | pub const d: u8 = 2;
LL | let d = 4;
| ^
| |
| interpreted as a constant pattern, not a new variable
| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
| missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable
| help: introduce a variable instead: `d_var`
|
= note: the matched value is of type `u8`

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in function argument: `&[]`, `&[_]` and `&[_, _, _, ..]` not covered
error[E0005]: refutable pattern in function argument
--> $DIR/const_let_refutable.rs:3:16
|
LL | const fn slice(&[a, b]: &[i32]) -> i32 {

View file

@ -8,7 +8,8 @@ enum Helper<T, U> {
fn transmute<T, U>(t: T) -> U {
let Helper::U(u) = Helper::T(t, []);
//~^ ERROR refutable pattern in local binding: `Helper::T(_, _)` not covered
//~^ ERROR refutable pattern in local binding
//~| `Helper::T(_, _)` not covered
u
}

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in local binding: `Helper::T(_, _)` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/empty-never-array.rs:10:9
|
LL | let Helper::U(u) = Helper::T(t, []);
@ -7,18 +7,18 @@ LL | let Helper::U(u) = Helper::T(t, []);
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
note: `Helper<T, U>` defined here
--> $DIR/empty-never-array.rs:4:5
--> $DIR/empty-never-array.rs:3:6
|
LL | enum Helper<T, U> {
| ------
| ^^^^^^
LL | T(T, [!; 0]),
| ^ not covered
| - not covered
= note: the matched value is of type `Helper<T, U>`
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | let u = if let Helper::U(u) = Helper::T(t, []) { u } else { todo!() };
| ++++++++++ ++++++++++++++++++++++
help: alternatively, you might want to use let else to handle the variant that isn't matched
help: alternatively, you might want to use `let else` to handle the variant that isn't matched
|
LL | let Helper::U(u) = Helper::T(t, []) else { todo!() };
| ++++++++++++++++

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in local binding: `None` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/E0005.rs:3:9
|
LL | let Some(y) = x;
@ -6,17 +6,12 @@ LL | let Some(y) = x;
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
note: `Option<i32>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL
::: $SRC_DIR/core/src/option.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Option<i32>`
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | let y = if let Some(y) = x { y } else { todo!() };
| ++++++++++ ++++++++++++++++++++++
help: alternatively, you might want to use let else to handle the variant that isn't matched
help: alternatively, you might want to use `let else` to handle the variant that isn't matched
|
LL | let Some(y) = x else { todo!() };
| ++++++++++++++++

View file

@ -1,14 +1,9 @@
error[E0005]: refutable pattern in `for` loop binding: `None` not covered
error[E0005]: refutable pattern in `for` loop binding
--> $DIR/E0297.rs:4:9
|
LL | for Some(x) in xs {}
| ^^^^^^^ pattern `None` not covered
|
note: `Option<i32>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL
::: $SRC_DIR/core/src/option.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Option<i32>`
error: aborting due to previous error

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in local binding: `Err(_)` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/feature-gate-exhaustive-patterns.rs:8:9
|
LL | let Ok(_x) = foo();
@ -6,17 +6,12 @@ LL | let Ok(_x) = foo();
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
note: `Result<u32, !>` defined here
--> $SRC_DIR/core/src/result.rs:LL:COL
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Result<u32, !>`
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | let _x = if let Ok(_x) = foo() { _x } else { todo!() };
| +++++++++++ +++++++++++++++++++++++
help: alternatively, you might want to use let else to handle the variant that isn't matched
help: alternatively, you might want to use `let else` to handle the variant that isn't matched
|
LL | let Ok(_x) = foo() else { todo!() };
| ++++++++++++++++

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in `for` loop binding: `&i32::MIN..=0_i32` and `&2_i32..=i32::MAX` not covered
error[E0005]: refutable pattern in `for` loop binding
--> $DIR/for-loop-refutable-pattern-error-message.rs:2:9
|
LL | for &1 in [1].iter() {}

View file

@ -2,7 +2,8 @@ fn main() {
let values: Vec<u8> = vec![1,2,3,4,5,6,7,8];
for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
//~^ ERROR refutable pattern in `for` loop binding: `&[]`, `&[_]`, `&[_, _]` and 1 more not
//~^ ERROR refutable pattern in `for` loop binding
//~| patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
println!("y={}", y);
}
}

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in `for` loop binding: `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
error[E0005]: refutable pattern in `for` loop binding
--> $DIR/issue-15381.rs:4:9
|
LL | for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in local binding: `Either::B(_)` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/exhaustive_patterns.rs:20:9
|
LL | let Either::A(()) = foo();
@ -7,13 +7,13 @@ LL | let Either::A(()) = foo();
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
note: `Either<(), !>` defined here
--> $DIR/exhaustive_patterns.rs:12:5
--> $DIR/exhaustive_patterns.rs:10:6
|
LL | enum Either<A, B> {
| ------
| ^^^^^^
LL | A(A),
LL | B(inner::Wrapper<B>),
| ^ not covered
| - not covered
= note: the matched value is of type `Either<(), !>`
help: you might want to use `if let` to ignore the variant that isn't matched
|

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in local binding: `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:2:10
|
LL | let (0 | (1 | 2)) = 0;

View file

@ -6,5 +6,6 @@ enum Thing {
fn main() {
let Thing::Foo(y) = Thing::Foo(1);
//~^ ERROR refutable pattern in local binding: `Thing::Bar` and `Thing::Baz` not covered
//~^ ERROR refutable pattern in local binding
//~| `Thing::Bar` and `Thing::Baz` not covered
}

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in local binding: `Thing::Bar` and `Thing::Baz` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/issue-31561.rs:8:9
|
LL | let Thing::Foo(y) = Thing::Foo(1);
@ -7,21 +7,21 @@ LL | let Thing::Foo(y) = Thing::Foo(1);
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
note: `Thing` defined here
--> $DIR/issue-31561.rs:3:5
--> $DIR/issue-31561.rs:1:6
|
LL | enum Thing {
| -----
| ^^^^^
LL | Foo(u8),
LL | Bar,
| ^^^ not covered
| --- not covered
LL | Baz
| ^^^ not covered
| --- not covered
= note: the matched value is of type `Thing`
help: you might want to use `if let` to ignore the variants that aren't matched
|
LL | let y = if let Thing::Foo(y) = Thing::Foo(1) { y } else { todo!() };
| ++++++++++ ++++++++++++++++++++++
help: alternatively, you might want to use let else to handle the variants that aren't matched
help: alternatively, you might want to use `let else` to handle the variants that aren't matched
|
LL | let Thing::Foo(y) = Thing::Foo(1) else { todo!() };
| ++++++++++++++++

View file

@ -15,9 +15,6 @@ enum E {
//~^ NOTE `E` defined here
//~| NOTE `E` defined here
//~| NOTE `E` defined here
//~| NOTE `E` defined here
//~| NOTE `E` defined here
//~| NOTE `E` defined here
//~| NOTE not covered
//~| NOTE not covered
//~| NOTE not covered
@ -41,37 +38,41 @@ fn by_val(e: E) {
E::A => {}
}
let E::A = e; //~ ERROR refutable pattern in local binding: `E::B` and `E::C` not covered
//~^ NOTE patterns `E::B` and `E::C` not covered
let E::A = e;
//~^ ERROR refutable pattern in local binding
//~| patterns `E::B` and `E::C` not covered
//~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
//~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
//~| NOTE the matched value is of type `E`
}
fn by_ref_once(e: &E) {
match e { //~ ERROR non-exhaustive patterns: `&E::B` and `&E::C` not covered
//~^ NOTE patterns `&E::B` and `&E::C` not covered
match e {
//~^ ERROR non-exhaustive patterns
//~| patterns `&E::B` and `&E::C` not covered
//~| NOTE the matched value is of type `&E`
E::A => {}
}
let E::A = e; //~ ERROR refutable pattern in local binding: `&E::B` and `&E::C` not covered
//~^ NOTE patterns `&E::B` and `&E::C` not covered
let E::A = e;
//~^ ERROR refutable pattern in local binding
//~| patterns `&E::B` and `&E::C` not covered
//~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
//~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
//~| NOTE the matched value is of type `&E`
}
fn by_ref_thrice(e: & &mut &E) {
match e { //~ ERROR non-exhaustive patterns: `&&mut &E::B` and `&&mut &E::C` not covered
//~^ NOTE patterns `&&mut &E::B` and `&&mut &E::C` not covered
match e {
//~^ ERROR non-exhaustive patterns
//~| patterns `&&mut &E::B` and `&&mut &E::C` not covered
//~| NOTE the matched value is of type `&&mut &E`
E::A => {}
}
let E::A = e;
//~^ ERROR refutable pattern in local binding: `&&mut &E::B` and `&&mut &E::C` not covered
//~| NOTE patterns `&&mut &E::B` and `&&mut &E::C` not covered
//~^ ERROR refutable pattern in local binding
//~| patterns `&&mut &E::B` and `&&mut &E::C` not covered
//~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
//~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
//~| NOTE the matched value is of type `&&mut &E`
@ -83,20 +84,21 @@ enum Opt {
Some(u8),
None,
//~^ NOTE `Opt` defined here
//~| NOTE `Opt` defined here
//~| NOTE not covered
//~| NOTE not covered
}
fn ref_pat(e: Opt) {
match e {//~ ERROR non-exhaustive patterns: `Opt::None` not covered
//~^ NOTE pattern `Opt::None` not covered
match e {
//~^ ERROR non-exhaustive patterns
//~| pattern `Opt::None` not covered
//~| NOTE the matched value is of type `Opt`
Opt::Some(ref _x) => {}
}
let Opt::Some(ref _x) = e; //~ ERROR refutable pattern in local binding: `Opt::None` not covered
//~^ NOTE the matched value is of type `Opt`
let Opt::Some(ref _x) = e;
//~^ ERROR refutable pattern in local binding
//~| NOTE the matched value is of type `Opt`
//~| NOTE pattern `Opt::None` not covered
//~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
//~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html

View file

@ -1,5 +1,5 @@
error[E0004]: non-exhaustive patterns: `E::B` and `E::C` not covered
--> $DIR/non-exhaustive-defined-here.rs:38:11
--> $DIR/non-exhaustive-defined-here.rs:35:11
|
LL | match e1 {
| ^^ patterns `E::B` and `E::C` not covered
@ -22,8 +22,8 @@ LL ~ E::A => {}
LL + E::B | E::C => todo!()
|
error[E0005]: refutable pattern in local binding: `E::B` and `E::C` not covered
--> $DIR/non-exhaustive-defined-here.rs:44:9
error[E0005]: refutable pattern in local binding
--> $DIR/non-exhaustive-defined-here.rs:41:9
|
LL | let E::A = e;
| ^^^^ patterns `E::B` and `E::C` not covered
@ -31,16 +31,16 @@ LL | let E::A = e;
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
note: `E` defined here
--> $DIR/non-exhaustive-defined-here.rs:14:5
--> $DIR/non-exhaustive-defined-here.rs:6:6
|
LL | enum E {
| -
| ^
...
LL | B,
| ^ not covered
| - not covered
...
LL | C
| ^ not covered
| - not covered
= note: the matched value is of type `E`
help: you might want to use `if let` to ignore the variants that aren't matched
|
@ -48,7 +48,7 @@ LL | if let E::A = e { todo!() }
| ++ ~~~~~~~~~~~
error[E0004]: non-exhaustive patterns: `&E::B` and `&E::C` not covered
--> $DIR/non-exhaustive-defined-here.rs:52:11
--> $DIR/non-exhaustive-defined-here.rs:50:11
|
LL | match e {
| ^ patterns `&E::B` and `&E::C` not covered
@ -71,8 +71,8 @@ LL ~ E::A => {}
LL + &E::B | &E::C => todo!()
|
error[E0005]: refutable pattern in local binding: `&E::B` and `&E::C` not covered
--> $DIR/non-exhaustive-defined-here.rs:58:9
error[E0005]: refutable pattern in local binding
--> $DIR/non-exhaustive-defined-here.rs:57:9
|
LL | let E::A = e;
| ^^^^ patterns `&E::B` and `&E::C` not covered
@ -80,16 +80,16 @@ LL | let E::A = e;
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
note: `E` defined here
--> $DIR/non-exhaustive-defined-here.rs:14:5
--> $DIR/non-exhaustive-defined-here.rs:6:6
|
LL | enum E {
| -
| ^
...
LL | B,
| ^ not covered
| - not covered
...
LL | C
| ^ not covered
| - not covered
= note: the matched value is of type `&E`
help: you might want to use `if let` to ignore the variants that aren't matched
|
@ -120,8 +120,8 @@ LL ~ E::A => {}
LL + &&mut &E::B | &&mut &E::C => todo!()
|
error[E0005]: refutable pattern in local binding: `&&mut &E::B` and `&&mut &E::C` not covered
--> $DIR/non-exhaustive-defined-here.rs:72:9
error[E0005]: refutable pattern in local binding
--> $DIR/non-exhaustive-defined-here.rs:73:9
|
LL | let E::A = e;
| ^^^^ patterns `&&mut &E::B` and `&&mut &E::C` not covered
@ -129,16 +129,16 @@ LL | let E::A = e;
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
note: `E` defined here
--> $DIR/non-exhaustive-defined-here.rs:14:5
--> $DIR/non-exhaustive-defined-here.rs:6:6
|
LL | enum E {
| -
| ^
...
LL | B,
| ^ not covered
| - not covered
...
LL | C
| ^ not covered
| - not covered
= note: the matched value is of type `&&mut &E`
help: you might want to use `if let` to ignore the variants that aren't matched
|
@ -152,7 +152,7 @@ LL | match e {
| ^ pattern `Opt::None` not covered
|
note: `Opt` defined here
--> $DIR/non-exhaustive-defined-here.rs:84:5
--> $DIR/non-exhaustive-defined-here.rs:85:5
|
LL | enum Opt {
| ---
@ -166,8 +166,8 @@ LL ~ Opt::Some(ref _x) => {}
LL + Opt::None => todo!()
|
error[E0005]: refutable pattern in local binding: `Opt::None` not covered
--> $DIR/non-exhaustive-defined-here.rs:98:9
error[E0005]: refutable pattern in local binding
--> $DIR/non-exhaustive-defined-here.rs:99:9
|
LL | let Opt::Some(ref _x) = e;
| ^^^^^^^^^^^^^^^^^ pattern `Opt::None` not covered
@ -175,19 +175,19 @@ LL | let Opt::Some(ref _x) = e;
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
note: `Opt` defined here
--> $DIR/non-exhaustive-defined-here.rs:84:5
--> $DIR/non-exhaustive-defined-here.rs:81:6
|
LL | enum Opt {
| ---
| ^^^
...
LL | None,
| ^^^^ not covered
| ---- not covered
= note: the matched value is of type `Opt`
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | let _x = if let Opt::Some(ref _x) = e { _x } else { todo!() };
| +++++++++++ +++++++++++++++++++++++
help: alternatively, you might want to use let else to handle the variant that isn't matched
help: alternatively, you might want to use `let else` to handle the variant that isn't matched
|
LL | let Opt::Some(ref _x) = e else { todo!() };
| ++++++++++++++++

View file

@ -1,7 +1,9 @@
fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { }
//~^ ERROR refutable pattern in function argument: `(_, _)` not covered
//~^ ERROR refutable pattern in function argument
//~| `(_, _)` not covered
fn main() {
let (1, (Some(1), 2..=3)) = (1, (None, 2));
//~^ ERROR refutable pattern in local binding: `(i32::MIN..=0_i32, _)` and `(2_i32..=i32::MAX, _)` not covered
//~^ ERROR refutable pattern in local binding
//~| `(i32::MIN..=0_i32, _)` and `(2_i32..=i32::MAX, _)` not covered
}

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in function argument: `(_, _)` not covered
error[E0005]: refutable pattern in function argument
--> $DIR/refutable-pattern-errors.rs:1:9
|
LL | fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { }
@ -6,8 +6,8 @@ LL | fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { }
|
= note: the matched value is of type `(isize, (Option<isize>, isize))`
error[E0005]: refutable pattern in local binding: `(i32::MIN..=0_i32, _)` and `(2_i32..=i32::MAX, _)` not covered
--> $DIR/refutable-pattern-errors.rs:5:9
error[E0005]: refutable pattern in local binding
--> $DIR/refutable-pattern-errors.rs:6:9
|
LL | let (1, (Some(1), 2..=3)) = (1, (None, 2));
| ^^^^^^^^^^^^^^^^^^^^^ patterns `(i32::MIN..=0_i32, _)` and `(2_i32..=i32::MAX, _)` not covered

View file

@ -1,5 +1,6 @@
fn main() {
let f = |3: isize| println!("hello");
//~^ ERROR refutable pattern in function argument: `_` not covered
//~^ ERROR refutable pattern in function argument
//~| `_` not covered
f(4);
}

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in function argument: `_` not covered
error[E0005]: refutable pattern in function argument
--> $DIR/refutable-pattern-in-fn-arg.rs:2:14
|
LL | let f = |3: isize| println!("hello");

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in local binding: `Err(_)` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/recursive-types-are-not-uninhabited.rs:6:9
|
LL | let Ok(x) = res;
@ -6,17 +6,12 @@ LL | let Ok(x) = res;
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
note: `Result<u32, &R<'_>>` defined here
--> $SRC_DIR/core/src/result.rs:LL:COL
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Result<u32, &R<'_>>`
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | let x = if let Ok(x) = res { x } else { todo!() };
| ++++++++++ ++++++++++++++++++++++
help: alternatively, you might want to use let else to handle the variant that isn't matched
help: alternatively, you might want to use `let else` to handle the variant that isn't matched
|
LL | let Ok(x) = res else { todo!() };
| ++++++++++++++++

View file

@ -1,7 +1,8 @@
fn main() {
let A = 3;
//~^ ERROR refutable pattern in local binding: `i32::MIN..=1_i32` and
//~| interpreted as a constant pattern, not a new variable
//~^ ERROR refutable pattern in local binding
//~| patterns `i32::MIN..=1_i32` and `3_i32..=i32::MAX` not covered
//~| missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable
//~| HELP introduce a variable instead
//~| SUGGESTION a_var

View file

@ -1,10 +1,11 @@
error[E0005]: refutable pattern in local binding: `i32::MIN..=1_i32` and `3_i32..=i32::MAX` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/const-pat-non-exaustive-let-new-var.rs:2:9
|
LL | let A = 3;
| ^
| |
| interpreted as a constant pattern, not a new variable
| patterns `i32::MIN..=1_i32` and `3_i32..=i32::MAX` not covered
| missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable
| help: introduce a variable instead: `a_var`
...
LL | const A: i32 = 2;

View file

@ -24,5 +24,7 @@ enum Foo {
fn main() {
let x: Foo = Foo::D(123, 456);
let Foo::D(_y, _z) = x; //~ ERROR refutable pattern in local binding: `Foo::A(_)` not covered
let Foo::D(_y, _z) = x;
//~^ ERROR refutable pattern in local binding
//~| `Foo::A(_)` not covered
}

View file

@ -1,4 +1,4 @@
error[E0005]: refutable pattern in local binding: `Foo::A(_)` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/uninhabited-irrefutable.rs:27:9
|
LL | let Foo::D(_y, _z) = x;
@ -7,18 +7,18 @@ LL | let Foo::D(_y, _z) = x;
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
note: `Foo` defined here
--> $DIR/uninhabited-irrefutable.rs:19:5
--> $DIR/uninhabited-irrefutable.rs:18:6
|
LL | enum Foo {
| ---
| ^^^
LL | A(foo::SecretlyEmpty),
| ^ not covered
| - not covered
= note: the matched value is of type `Foo`
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | let (_y, _z) = if let Foo::D(_y, _z) = x { (_y, _z) } else { todo!() };
| +++++++++++++++++ +++++++++++++++++++++++++++++
help: alternatively, you might want to use let else to handle the variant that isn't matched
help: alternatively, you might want to use `let else` to handle the variant that isn't matched
|
LL | let Foo::D(_y, _z) = x else { todo!() };
| ++++++++++++++++

View file

@ -95,7 +95,7 @@ LL ~ Ok(x) => x,
LL ~ Err(_) => todo!(),
|
error[E0005]: refutable pattern in local binding: `Err(_)` not covered
error[E0005]: refutable pattern in local binding
--> $DIR/uninhabited-matches-feature-gated.rs:37:9
|
LL | let Ok(x) = x;
@ -103,17 +103,12 @@ LL | let Ok(x) = x;
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
note: `Result<u32, Void>` defined here
--> $SRC_DIR/core/src/result.rs:LL:COL
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Result<u32, Void>`
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | let x = if let Ok(x) = x { x } else { todo!() };
| ++++++++++ ++++++++++++++++++++++
help: alternatively, you might want to use let else to handle the variant that isn't matched
help: alternatively, you might want to use `let else` to handle the variant that isn't matched
|
LL | let Ok(x) = x else { todo!() };
| ++++++++++++++++