Perform match checking on THIR.
This commit is contained in:
parent
3b47cdc439
commit
05082f57af
81 changed files with 668 additions and 997 deletions
|
@ -2,7 +2,6 @@ use crate::def::{CtorOf, DefKind, Res};
|
|||
use crate::def_id::DefId;
|
||||
use crate::hir::{self, BindingAnnotation, ByRef, HirId, PatKind};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_span::hygiene::DesugaringKind;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::Span;
|
||||
|
||||
|
@ -136,14 +135,4 @@ impl hir::Pat<'_> {
|
|||
});
|
||||
result
|
||||
}
|
||||
|
||||
/// If the pattern is `Some(<pat>)` from a desugared for loop, returns the inner pattern
|
||||
pub fn for_loop_some(&self) -> Option<&Self> {
|
||||
if self.span.desugaring_kind() == Some(DesugaringKind::ForLoop) {
|
||||
if let hir::PatKind::Struct(_, [pat_field], _) = self.kind {
|
||||
return Some(pat_field.pat);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -239,19 +239,9 @@ mir_build_trailing_irrefutable_let_patterns = trailing irrefutable {$count ->
|
|||
} into the body
|
||||
|
||||
mir_build_bindings_with_variant_name =
|
||||
pattern binding `{$ident}` is named the same as one of the variants of the type `{$ty_path}`
|
||||
pattern binding `{$name}` is named the same as one of the variants of the type `{$ty_path}`
|
||||
.suggestion = to match on the variant, qualify the path
|
||||
|
||||
mir_build_irrefutable_let_patterns_generic_let = irrefutable `let` {$count ->
|
||||
[one] pattern
|
||||
*[other] patterns
|
||||
}
|
||||
.note = {$count ->
|
||||
[one] this pattern
|
||||
*[other] these patterns
|
||||
} will always match, so the `let` is useless
|
||||
.help = consider removing `let`
|
||||
|
||||
mir_build_irrefutable_let_patterns_if_let = irrefutable `if let` {$count ->
|
||||
[one] pattern
|
||||
*[other] patterns
|
||||
|
|
|
@ -58,6 +58,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
|
|||
ty::WithOptConstParam { did, const_param_did: None } => {
|
||||
tcx.ensure_with_value().thir_check_unsafety(did);
|
||||
tcx.ensure_with_value().thir_abstract_const(did);
|
||||
tcx.ensure_with_value().check_match(did);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,8 @@ use rustc_hir::def::Res;
|
|||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||
use rustc_middle::thir::Pat;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::{symbol::Ident, Span};
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::Span;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(mir_build_unconditional_recursion)]
|
||||
|
@ -534,18 +535,10 @@ pub struct TrailingIrrefutableLetPatterns {
|
|||
#[derive(LintDiagnostic)]
|
||||
#[diag(mir_build_bindings_with_variant_name, code = "E0170")]
|
||||
pub struct BindingsWithVariantName {
|
||||
#[suggestion(code = "{ty_path}::{ident}", applicability = "machine-applicable")]
|
||||
#[suggestion(code = "{ty_path}::{name}", applicability = "machine-applicable")]
|
||||
pub suggestion: Option<Span>,
|
||||
pub ty_path: String,
|
||||
pub ident: Ident,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(mir_build_irrefutable_let_patterns_generic_let)]
|
||||
#[note]
|
||||
#[help]
|
||||
pub struct IrrefutableLetPatternsGenericLet {
|
||||
pub count: usize,
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
|
@ -590,7 +583,7 @@ pub struct BorrowOfMovedValue<'tcx> {
|
|||
pub binding_span: Span,
|
||||
#[label(mir_build_value_borrowed_label)]
|
||||
pub conflicts_ref: Vec<Span>,
|
||||
pub name: Ident,
|
||||
pub name: Symbol,
|
||||
pub ty: Ty<'tcx>,
|
||||
#[suggestion(code = "ref ", applicability = "machine-applicable")]
|
||||
pub suggest_borrowing: Option<Span>,
|
||||
|
@ -638,19 +631,19 @@ pub enum Conflict {
|
|||
Mut {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
name: Ident,
|
||||
name: Symbol,
|
||||
},
|
||||
#[label(mir_build_borrow)]
|
||||
Ref {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
name: Ident,
|
||||
name: Symbol,
|
||||
},
|
||||
#[label(mir_build_moved)]
|
||||
Moved {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
name: Ident,
|
||||
name: Symbol,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -2,41 +2,48 @@ use super::deconstruct_pat::{Constructor, DeconstructedPat};
|
|||
use super::usefulness::{
|
||||
compute_match_usefulness, MatchArm, MatchCheckCtxt, Reachability, UsefulnessReport,
|
||||
};
|
||||
use super::{PatCtxt, PatternError};
|
||||
|
||||
use crate::errors::*;
|
||||
|
||||
use hir::{ExprKind, PatKind};
|
||||
use rustc_arena::TypedArena;
|
||||
use rustc_ast::{LitKind, Mutability};
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_errors::{
|
||||
struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::*;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::{HirId, Pat};
|
||||
use rustc_hir::HirId;
|
||||
use rustc_middle::thir::visit::{self, Visitor};
|
||||
use rustc_middle::thir::*;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
|
||||
|
||||
use rustc_session::lint::builtin::{
|
||||
BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS,
|
||||
};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{BytePos, Span};
|
||||
use rustc_span::hygiene::DesugaringKind;
|
||||
use rustc_span::Span;
|
||||
|
||||
pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
let body_id = tcx.hir().body_owned_by(def_id);
|
||||
let Ok((thir, expr)) = tcx.thir_body(ty::WithOptConstParam::unknown(def_id)) else { return };
|
||||
let thir = thir.borrow();
|
||||
let pattern_arena = TypedArena::default();
|
||||
let mut visitor = MatchVisitor {
|
||||
tcx,
|
||||
typeck_results: tcx.typeck_body(body_id),
|
||||
thir: &*thir,
|
||||
param_env: tcx.param_env(def_id),
|
||||
lint_level: tcx.hir().local_def_id_to_hir_id(def_id),
|
||||
let_source: LetSource::None,
|
||||
pattern_arena: &pattern_arena,
|
||||
};
|
||||
visitor.visit_body(tcx.hir().body(body_id));
|
||||
visitor.visit_expr(&thir[expr]);
|
||||
for param in thir.params.iter() {
|
||||
if let Some(box ref pattern) = param.pat {
|
||||
visitor.check_irrefutable(pattern, "function argument", None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_e0004(
|
||||
|
@ -54,77 +61,132 @@ enum RefutableFlag {
|
|||
}
|
||||
use RefutableFlag::*;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
enum LetSource {
|
||||
None,
|
||||
IfLet,
|
||||
IfLetGuard,
|
||||
LetElse,
|
||||
WhileLet,
|
||||
}
|
||||
|
||||
struct MatchVisitor<'a, 'p, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
thir: &'a Thir<'tcx>,
|
||||
lint_level: HirId,
|
||||
let_source: LetSource,
|
||||
pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, '_, 'tcx> {
|
||||
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
|
||||
intravisit::walk_expr(self, ex);
|
||||
match &ex.kind {
|
||||
hir::ExprKind::Match(scrut, arms, source) => {
|
||||
self.check_match(scrut, arms, *source, ex.span)
|
||||
impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> {
|
||||
fn thir(&self) -> &'a Thir<'tcx> {
|
||||
self.thir
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn visit_arm(&mut self, arm: &Arm<'tcx>) {
|
||||
match arm.guard {
|
||||
Some(Guard::If(expr)) => {
|
||||
self.with_let_source(LetSource::IfLetGuard, |this| {
|
||||
this.visit_expr(&this.thir[expr])
|
||||
});
|
||||
}
|
||||
Some(Guard::IfLet(ref pat, expr)) => {
|
||||
self.with_let_source(LetSource::IfLetGuard, |this| {
|
||||
this.check_let(pat, expr, LetSource::IfLetGuard, pat.span);
|
||||
this.visit_pat(pat);
|
||||
this.visit_expr(&this.thir[expr]);
|
||||
});
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
self.visit_pat(&arm.pattern);
|
||||
self.visit_expr(&self.thir[arm.body]);
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn visit_expr(&mut self, ex: &Expr<'tcx>) {
|
||||
match ex.kind {
|
||||
ExprKind::Scope { value, lint_level, .. } => {
|
||||
let old_lint_level = self.lint_level;
|
||||
if let LintLevel::Explicit(hir_id) = lint_level {
|
||||
self.lint_level = hir_id;
|
||||
}
|
||||
self.visit_expr(&self.thir[value]);
|
||||
self.lint_level = old_lint_level;
|
||||
return;
|
||||
}
|
||||
ExprKind::If { cond, then, else_opt, if_then_scope: _ } => {
|
||||
// Give a specific `let_source` for the condition.
|
||||
let let_source = match ex.span.desugaring_kind() {
|
||||
Some(DesugaringKind::WhileLoop) => LetSource::WhileLet,
|
||||
_ => LetSource::IfLet,
|
||||
};
|
||||
self.with_let_source(let_source, |this| this.visit_expr(&self.thir[cond]));
|
||||
self.with_let_source(LetSource::None, |this| {
|
||||
this.visit_expr(&this.thir[then]);
|
||||
if let Some(else_) = else_opt {
|
||||
this.visit_expr(&this.thir[else_]);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
ExprKind::Match { scrutinee, box ref arms } => {
|
||||
let source = match ex.span.desugaring_kind() {
|
||||
Some(DesugaringKind::ForLoop) => hir::MatchSource::ForLoopDesugar,
|
||||
Some(DesugaringKind::QuestionMark) => hir::MatchSource::TryDesugar,
|
||||
Some(DesugaringKind::Await) => hir::MatchSource::AwaitDesugar,
|
||||
_ => hir::MatchSource::Normal,
|
||||
};
|
||||
self.check_match(scrutinee, arms, source, ex.span);
|
||||
}
|
||||
ExprKind::Let { box ref pat, expr } => {
|
||||
self.check_let(pat, expr, self.let_source, ex.span);
|
||||
}
|
||||
ExprKind::LogicalOp { op: LogicalOp::And, .. } => {
|
||||
self.check_let_chain(ex, self.let_source);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
self.with_let_source(LetSource::None, |this| visit::walk_expr(this, ex));
|
||||
}
|
||||
|
||||
fn visit_stmt(&mut self, stmt: &Stmt<'tcx>) {
|
||||
let old_lint_level = self.lint_level;
|
||||
match stmt.kind {
|
||||
StmtKind::Let {
|
||||
box ref pattern, initializer, else_block, lint_level, span, ..
|
||||
} => {
|
||||
if let LintLevel::Explicit(lint_level) = lint_level {
|
||||
self.lint_level = lint_level;
|
||||
}
|
||||
|
||||
if let Some(initializer) = initializer && else_block.is_some() {
|
||||
self.check_let(pattern, initializer, LetSource::LetElse, span);
|
||||
}
|
||||
|
||||
if else_block.is_none() {
|
||||
self.check_irrefutable(pattern, "local binding", Some(span));
|
||||
}
|
||||
hir::ExprKind::Let(hir::Let { pat, init, span, .. }) => {
|
||||
self.check_let(pat, init, *span)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, loc: &'tcx hir::Local<'tcx>) {
|
||||
intravisit::walk_local(self, loc);
|
||||
let els = loc.els;
|
||||
if let Some(init) = loc.init && els.is_some() {
|
||||
// Build a span without the else { ... } as we don't want to underline
|
||||
// the entire else block in the IDE setting.
|
||||
let span = loc.span.with_hi(init.span.hi());
|
||||
self.check_let(&loc.pat, init, span);
|
||||
}
|
||||
|
||||
let (msg, sp) = match loc.source {
|
||||
hir::LocalSource::Normal => ("local binding", Some(loc.span)),
|
||||
hir::LocalSource::AsyncFn => ("async fn binding", None),
|
||||
hir::LocalSource::AwaitDesugar => ("`await` future binding", None),
|
||||
hir::LocalSource::AssignDesugar(_) => ("destructuring assignment binding", None),
|
||||
};
|
||||
if els.is_none() {
|
||||
self.check_irrefutable(&loc.pat, msg, sp);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
|
||||
intravisit::walk_param(self, param);
|
||||
self.check_irrefutable(¶m.pat, "function argument", None);
|
||||
}
|
||||
}
|
||||
|
||||
impl PatCtxt<'_, '_> {
|
||||
fn report_inlining_errors(&self) {
|
||||
for error in &self.errors {
|
||||
match *error {
|
||||
PatternError::StaticInPattern(span) => {
|
||||
self.tcx.sess.emit_err(StaticInPattern { span });
|
||||
}
|
||||
PatternError::AssocConstInPattern(span) => {
|
||||
self.tcx.sess.emit_err(AssocConstInPattern { span });
|
||||
}
|
||||
PatternError::ConstParamInPattern(span) => {
|
||||
self.tcx.sess.emit_err(ConstParamInPattern { span });
|
||||
}
|
||||
PatternError::NonConstPath(span) => {
|
||||
self.tcx.sess.emit_err(NonConstPath { span });
|
||||
}
|
||||
}
|
||||
}
|
||||
visit::walk_stmt(self, stmt);
|
||||
self.lint_level = old_lint_level;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
||||
fn check_patterns(&self, pat: &Pat<'_>, rf: RefutableFlag) {
|
||||
#[instrument(level = "trace", skip(self, f))]
|
||||
fn with_let_source(&mut self, let_source: LetSource, f: impl FnOnce(&mut Self)) {
|
||||
let old_let_source = self.let_source;
|
||||
self.let_source = let_source;
|
||||
ensure_sufficient_stack(|| f(self));
|
||||
self.let_source = old_let_source;
|
||||
}
|
||||
|
||||
fn check_patterns(&self, pat: &Pat<'tcx>, rf: RefutableFlag) {
|
||||
pat.walk_always(|pat| check_borrow_conflicts_in_at_patterns(self, pat));
|
||||
check_for_bindings_named_same_as_variants(self, pat, rf);
|
||||
}
|
||||
|
@ -132,18 +194,9 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
|||
fn lower_pattern(
|
||||
&self,
|
||||
cx: &mut MatchCheckCtxt<'p, 'tcx>,
|
||||
pat: &'tcx hir::Pat<'tcx>,
|
||||
have_errors: &mut bool,
|
||||
pattern: &Pat<'tcx>,
|
||||
) -> &'p DeconstructedPat<'p, 'tcx> {
|
||||
let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.typeck_results);
|
||||
patcx.include_lint_checks();
|
||||
let pattern = patcx.lower_pattern(pat);
|
||||
let pattern: &_ = cx.pattern_arena.alloc(DeconstructedPat::from_pat(cx, &pattern));
|
||||
if !patcx.errors.is_empty() {
|
||||
*have_errors = true;
|
||||
patcx.report_inlining_errors();
|
||||
}
|
||||
pattern
|
||||
cx.pattern_arena.alloc(DeconstructedPat::from_pat(cx, &pattern))
|
||||
}
|
||||
|
||||
fn new_cx(&self, hir_id: HirId) -> MatchCheckCtxt<'p, 'tcx> {
|
||||
|
@ -155,50 +208,48 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_let(&mut self, pat: &'tcx hir::Pat<'tcx>, scrutinee: &hir::Expr<'_>, span: Span) {
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn check_let(&mut self, pat: &Pat<'tcx>, scrutinee: ExprId, source: LetSource, span: Span) {
|
||||
if let LetSource::None = source {
|
||||
return;
|
||||
}
|
||||
self.check_patterns(pat, Refutable);
|
||||
let mut cx = self.new_cx(scrutinee.hir_id);
|
||||
let tpat = self.lower_pattern(&mut cx, pat, &mut false);
|
||||
self.check_let_reachability(&mut cx, pat.hir_id, tpat, span);
|
||||
let mut cx = self.new_cx(self.lint_level);
|
||||
let tpat = self.lower_pattern(&mut cx, pat);
|
||||
self.check_let_reachability(&mut cx, self.lint_level, source, tpat, span);
|
||||
}
|
||||
|
||||
fn check_match(
|
||||
&mut self,
|
||||
scrut: &hir::Expr<'_>,
|
||||
hir_arms: &'tcx [hir::Arm<'tcx>],
|
||||
scrut: ExprId,
|
||||
arms: &[ArmId],
|
||||
source: hir::MatchSource,
|
||||
expr_span: Span,
|
||||
) {
|
||||
let mut cx = self.new_cx(scrut.hir_id);
|
||||
let mut cx = self.new_cx(self.lint_level);
|
||||
|
||||
for arm in hir_arms {
|
||||
for &arm in arms {
|
||||
// Check the arm for some things unrelated to exhaustiveness.
|
||||
self.check_patterns(&arm.pat, Refutable);
|
||||
if let Some(hir::Guard::IfLet(ref let_expr)) = arm.guard {
|
||||
self.check_patterns(let_expr.pat, Refutable);
|
||||
let tpat = self.lower_pattern(&mut cx, let_expr.pat, &mut false);
|
||||
self.check_let_reachability(&mut cx, let_expr.pat.hir_id, tpat, tpat.span());
|
||||
}
|
||||
let arm = &self.thir.arms[arm];
|
||||
self.check_patterns(&arm.pattern, Refutable);
|
||||
}
|
||||
|
||||
let mut have_errors = false;
|
||||
|
||||
let arms: Vec<_> = hir_arms
|
||||
let tarms: Vec<_> = arms
|
||||
.iter()
|
||||
.map(|hir::Arm { pat, guard, .. }| MatchArm {
|
||||
pat: self.lower_pattern(&mut cx, pat, &mut have_errors),
|
||||
hir_id: pat.hir_id,
|
||||
has_guard: guard.is_some(),
|
||||
.map(|&arm| {
|
||||
let arm = &self.thir.arms[arm];
|
||||
let hir_id = match arm.lint_level {
|
||||
LintLevel::Explicit(hir_id) => hir_id,
|
||||
LintLevel::Inherited => self.lint_level,
|
||||
};
|
||||
let pat = self.lower_pattern(&mut cx, &arm.pattern);
|
||||
MatchArm { pat, hir_id, has_guard: arm.guard.is_some() }
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Bail out early if lowering failed.
|
||||
if have_errors {
|
||||
return;
|
||||
}
|
||||
|
||||
let scrut_ty = self.typeck_results.expr_ty_adjusted(scrut);
|
||||
let report = compute_match_usefulness(&cx, &arms, scrut.hir_id, scrut_ty);
|
||||
let scrut = &self.thir[scrut];
|
||||
let scrut_ty = scrut.ty;
|
||||
let report = compute_match_usefulness(&cx, &tarms, self.lint_level, scrut_ty);
|
||||
|
||||
match source {
|
||||
// Don't report arm reachability of desugared `match $iter.into_iter() { iter => .. }`
|
||||
|
@ -215,12 +266,18 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
|||
// Check if the match is exhaustive.
|
||||
let witnesses = report.non_exhaustiveness_witnesses;
|
||||
if !witnesses.is_empty() {
|
||||
if source == hir::MatchSource::ForLoopDesugar && hir_arms.len() == 2 {
|
||||
if source == hir::MatchSource::ForLoopDesugar && arms.len() == 2 {
|
||||
// the for loop pattern is not irrefutable
|
||||
let pat = hir_arms[1].pat.for_loop_some().unwrap();
|
||||
self.check_irrefutable(pat, "`for` loop binding", None);
|
||||
let pat = &self.thir[arms[1]].pattern;
|
||||
// `pat` should be `Some(<pat_field>)` from a desugared for loop.
|
||||
debug_assert_eq!(pat.span.desugaring_kind(), Some(DesugaringKind::ForLoop));
|
||||
let PatKind::Variant { ref subpatterns, .. } = pat.kind else { bug!() };
|
||||
let [pat_field] = &subpatterns[..] else { bug!() };
|
||||
self.check_irrefutable(&pat_field.pattern, "`for` loop binding", None);
|
||||
} else {
|
||||
non_exhaustive_match(&cx, scrut_ty, scrut.span, witnesses, hir_arms, expr_span);
|
||||
non_exhaustive_match(
|
||||
&cx, self.thir, scrut_ty, scrut.span, witnesses, arms, expr_span,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -229,114 +286,92 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
|||
&mut self,
|
||||
cx: &mut MatchCheckCtxt<'p, 'tcx>,
|
||||
pat_id: HirId,
|
||||
source: LetSource,
|
||||
pat: &'p DeconstructedPat<'p, 'tcx>,
|
||||
span: Span,
|
||||
) {
|
||||
if self.check_let_chain(cx, pat_id) {
|
||||
if is_let_irrefutable(cx, pat_id, pat) {
|
||||
irrefutable_let_patterns(cx.tcx, pat_id, source, 1, span);
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn check_let_chain(&mut self, top_expr: &Expr<'tcx>, let_source: LetSource) {
|
||||
if let LetSource::None = let_source {
|
||||
return;
|
||||
}
|
||||
|
||||
if is_let_irrefutable(cx, pat_id, pat) {
|
||||
irrefutable_let_pattern(cx.tcx, pat_id, span);
|
||||
}
|
||||
}
|
||||
let ExprKind::LogicalOp { op: LogicalOp::And, mut lhs, rhs } = top_expr.kind else { bug!() };
|
||||
|
||||
fn check_let_chain(&mut self, cx: &mut MatchCheckCtxt<'p, 'tcx>, pat_id: HirId) -> bool {
|
||||
let hir = self.tcx.hir();
|
||||
let parent = hir.parent_id(pat_id);
|
||||
// Lint level enclosing the next `lhs`.
|
||||
let mut cur_lint_level = self.lint_level;
|
||||
|
||||
// First, figure out if the given pattern is part of a let chain,
|
||||
// and if so, obtain the top node of the chain.
|
||||
let mut top = parent;
|
||||
let mut part_of_chain = false;
|
||||
loop {
|
||||
let new_top = hir.parent_id(top);
|
||||
if let hir::Node::Expr(
|
||||
hir::Expr {
|
||||
kind: hir::ExprKind::Binary(Spanned { node: hir::BinOpKind::And, .. }, lhs, rhs),
|
||||
..
|
||||
},
|
||||
..,
|
||||
) = hir.get(new_top)
|
||||
{
|
||||
// If this isn't the first iteration, we need to check
|
||||
// if there is a let expr before us in the chain, so
|
||||
// that we avoid doubly checking the let chain.
|
||||
|
||||
// The way a chain of &&s is encoded is ((let ... && let ...) && let ...) && let ...
|
||||
// as && is left-to-right associative. Thus, we need to check rhs.
|
||||
if part_of_chain && matches!(rhs.kind, hir::ExprKind::Let(..)) {
|
||||
return true;
|
||||
}
|
||||
// If there is a let at the lhs, and we provide the rhs, we don't do any checking either.
|
||||
if !part_of_chain && matches!(lhs.kind, hir::ExprKind::Let(..)) && rhs.hir_id == top
|
||||
{
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// We've reached the top.
|
||||
break;
|
||||
}
|
||||
|
||||
// Since this function is called within a let context, it is reasonable to assume that any parent
|
||||
// `&&` infers a let chain
|
||||
part_of_chain = true;
|
||||
top = new_top;
|
||||
}
|
||||
if !part_of_chain {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Second, obtain the refutabilities of all exprs in the chain,
|
||||
// Obtain the refutabilities of all exprs in the chain,
|
||||
// and record chain members that aren't let exprs.
|
||||
let mut chain_refutabilities = Vec::new();
|
||||
let hir::Node::Expr(top_expr) = hir.get(top) else {
|
||||
// We ensure right above that it's an Expr
|
||||
unreachable!()
|
||||
};
|
||||
let mut cur_expr = top_expr;
|
||||
loop {
|
||||
let mut add = |expr: &hir::Expr<'tcx>| {
|
||||
let refutability = match expr.kind {
|
||||
hir::ExprKind::Let(hir::Let { pat, init, span, .. }) => {
|
||||
let mut ncx = self.new_cx(init.hir_id);
|
||||
let tpat = self.lower_pattern(&mut ncx, pat, &mut false);
|
||||
|
||||
let refutable = !is_let_irrefutable(&mut ncx, pat.hir_id, tpat);
|
||||
Some((*span, refutable))
|
||||
let add = |expr: ExprId, mut local_lint_level| {
|
||||
// `local_lint_level` is the lint level enclosing the pattern inside `expr`.
|
||||
let mut expr = &self.thir[expr];
|
||||
debug!(?expr, ?local_lint_level, "add");
|
||||
// Fast-forward through scopes.
|
||||
while let ExprKind::Scope { value, lint_level, .. } = expr.kind {
|
||||
if let LintLevel::Explicit(hir_id) = lint_level {
|
||||
local_lint_level = hir_id
|
||||
}
|
||||
expr = &self.thir[value];
|
||||
}
|
||||
debug!(?expr, ?local_lint_level, "after scopes");
|
||||
match expr.kind {
|
||||
ExprKind::Let { box ref pat, expr: _ } => {
|
||||
let mut ncx = self.new_cx(local_lint_level);
|
||||
let tpat = self.lower_pattern(&mut ncx, pat);
|
||||
let refutable = !is_let_irrefutable(&mut ncx, local_lint_level, tpat);
|
||||
Some((expr.span, refutable))
|
||||
}
|
||||
ExprKind::LogicalOp { op: LogicalOp::And, .. } => {
|
||||
bug!()
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
chain_refutabilities.push(refutability);
|
||||
};
|
||||
if let hir::Expr {
|
||||
kind: hir::ExprKind::Binary(Spanned { node: hir::BinOpKind::And, .. }, lhs, rhs),
|
||||
..
|
||||
} = cur_expr
|
||||
|
||||
// Let chains recurse on the left, so we start by adding the rightmost.
|
||||
chain_refutabilities.push(add(rhs, cur_lint_level));
|
||||
|
||||
loop {
|
||||
while let ExprKind::Scope { value, lint_level, .. } = self.thir[lhs].kind {
|
||||
if let LintLevel::Explicit(hir_id) = lint_level {
|
||||
cur_lint_level = hir_id
|
||||
}
|
||||
lhs = value;
|
||||
}
|
||||
if let ExprKind::LogicalOp { op: LogicalOp::And, lhs: new_lhs, rhs: expr } =
|
||||
self.thir[lhs].kind
|
||||
{
|
||||
add(rhs);
|
||||
cur_expr = lhs;
|
||||
chain_refutabilities.push(add(expr, cur_lint_level));
|
||||
lhs = new_lhs;
|
||||
} else {
|
||||
add(cur_expr);
|
||||
chain_refutabilities.push(add(lhs, cur_lint_level));
|
||||
break;
|
||||
}
|
||||
}
|
||||
debug!(?chain_refutabilities);
|
||||
chain_refutabilities.reverse();
|
||||
|
||||
// Third, emit the actual warnings.
|
||||
|
||||
if chain_refutabilities.iter().all(|r| matches!(*r, Some((_, false)))) {
|
||||
// The entire chain is made up of irrefutable `let` statements
|
||||
let let_source = let_source_parent(self.tcx, top, None);
|
||||
irrefutable_let_patterns(
|
||||
cx.tcx,
|
||||
top,
|
||||
self.tcx,
|
||||
self.lint_level,
|
||||
let_source,
|
||||
chain_refutabilities.len(),
|
||||
top_expr.span,
|
||||
);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(until) = chain_refutabilities.iter().position(|r| !matches!(*r, Some((_, false)))) && until > 0 {
|
||||
// The chain has a non-zero prefix of irrefutable `let` statements.
|
||||
|
||||
|
@ -346,7 +381,6 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
|||
// so can't always be moved out.
|
||||
// FIXME: Add checking whether the bindings are actually used in the prefix,
|
||||
// and lint if they are not.
|
||||
let let_source = let_source_parent(self.tcx, top, None);
|
||||
if !matches!(let_source, LetSource::WhileLet | LetSource::IfLetGuard) {
|
||||
// Emit the lint
|
||||
let prefix = &chain_refutabilities[..until];
|
||||
|
@ -354,9 +388,10 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
|||
let span_end = prefix.last().unwrap().unwrap().0;
|
||||
let span = span_start.to(span_end);
|
||||
let count = prefix.len();
|
||||
cx.tcx.emit_spanned_lint(IRREFUTABLE_LET_PATTERNS, top, span, LeadingIrrefutableLetPatterns { count });
|
||||
self.tcx.emit_spanned_lint(IRREFUTABLE_LET_PATTERNS, self.lint_level, span, LeadingIrrefutableLetPatterns { count });
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(from) = chain_refutabilities.iter().rposition(|r| !matches!(*r, Some((_, false)))) && from != (chain_refutabilities.len() - 1) {
|
||||
// The chain has a non-empty suffix of irrefutable `let` statements
|
||||
let suffix = &chain_refutabilities[from + 1..];
|
||||
|
@ -364,18 +399,18 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
|||
let span_end = suffix.last().unwrap().unwrap().0;
|
||||
let span = span_start.to(span_end);
|
||||
let count = suffix.len();
|
||||
cx.tcx.emit_spanned_lint(IRREFUTABLE_LET_PATTERNS, top, span, TrailingIrrefutableLetPatterns { count });
|
||||
self.tcx.emit_spanned_lint(IRREFUTABLE_LET_PATTERNS, self.lint_level, span, TrailingIrrefutableLetPatterns { count });
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>) {
|
||||
let mut cx = self.new_cx(pat.hir_id);
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn check_irrefutable(&self, pat: &Pat<'tcx>, origin: &str, sp: Option<Span>) {
|
||||
let mut cx = self.new_cx(self.lint_level);
|
||||
|
||||
let pattern = self.lower_pattern(&mut cx, pat, &mut false);
|
||||
let pattern = self.lower_pattern(&mut cx, pat);
|
||||
let pattern_ty = 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);
|
||||
let arm = MatchArm { pat: pattern, hir_id: self.lint_level, has_guard: false };
|
||||
let report = compute_match_usefulness(&cx, &[arm], self.lint_level, pattern_ty);
|
||||
|
||||
// Note: we ignore whether the pattern is unreachable (i.e. whether the type is empty). We
|
||||
// only care about exhaustiveness here.
|
||||
|
@ -386,57 +421,35 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
let (inform, interpreted_as_const, res_defined_here,let_suggestion, misc_suggestion) =
|
||||
if let hir::PatKind::Path(hir::QPath::Resolved(
|
||||
None,
|
||||
hir::Path {
|
||||
segments: &[hir::PathSegment { args: None, res, ident, .. }],
|
||||
..
|
||||
},
|
||||
)) = &pat.kind
|
||||
{
|
||||
(
|
||||
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 inform = sp.is_some().then_some(Inform);
|
||||
let mut let_suggestion = None;
|
||||
let mut misc_suggestion = None;
|
||||
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);
|
||||
}
|
||||
pat.each_binding(|name, _, _, _| {
|
||||
bindings.push(name);
|
||||
});
|
||||
let semi_span = span.shrink_to_hi().with_lo(span.hi() - BytePos(1));
|
||||
let semi_span = span.shrink_to_hi();
|
||||
let start_span = span.shrink_to_lo();
|
||||
let end_span = semi_span.shrink_to_lo();
|
||||
let count = witnesses.len();
|
||||
|
||||
// If the pattern to match is an integer literal:
|
||||
let int_suggestion = if
|
||||
let PatKind::Lit(expr) = &pat.kind
|
||||
&& bindings.is_empty()
|
||||
&& let ExprKind::Lit(Spanned { node: LitKind::Int(_, _), span }) = expr.kind {
|
||||
if bindings.is_empty()
|
||||
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span)
|
||||
&& snippet.chars().all(|c| c.is_digit(10))
|
||||
{
|
||||
// Then give a suggestion, the user might've meant to create a binding instead.
|
||||
Some(MiscPatternSuggestion::AttemptedIntegerLiteral { start_span: span.shrink_to_lo() })
|
||||
} else { None };
|
||||
misc_suggestion = Some(MiscPatternSuggestion::AttemptedIntegerLiteral {
|
||||
start_span: pat.span.shrink_to_lo()
|
||||
});
|
||||
}
|
||||
|
||||
let let_suggestion = if bindings.is_empty() {SuggestLet::If{start_span, semi_span, count}} else{ SuggestLet::Else{end_span, count }};
|
||||
(sp.map(|_|Inform), None, None, Some(let_suggestion), int_suggestion)
|
||||
let_suggestion = Some(if bindings.is_empty() {
|
||||
SuggestLet::If {start_span, semi_span, count }
|
||||
} else {
|
||||
(sp.map(|_|Inform), None, None, None, None)
|
||||
SuggestLet::Else { end_span, count }
|
||||
});
|
||||
};
|
||||
|
||||
let adt_defined_here = try {
|
||||
|
@ -456,12 +469,12 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
|||
origin,
|
||||
uncovered: Uncovered::new(pat.span, &cx, witnesses),
|
||||
inform,
|
||||
interpreted_as_const,
|
||||
interpreted_as_const: None,
|
||||
_p: (),
|
||||
pattern_ty,
|
||||
let_suggestion,
|
||||
misc_suggestion,
|
||||
res_defined_here,
|
||||
res_defined_here: None,
|
||||
adt_defined_here,
|
||||
});
|
||||
}
|
||||
|
@ -473,14 +486,18 @@ fn check_for_bindings_named_same_as_variants(
|
|||
rf: RefutableFlag,
|
||||
) {
|
||||
pat.walk_always(|p| {
|
||||
if let hir::PatKind::Binding(_, _, ident, None) = p.kind
|
||||
&& let Some(ty::BindByValue(hir::Mutability::Not)) =
|
||||
cx.typeck_results.extract_binding_mode(cx.tcx.sess, p.hir_id, p.span)
|
||||
&& let pat_ty = cx.typeck_results.pat_ty(p).peel_refs()
|
||||
&& let ty::Adt(edef, _) = pat_ty.kind()
|
||||
if let PatKind::Binding {
|
||||
name,
|
||||
mode: BindingMode::ByValue,
|
||||
mutability: Mutability::Not,
|
||||
subpattern: None,
|
||||
ty,
|
||||
..
|
||||
} = p.kind
|
||||
&& let ty::Adt(edef, _) = ty.peel_refs().kind()
|
||||
&& edef.is_enum()
|
||||
&& edef.variants().iter().any(|variant| {
|
||||
variant.ident(cx.tcx) == ident && variant.ctor_kind() == Some(CtorKind::Const)
|
||||
variant.name == name && variant.ctor_kind() == Some(CtorKind::Const)
|
||||
})
|
||||
{
|
||||
let variant_count = edef.variants().len();
|
||||
|
@ -489,7 +506,7 @@ fn check_for_bindings_named_same_as_variants(
|
|||
});
|
||||
cx.tcx.emit_spanned_lint(
|
||||
BINDINGS_WITH_VARIANT_NAME,
|
||||
p.hir_id,
|
||||
cx.lint_level,
|
||||
p.span,
|
||||
BindingsWithVariantName {
|
||||
// If this is an irrefutable pattern, and there's > 1 variant,
|
||||
|
@ -499,7 +516,7 @@ fn check_for_bindings_named_same_as_variants(
|
|||
Some(p.span)
|
||||
} else { None },
|
||||
ty_path,
|
||||
ident,
|
||||
name,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -525,11 +542,6 @@ fn unreachable_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, catchall: Option<
|
|||
);
|
||||
}
|
||||
|
||||
fn irrefutable_let_pattern(tcx: TyCtxt<'_>, id: HirId, span: Span) {
|
||||
let source = let_source(tcx, id);
|
||||
irrefutable_let_patterns(tcx, id, source, 1, span);
|
||||
}
|
||||
|
||||
fn irrefutable_let_patterns(
|
||||
tcx: TyCtxt<'_>,
|
||||
id: HirId,
|
||||
|
@ -544,7 +556,7 @@ fn irrefutable_let_patterns(
|
|||
}
|
||||
|
||||
match source {
|
||||
LetSource::GenericLet => emit_diag!(IrrefutableLetPatternsGenericLet),
|
||||
LetSource::None => bug!(),
|
||||
LetSource::IfLet => emit_diag!(IrrefutableLetPatternsIfLet),
|
||||
LetSource::IfLetGuard => emit_diag!(IrrefutableLetPatternsIfLetGuard),
|
||||
LetSource::LetElse => emit_diag!(IrrefutableLetPatternsLetElse),
|
||||
|
@ -600,10 +612,11 @@ fn report_arm_reachability<'p, 'tcx>(
|
|||
/// Report that a match is not exhaustive.
|
||||
fn non_exhaustive_match<'p, 'tcx>(
|
||||
cx: &MatchCheckCtxt<'p, 'tcx>,
|
||||
thir: &Thir<'tcx>,
|
||||
scrut_ty: Ty<'tcx>,
|
||||
sp: Span,
|
||||
witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
|
||||
arms: &[hir::Arm<'tcx>],
|
||||
arms: &[ArmId],
|
||||
expr_span: Span,
|
||||
) {
|
||||
let is_empty_match = arms.is_empty();
|
||||
|
@ -701,6 +714,7 @@ fn non_exhaustive_match<'p, 'tcx>(
|
|||
));
|
||||
}
|
||||
[only] => {
|
||||
let only = &thir[*only];
|
||||
let (pre_indentation, is_multiline) = if let Some(snippet) = sm.indentation_before(only.span)
|
||||
&& let Ok(with_trailing) = sm.span_extend_while(only.span, |c| c.is_whitespace() || c == ',')
|
||||
&& sm.is_multiline(with_trailing)
|
||||
|
@ -709,8 +723,9 @@ fn non_exhaustive_match<'p, 'tcx>(
|
|||
} else {
|
||||
(" ".to_string(), false)
|
||||
};
|
||||
let comma = if matches!(only.body.kind, hir::ExprKind::Block(..))
|
||||
&& only.span.eq_ctxt(only.body.span)
|
||||
let only_body = &thir[only.body];
|
||||
let comma = if matches!(only_body.kind, ExprKind::Block { .. })
|
||||
&& only.span.eq_ctxt(only_body.span)
|
||||
&& is_multiline
|
||||
{
|
||||
""
|
||||
|
@ -722,9 +737,13 @@ fn non_exhaustive_match<'p, 'tcx>(
|
|||
format!("{}{}{} => todo!()", comma, pre_indentation, pattern),
|
||||
));
|
||||
}
|
||||
[.., prev, last] if prev.span.eq_ctxt(last.span) => {
|
||||
let comma = if matches!(last.body.kind, hir::ExprKind::Block(..))
|
||||
&& last.span.eq_ctxt(last.body.span)
|
||||
[.., prev, last] => {
|
||||
let prev = &thir[*prev];
|
||||
let last = &thir[*last];
|
||||
if prev.span.eq_ctxt(last.span) {
|
||||
let last_body = &thir[last.body];
|
||||
let comma = if matches!(last_body.kind, ExprKind::Block { .. })
|
||||
&& last.span.eq_ctxt(last_body.span)
|
||||
{
|
||||
""
|
||||
} else {
|
||||
|
@ -742,6 +761,7 @@ fn non_exhaustive_match<'p, 'tcx>(
|
|||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
@ -859,10 +879,6 @@ fn maybe_point_at_variant<'a, 'p: 'a, 'tcx: 'a>(
|
|||
}
|
||||
|
||||
/// Check if a by-value binding is by-value. That is, check if the binding's type is not `Copy`.
|
||||
fn is_binding_by_move(cx: &MatchVisitor<'_, '_, '_>, hir_id: HirId) -> bool {
|
||||
!cx.typeck_results.node_type(hir_id).is_copy_modulo_regions(cx.tcx, cx.param_env)
|
||||
}
|
||||
|
||||
/// Check that there are no borrow or move conflicts in `binding @ subpat` patterns.
|
||||
///
|
||||
/// For example, this would reject:
|
||||
|
@ -873,43 +889,31 @@ fn is_binding_by_move(cx: &MatchVisitor<'_, '_, '_>, hir_id: HirId) -> bool {
|
|||
/// - `x @ Some(ref mut? y)`.
|
||||
///
|
||||
/// This analysis is *not* subsumed by NLL.
|
||||
fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pat<'_>) {
|
||||
fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, '_, 'tcx>, pat: &Pat<'tcx>) {
|
||||
// Extract `sub` in `binding @ sub`.
|
||||
let (name, sub) = match &pat.kind {
|
||||
hir::PatKind::Binding(.., name, Some(sub)) => (*name, sub),
|
||||
_ => return,
|
||||
};
|
||||
let mk_span = |pat_span, ident_span: Span| {
|
||||
if let Some(ident_span) = ident_span.find_ancestor_inside(pat_span) {
|
||||
pat_span.with_hi(ident_span.hi())
|
||||
} else {
|
||||
pat_span
|
||||
}
|
||||
};
|
||||
let binding_span = mk_span(pat.span, name.span);
|
||||
let PatKind::Binding { name, mode, ty, subpattern: Some(box ref sub), .. } = pat.kind else { return };
|
||||
let binding_span = pat.span; //.with_hi(name.span.hi());
|
||||
|
||||
let is_binding_by_move = |ty: Ty<'tcx>| !ty.is_copy_modulo_regions(cx.tcx, cx.param_env);
|
||||
|
||||
let typeck_results = cx.typeck_results;
|
||||
let sess = cx.tcx.sess;
|
||||
|
||||
// Get the binding move, extract the mutability if by-ref.
|
||||
let mut_outer = match typeck_results.extract_binding_mode(sess, pat.hir_id, binding_span) {
|
||||
Some(ty::BindByValue(_)) if is_binding_by_move(cx, pat.hir_id) => {
|
||||
let mut_outer = match mode {
|
||||
BindingMode::ByValue if is_binding_by_move(ty) => {
|
||||
// We have `x @ pat` where `x` is by-move. Reject all borrows in `pat`.
|
||||
let mut conflicts_ref = Vec::new();
|
||||
sub.each_binding(|_, hir_id, span, ident| {
|
||||
let span = mk_span(span, ident.span);
|
||||
match typeck_results.extract_binding_mode(sess, hir_id, span) {
|
||||
Some(ty::BindByValue(_)) | None => {}
|
||||
Some(ty::BindByReference(_)) => conflicts_ref.push(span),
|
||||
}
|
||||
sub.each_binding(|_, mode, _, span| match mode {
|
||||
BindingMode::ByValue => {}
|
||||
BindingMode::ByRef(_) => conflicts_ref.push(span),
|
||||
});
|
||||
if !conflicts_ref.is_empty() {
|
||||
sess.emit_err(BorrowOfMovedValue {
|
||||
span: binding_span,
|
||||
span: pat.span,
|
||||
binding_span,
|
||||
conflicts_ref,
|
||||
name,
|
||||
ty: typeck_results.node_type(pat.hir_id),
|
||||
ty,
|
||||
suggest_borrowing: pat
|
||||
.span
|
||||
.contains(binding_span)
|
||||
|
@ -918,8 +922,8 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
|
|||
}
|
||||
return;
|
||||
}
|
||||
Some(ty::BindByValue(_)) | None => return,
|
||||
Some(ty::BindByReference(m)) => m,
|
||||
BindingMode::ByValue => return,
|
||||
BindingMode::ByRef(m) => m.mutability(),
|
||||
};
|
||||
|
||||
// We now have `ref $mut_outer binding @ sub` (semantically).
|
||||
|
@ -927,10 +931,9 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
|
|||
let mut conflicts_move = Vec::new();
|
||||
let mut conflicts_mut_mut = Vec::new();
|
||||
let mut conflicts_mut_ref = Vec::new();
|
||||
sub.each_binding(|_, hir_id, span, name| {
|
||||
let span = mk_span(span, name.span);
|
||||
match typeck_results.extract_binding_mode(sess, hir_id, span) {
|
||||
Some(ty::BindByReference(mut_inner)) => match (mut_outer, mut_inner) {
|
||||
sub.each_binding(|name, mode, ty, span| {
|
||||
match mode {
|
||||
BindingMode::ByRef(mut_inner) => match (mut_outer, mut_inner.mutability()) {
|
||||
// Both sides are `ref`.
|
||||
(Mutability::Not, Mutability::Not) => {}
|
||||
// 2x `ref mut`.
|
||||
|
@ -944,10 +947,10 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
|
|||
conflicts_mut_ref.push(Conflict::Ref { span, name })
|
||||
}
|
||||
},
|
||||
Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id) => {
|
||||
BindingMode::ByValue if is_binding_by_move(ty) => {
|
||||
conflicts_move.push(Conflict::Moved { span, name }) // `ref mut?` + by-move conflict.
|
||||
}
|
||||
Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine.
|
||||
BindingMode::ByValue => {} // `ref mut?` + by-copy is fine.
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -966,81 +969,19 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
|
|||
// Report errors if any.
|
||||
if report_mut_mut {
|
||||
// Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`.
|
||||
sess.emit_err(MultipleMutBorrows { span: binding_span, occurences });
|
||||
sess.emit_err(MultipleMutBorrows { span: pat.span, occurences });
|
||||
} else if report_mut_ref {
|
||||
// Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse.
|
||||
match mut_outer {
|
||||
Mutability::Mut => {
|
||||
sess.emit_err(AlreadyMutBorrowed { span: binding_span, occurences });
|
||||
sess.emit_err(AlreadyMutBorrowed { span: pat.span, occurences });
|
||||
}
|
||||
Mutability::Not => {
|
||||
sess.emit_err(AlreadyBorrowed { span: binding_span, occurences });
|
||||
sess.emit_err(AlreadyBorrowed { span: pat.span, occurences });
|
||||
}
|
||||
};
|
||||
} else if report_move_conflict {
|
||||
// Report by-ref and by-move conflicts, e.g. `ref x @ y`.
|
||||
sess.emit_err(MovedWhileBorrowed { span: binding_span, occurences });
|
||||
sess.emit_err(MovedWhileBorrowed { span: pat.span, occurences });
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum LetSource {
|
||||
GenericLet,
|
||||
IfLet,
|
||||
IfLetGuard,
|
||||
LetElse,
|
||||
WhileLet,
|
||||
}
|
||||
|
||||
fn let_source(tcx: TyCtxt<'_>, pat_id: HirId) -> LetSource {
|
||||
let hir = tcx.hir();
|
||||
|
||||
let parent = hir.parent_id(pat_id);
|
||||
let_source_parent(tcx, parent, Some(pat_id))
|
||||
}
|
||||
|
||||
fn let_source_parent(tcx: TyCtxt<'_>, parent: HirId, pat_id: Option<HirId>) -> LetSource {
|
||||
let hir = tcx.hir();
|
||||
|
||||
let parent_node = hir.get(parent);
|
||||
|
||||
match parent_node {
|
||||
hir::Node::Arm(hir::Arm {
|
||||
guard: Some(hir::Guard::IfLet(&hir::Let { pat: hir::Pat { hir_id, .. }, .. })),
|
||||
..
|
||||
}) if Some(*hir_id) == pat_id => {
|
||||
return LetSource::IfLetGuard;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let parent_parent = hir.parent_id(parent);
|
||||
let parent_parent_node = hir.get(parent_parent);
|
||||
match parent_parent_node {
|
||||
hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), .. }) => {
|
||||
return LetSource::LetElse;
|
||||
}
|
||||
hir::Node::Arm(hir::Arm { guard: Some(hir::Guard::If(_)), .. }) => {
|
||||
return LetSource::IfLetGuard;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let parent_parent_parent = hir.parent_id(parent_parent);
|
||||
let parent_parent_parent_parent = hir.parent_id(parent_parent_parent);
|
||||
let parent_parent_parent_parent_node = hir.get(parent_parent_parent_parent);
|
||||
|
||||
if let hir::Node::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::Loop(_, _, hir::LoopSource::While, _),
|
||||
..
|
||||
}) = parent_parent_parent_parent_node
|
||||
{
|
||||
return LetSource::WhileLet;
|
||||
}
|
||||
|
||||
if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::If(..), .. }) = parent_parent_node {
|
||||
return LetSource::IfLet;
|
||||
}
|
||||
|
||||
LetSource::GenericLet
|
||||
}
|
||||
|
|
|
@ -54,11 +54,9 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
|
|||
pat: &'tcx hir::Pat<'tcx>,
|
||||
) -> Box<Pat<'tcx>> {
|
||||
let mut pcx = PatCtxt::new(tcx, param_env, typeck_results);
|
||||
pcx.include_lint_checks();
|
||||
let result = pcx.lower_pattern(pat);
|
||||
if !pcx.errors.is_empty() {
|
||||
let msg = format!("encountered errors lowering pattern: {:?}", pcx.errors);
|
||||
tcx.sess.delay_span_bug(pat.span, &msg);
|
||||
}
|
||||
pcx.report_inlining_errors();
|
||||
debug!("pat_from_hir({:?}) = {:?}", pat, result);
|
||||
result
|
||||
}
|
||||
|
@ -77,6 +75,25 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
self
|
||||
}
|
||||
|
||||
fn report_inlining_errors(&self) {
|
||||
for error in &self.errors {
|
||||
match *error {
|
||||
PatternError::StaticInPattern(span) => {
|
||||
self.tcx.sess.emit_err(StaticInPattern { span });
|
||||
}
|
||||
PatternError::AssocConstInPattern(span) => {
|
||||
self.tcx.sess.emit_err(AssocConstInPattern { span });
|
||||
}
|
||||
PatternError::ConstParamInPattern(span) => {
|
||||
self.tcx.sess.emit_err(ConstParamInPattern { span });
|
||||
}
|
||||
PatternError::NonConstPath(span) => {
|
||||
self.tcx.sess.emit_err(NonConstPath { span });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
|
||||
// When implicit dereferences have been inserted in this pattern, the unadjusted lowered
|
||||
// pattern has the type that results *after* dereferencing. For example, in this code:
|
||||
|
|
|
@ -14,14 +14,15 @@ LL | async fn foo(x: u32) -> u32 {
|
|||
| ^^^query stack during panic:
|
||||
#0 [typeck] type-checking `foo`
|
||||
#1 [thir_body] building THIR for `foo`
|
||||
#2 [mir_built] building MIR for `foo`
|
||||
#3 [unsafety_check_result] unsafety-checking `foo`
|
||||
#4 [mir_const] preparing `foo` for borrow checking
|
||||
#5 [mir_promoted] processing MIR for `foo`
|
||||
#6 [mir_borrowck] borrow-checking `foo`
|
||||
#7 [type_of] computing type of `foo::{opaque#0}`
|
||||
#8 [check_mod_item_types] checking item types in top-level module
|
||||
#9 [analysis] running analysis passes on this crate
|
||||
#2 [check_match] match-checking `foo`
|
||||
#3 [mir_built] building MIR for `foo`
|
||||
#4 [unsafety_check_result] unsafety-checking `foo`
|
||||
#5 [mir_const] preparing `foo` for borrow checking
|
||||
#6 [mir_promoted] processing MIR for `foo`
|
||||
#7 [mir_borrowck] borrow-checking `foo`
|
||||
#8 [type_of] computing type of `foo::{opaque#0}`
|
||||
#9 [check_mod_item_types] checking item types in top-level module
|
||||
#10 [analysis] running analysis passes on this crate
|
||||
end of query stack
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ fn main() {
|
|||
match -128i8 {
|
||||
NEG_NEG_128 => println!("A"),
|
||||
//~^ ERROR could not evaluate constant pattern
|
||||
//~| ERROR could not evaluate constant pattern
|
||||
_ => println!("B"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,6 @@ error: could not evaluate constant pattern
|
|||
LL | NEG_NEG_128 => println!("A"),
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const-eval-overflow-2.rs:15:9
|
||||
|
|
||||
LL | NEG_NEG_128 => println!("A"),
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ref_to_int_match.rs:25:27
|
||||
--> $DIR/ref_to_int_match.rs:24:27
|
||||
|
|
||||
LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
|
||||
| ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
@ -13,12 +13,6 @@ error: could not evaluate constant pattern
|
|||
LL | 10..=BAR => {},
|
||||
| ^^^
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/ref_to_int_match.rs:7:14
|
||||
|
|
||||
LL | 10..=BAR => {},
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/ref_to_int_match.rs:25:27
|
||||
--> $DIR/ref_to_int_match.rs:24:27
|
||||
|
|
||||
LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
|
||||
| ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
|
||||
|
@ -13,12 +13,6 @@ error: could not evaluate constant pattern
|
|||
LL | 10..=BAR => {},
|
||||
| ^^^
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/ref_to_int_match.rs:7:14
|
||||
|
|
||||
LL | 10..=BAR => {},
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
|
|
|
@ -5,7 +5,6 @@ fn main() {
|
|||
match n {
|
||||
0..=10 => {},
|
||||
10..=BAR => {}, //~ ERROR could not evaluate constant pattern
|
||||
//~| ERROR could not evaluate constant pattern
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@ LL | A = { let 0 = 0; 0 },
|
|||
= note: the matched value is of type `i32`
|
||||
help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | A = { if let 0 = 0 { todo!() } 0 },
|
||||
| ++ ~~~~~~~~~~~
|
||||
LL | A = { if let 0 = 0 { todo!() }; 0 },
|
||||
| ++ +++++++++++
|
||||
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||
|
|
||||
LL | A = { let _0 = 0; 0 },
|
||||
|
|
|
@ -9,8 +9,8 @@ LL | let x: [i32; { let 0 = 0; 0 }] = [];
|
|||
= note: the matched value is of type `i32`
|
||||
help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | let x: [i32; { if let 0 = 0 { todo!() } 0 }] = [];
|
||||
| ++ ~~~~~~~~~~~
|
||||
LL | let x: [i32; { if let 0 = 0 { todo!() }; 0 }] = [];
|
||||
| ++ +++++++++++
|
||||
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||
|
|
||||
LL | let x: [i32; { let _0 = 0; 0 }] = [];
|
||||
|
|
|
@ -9,8 +9,8 @@ LL | const X: i32 = { let 0 = 0; 0 };
|
|||
= note: the matched value is of type `i32`
|
||||
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 };
|
||||
| ++ ~~~~~~~~~~~
|
||||
LL | const X: i32 = { if let 0 = 0 { todo!() }; 0 };
|
||||
| ++ +++++++++++
|
||||
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||
|
|
||||
LL | const X: i32 = { let _0 = 0; 0 };
|
||||
|
@ -27,8 +27,8 @@ LL | static Y: i32 = { let 0 = 0; 0 };
|
|||
= note: the matched value is of type `i32`
|
||||
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 };
|
||||
| ++ ~~~~~~~~~~~
|
||||
LL | static Y: i32 = { if let 0 = 0 { todo!() }; 0 };
|
||||
| ++ +++++++++++
|
||||
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||
|
|
||||
LL | static Y: i32 = { let _0 = 0; 0 };
|
||||
|
@ -45,8 +45,8 @@ LL | const X: i32 = { let 0 = 0; 0 };
|
|||
= note: the matched value is of type `i32`
|
||||
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 };
|
||||
| ++ ~~~~~~~~~~~
|
||||
LL | const X: i32 = { if let 0 = 0 { todo!() }; 0 };
|
||||
| ++ +++++++++++
|
||||
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||
|
|
||||
LL | const X: i32 = { let _0 = 0; 0 };
|
||||
|
@ -63,8 +63,8 @@ LL | const X: i32 = { let 0 = 0; 0 };
|
|||
= note: the matched value is of type `i32`
|
||||
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 };
|
||||
| ++ ~~~~~~~~~~~
|
||||
LL | const X: i32 = { if let 0 = 0 { todo!() }; 0 };
|
||||
| ++ +++++++++++
|
||||
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||
|
|
||||
LL | const X: i32 = { let _0 = 0; 0 };
|
||||
|
|
|
@ -12,17 +12,14 @@ fn main() {
|
|||
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
|
||||
//~| HELP you might want to use `if let` to ignore the variants that aren't matched
|
||||
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
|
||||
//~| HELP you might want to use `if let` to ignore the variants that aren't matched
|
||||
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
|
||||
//~| HELP you might want to use `if let` to ignore the variants that aren't matched
|
||||
fn f() {} // Check that the `NOTE`s still work with an item here (cf. issue #35115).
|
||||
}
|
||||
|
|
|
@ -1,47 +1,44 @@
|
|||
error[E0005]: refutable pattern in local binding
|
||||
--> $DIR/const-pattern-irrefutable.rs:12:9
|
||||
|
|
||||
LL | const a: u8 = 2;
|
||||
| ----------- constant defined here
|
||||
...
|
||||
LL | let a = 4;
|
||||
| ^
|
||||
| |
|
||||
| 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`
|
||||
| ^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
|
||||
|
|
||||
= 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: the matched value is of type `u8`
|
||||
help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | if let a = 4 { todo!() };
|
||||
| ++ +++++++++++
|
||||
|
||||
error[E0005]: refutable pattern in local binding
|
||||
--> $DIR/const-pattern-irrefutable.rs:17:9
|
||||
--> $DIR/const-pattern-irrefutable.rs:16:9
|
||||
|
|
||||
LL | pub const b: u8 = 2;
|
||||
| --------------- constant defined here
|
||||
...
|
||||
LL | let c = 4;
|
||||
| ^
|
||||
| |
|
||||
| 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`
|
||||
| ^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
|
||||
|
|
||||
= 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: the matched value is of type `u8`
|
||||
help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | if let c = 4 { todo!() };
|
||||
| ++ +++++++++++
|
||||
|
||||
error[E0005]: refutable pattern in local binding
|
||||
--> $DIR/const-pattern-irrefutable.rs:22:9
|
||||
--> $DIR/const-pattern-irrefutable.rs:20:9
|
||||
|
|
||||
LL | pub const d: u8 = 2;
|
||||
| --------------- constant defined here
|
||||
...
|
||||
LL | let d = 4;
|
||||
| ^
|
||||
| |
|
||||
| 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`
|
||||
| ^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
|
||||
|
|
||||
= 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: the matched value is of type `u8`
|
||||
help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | if let d = 4 { todo!() };
|
||||
| ++ +++++++++++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ LL | match &[][..] {
|
|||
= note: the matched value is of type `&[E]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ E_SL => {}
|
||||
LL ~ E_SL => {},
|
||||
LL + &_ => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ fn main() {
|
|||
match 1 {
|
||||
NUM => unimplemented!(),
|
||||
//~^ ERROR could not evaluate constant pattern
|
||||
//~| ERROR could not evaluate constant pattern
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,12 +12,6 @@ error: could not evaluate constant pattern
|
|||
LL | NUM => unimplemented!(),
|
||||
| ^^^
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/issue-43105.rs:8:9
|
||||
|
|
||||
LL | NUM => unimplemented!(),
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
|
|
|
@ -19,7 +19,6 @@ impl<T: 'static> GetTypeId<T> {
|
|||
const fn check_type_id<T: 'static>() -> bool {
|
||||
matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
|
||||
//~^ ERROR constant pattern depends on a generic parameter
|
||||
//~| ERROR constant pattern depends on a generic parameter
|
||||
}
|
||||
|
||||
pub struct GetTypeNameLen<T>(T);
|
||||
|
@ -31,7 +30,6 @@ impl<T: 'static> GetTypeNameLen<T> {
|
|||
const fn check_type_name_len<T: 'static>() -> bool {
|
||||
matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
|
||||
//~^ ERROR constant pattern depends on a generic parameter
|
||||
//~| ERROR constant pattern depends on a generic parameter
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -5,22 +5,10 @@ LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
|
|||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: constant pattern depends on a generic parameter
|
||||
--> $DIR/issue-73976-polymorphic.rs:32:42
|
||||
--> $DIR/issue-73976-polymorphic.rs:31:42
|
||||
|
|
||||
LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: constant pattern depends on a generic parameter
|
||||
--> $DIR/issue-73976-polymorphic.rs:20:37
|
||||
|
|
||||
LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: constant pattern depends on a generic parameter
|
||||
--> $DIR/issue-73976-polymorphic.rs:32:42
|
||||
|
|
||||
LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -6,5 +6,4 @@ const FOO: *const u32 = {
|
|||
fn main() {
|
||||
let FOO = FOO;
|
||||
//~^ ERROR could not evaluate constant pattern
|
||||
//~| ERROR could not evaluate constant pattern
|
||||
}
|
||||
|
|
|
@ -17,12 +17,6 @@ error: could not evaluate constant pattern
|
|||
LL | let FOO = FOO;
|
||||
| ^^^
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/issue-78655.rs:7:9
|
||||
|
|
||||
LL | let FOO = FOO;
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0381`.
|
||||
|
|
|
@ -11,7 +11,6 @@ impl<T> GetVariantCount<T> {
|
|||
const fn check_variant_count<T>() -> bool {
|
||||
matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
|
||||
//~^ ERROR constant pattern depends on a generic parameter
|
||||
//~| ERROR constant pattern depends on a generic parameter
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -4,11 +4,5 @@ error: constant pattern depends on a generic parameter
|
|||
LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: constant pattern depends on a generic parameter
|
||||
--> $DIR/issue-79137-toogeneric.rs:12:43
|
||||
|
|
||||
LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ LL | const U8_MUT: &u8 = {
|
|||
}
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:43:9
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:42:9
|
||||
|
|
||||
LL | U8_MUT => true,
|
||||
| ^^^^^^
|
||||
|
@ -39,7 +39,7 @@ LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:54:9
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:52:9
|
||||
|
|
||||
LL | U8_MUT2 => true,
|
||||
| ^^^^^^^
|
||||
|
@ -51,31 +51,7 @@ LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None =>
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:62:9
|
||||
|
|
||||
LL | U8_MUT3 => true,
|
||||
| ^^^^^^^
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:34:9
|
||||
|
|
||||
LL | SLICE_MUT => true,
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:43:9
|
||||
|
|
||||
LL | U8_MUT => true,
|
||||
| ^^^^^^
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:54:9
|
||||
|
|
||||
LL | U8_MUT2 => true,
|
||||
| ^^^^^^^
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:62:9
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:59:9
|
||||
|
|
||||
LL | U8_MUT3 => true,
|
||||
| ^^^^^^^
|
||||
|
@ -133,6 +109,6 @@ help: skipping check that does not even have a feature gate
|
|||
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 12 previous errors; 1 warning emitted
|
||||
error: aborting due to 8 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
|
|
|
@ -27,7 +27,7 @@ LL | const U8_MUT: &u8 = {
|
|||
}
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:43:9
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:42:9
|
||||
|
|
||||
LL | U8_MUT => true,
|
||||
| ^^^^^^
|
||||
|
@ -39,7 +39,7 @@ LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:54:9
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:52:9
|
||||
|
|
||||
LL | U8_MUT2 => true,
|
||||
| ^^^^^^^
|
||||
|
@ -51,31 +51,7 @@ LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None =>
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:62:9
|
||||
|
|
||||
LL | U8_MUT3 => true,
|
||||
| ^^^^^^^
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:34:9
|
||||
|
|
||||
LL | SLICE_MUT => true,
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:43:9
|
||||
|
|
||||
LL | U8_MUT => true,
|
||||
| ^^^^^^
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:54:9
|
||||
|
|
||||
LL | U8_MUT2 => true,
|
||||
| ^^^^^^^
|
||||
|
||||
error: could not evaluate constant pattern
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:62:9
|
||||
--> $DIR/const_refers_to_static_cross_crate.rs:59:9
|
||||
|
|
||||
LL | U8_MUT3 => true,
|
||||
| ^^^^^^^
|
||||
|
@ -133,6 +109,6 @@ help: skipping check that does not even have a feature gate
|
|||
LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 12 previous errors; 1 warning emitted
|
||||
error: aborting due to 8 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
|
|
|
@ -33,7 +33,6 @@ pub fn test(x: &[u8; 1]) -> bool {
|
|||
match x {
|
||||
SLICE_MUT => true,
|
||||
//~^ ERROR could not evaluate constant pattern
|
||||
//~| ERROR could not evaluate constant pattern
|
||||
&[1..] => false,
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +41,6 @@ pub fn test2(x: &u8) -> bool {
|
|||
match x {
|
||||
U8_MUT => true,
|
||||
//~^ ERROR could not evaluate constant pattern
|
||||
//~| ERROR could not evaluate constant pattern
|
||||
&(1..) => false,
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +51,6 @@ pub fn test3(x: &u8) -> bool {
|
|||
match x {
|
||||
U8_MUT2 => true,
|
||||
//~^ ERROR could not evaluate constant pattern
|
||||
//~| ERROR could not evaluate constant pattern
|
||||
&(1..) => false,
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +58,6 @@ pub fn test4(x: &u8) -> bool {
|
|||
match x {
|
||||
U8_MUT3 => true,
|
||||
//~^ ERROR could not evaluate constant pattern
|
||||
//~| ERROR could not evaluate constant pattern
|
||||
&(1..) => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ LL | HastaLaVistaBaby,
|
|||
= note: the matched value is of type `Terminator`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ Terminator::TalkToMyHand => {}
|
||||
LL ~ Terminator::TalkToMyHand => {},
|
||||
LL + Terminator::HastaLaVistaBaby => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -4,6 +4,5 @@ fn main() {
|
|||
match 5u32 {
|
||||
1000 ..= 5 => {}
|
||||
//~^ ERROR lower range bound must be less than or equal to upper
|
||||
//~| ERROR lower range bound must be less than or equal to upper
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,12 +6,6 @@ LL | 1000 ..= 5 => {}
|
|||
|
|
||||
= note: When matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range.
|
||||
|
||||
error[E0030]: lower range bound must be less than or equal to upper
|
||||
--> $DIR/E0030-teach.rs:5:9
|
||||
|
|
||||
LL | 1000 ..= 5 => {}
|
||||
| ^^^^ lower bound larger than upper bound
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0030`.
|
||||
|
|
|
@ -2,6 +2,5 @@ fn main() {
|
|||
match 5u32 {
|
||||
1000 ..= 5 => {}
|
||||
//~^ ERROR lower range bound must be less than or equal to upper
|
||||
//~| ERROR lower range bound must be less than or equal to upper
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,6 @@ error[E0030]: lower range bound must be less than or equal to upper
|
|||
LL | 1000 ..= 5 => {}
|
||||
| ^^^^ lower bound larger than upper bound
|
||||
|
||||
error[E0030]: lower range bound must be less than or equal to upper
|
||||
--> $DIR/E0030.rs:3:9
|
||||
|
|
||||
LL | 1000 ..= 5 => {}
|
||||
| ^^^^ lower bound larger than upper bound
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0030`.
|
||||
|
|
|
@ -115,7 +115,7 @@ LL | A, B, C,
|
|||
= note: the matched value is of type `Foo`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ Foo::B => {}
|
||||
LL ~ Foo::B => {},
|
||||
LL + Foo::C => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ LL | match 0usize {
|
|||
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ 0..=usize::MAX => {}
|
||||
LL ~ 0..=usize::MAX => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
@ -24,7 +24,7 @@ LL | match 0isize {
|
|||
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ isize::MIN..=isize::MAX => {}
|
||||
LL ~ isize::MIN..=isize::MAX => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -10,44 +10,31 @@ macro_rules! m {
|
|||
fn main() {
|
||||
m!(0, ..u8::MIN);
|
||||
//~^ ERROR lower range bound must be less than upper
|
||||
//~| ERROR lower range bound must be less than upper
|
||||
m!(0, ..u16::MIN);
|
||||
//~^ ERROR lower range bound must be less than upper
|
||||
//~| ERROR lower range bound must be less than upper
|
||||
m!(0, ..u32::MIN);
|
||||
//~^ ERROR lower range bound must be less than upper
|
||||
//~| ERROR lower range bound must be less than upper
|
||||
m!(0, ..u64::MIN);
|
||||
//~^ ERROR lower range bound must be less than upper
|
||||
//~| ERROR lower range bound must be less than upper
|
||||
m!(0, ..u128::MIN);
|
||||
//~^ ERROR lower range bound must be less than upper
|
||||
//~| ERROR lower range bound must be less than upper
|
||||
|
||||
m!(0, ..i8::MIN);
|
||||
//~^ ERROR lower range bound must be less than upper
|
||||
//~| ERROR lower range bound must be less than upper
|
||||
m!(0, ..i16::MIN);
|
||||
//~^ ERROR lower range bound must be less than upper
|
||||
//~| ERROR lower range bound must be less than upper
|
||||
m!(0, ..i32::MIN);
|
||||
//~^ ERROR lower range bound must be less than upper
|
||||
//~| ERROR lower range bound must be less than upper
|
||||
m!(0, ..i64::MIN);
|
||||
//~^ ERROR lower range bound must be less than upper
|
||||
//~| ERROR lower range bound must be less than upper
|
||||
m!(0, ..i128::MIN);
|
||||
//~^ ERROR lower range bound must be less than upper
|
||||
//~| ERROR lower range bound must be less than upper
|
||||
|
||||
m!(0f32, ..f32::NEG_INFINITY);
|
||||
//~^ ERROR lower range bound must be less than upper
|
||||
//~| ERROR lower range bound must be less than upper
|
||||
m!(0f64, ..f64::NEG_INFINITY);
|
||||
//~^ ERROR lower range bound must be less than upper
|
||||
//~| ERROR lower range bound must be less than upper
|
||||
|
||||
m!('a', ..'\u{0}');
|
||||
//~^ ERROR lower range bound must be less than upper
|
||||
//~| ERROR lower range bound must be less than upper
|
||||
}
|
||||
|
|
|
@ -5,155 +5,77 @@ LL | m!(0, ..u8::MIN);
|
|||
| ^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:14:11
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:13:11
|
||||
|
|
||||
LL | m!(0, ..u16::MIN);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:17:11
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:15:11
|
||||
|
|
||||
LL | m!(0, ..u32::MIN);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:20:11
|
||||
|
|
||||
LL | m!(0, ..u64::MIN);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:23:11
|
||||
|
|
||||
LL | m!(0, ..u128::MIN);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:27:11
|
||||
|
|
||||
LL | m!(0, ..i8::MIN);
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:30:11
|
||||
|
|
||||
LL | m!(0, ..i16::MIN);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:33:11
|
||||
|
|
||||
LL | m!(0, ..i32::MIN);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:36:11
|
||||
|
|
||||
LL | m!(0, ..i64::MIN);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:39:11
|
||||
|
|
||||
LL | m!(0, ..i128::MIN);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:43:14
|
||||
|
|
||||
LL | m!(0f32, ..f32::NEG_INFINITY);
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:46:14
|
||||
|
|
||||
LL | m!(0f64, ..f64::NEG_INFINITY);
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:50:13
|
||||
|
|
||||
LL | m!('a', ..'\u{0}');
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:11:11
|
||||
|
|
||||
LL | m!(0, ..u8::MIN);
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:14:11
|
||||
|
|
||||
LL | m!(0, ..u16::MIN);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:17:11
|
||||
|
|
||||
LL | m!(0, ..u32::MIN);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:20:11
|
||||
|
|
||||
LL | m!(0, ..u64::MIN);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:23:11
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:19:11
|
||||
|
|
||||
LL | m!(0, ..u128::MIN);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:27:11
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:22:11
|
||||
|
|
||||
LL | m!(0, ..i8::MIN);
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:30:11
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:24:11
|
||||
|
|
||||
LL | m!(0, ..i16::MIN);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:33:11
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:26:11
|
||||
|
|
||||
LL | m!(0, ..i32::MIN);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:36:11
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:28:11
|
||||
|
|
||||
LL | m!(0, ..i64::MIN);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:39:11
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:30:11
|
||||
|
|
||||
LL | m!(0, ..i128::MIN);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:43:14
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:33:14
|
||||
|
|
||||
LL | m!(0f32, ..f32::NEG_INFINITY);
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:46:14
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:35:14
|
||||
|
|
||||
LL | m!(0f64, ..f64::NEG_INFINITY);
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:50:13
|
||||
--> $DIR/half-open-range-pats-thir-lower-empty.rs:38:13
|
||||
|
|
||||
LL | m!('a', ..'\u{0}');
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to 26 previous errors
|
||||
error: aborting due to 13 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0579`.
|
||||
|
|
|
@ -29,6 +29,11 @@ note: ...which requires building MIR for `cycle1`...
|
|||
|
|
||||
LL | fn cycle1() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires match-checking `cycle1`...
|
||||
--> $DIR/auto-trait-leak.rs:12:1
|
||||
|
|
||||
LL | fn cycle1() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires building THIR for `cycle1`...
|
||||
--> $DIR/auto-trait-leak.rs:12:1
|
||||
|
|
||||
|
@ -70,6 +75,11 @@ note: ...which requires building MIR for `cycle2`...
|
|||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires match-checking `cycle2`...
|
||||
--> $DIR/auto-trait-leak.rs:19:1
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires building THIR for `cycle2`...
|
||||
--> $DIR/auto-trait-leak.rs:19:1
|
||||
|
|
||||
|
|
|
@ -7,7 +7,6 @@ fn foo<const V: usize>() {
|
|||
match 0 {
|
||||
const { V } => {},
|
||||
//~^ ERROR constant pattern depends on a generic parameter
|
||||
//~| ERROR constant pattern depends on a generic parameter
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +19,6 @@ fn bar<const V: usize>() {
|
|||
match 0 {
|
||||
const { f(V) } => {},
|
||||
//~^ ERROR constant pattern depends on a generic parameter
|
||||
//~| ERROR constant pattern depends on a generic parameter
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,22 +5,10 @@ LL | const { V } => {},
|
|||
| ^^^^^^^^^^^
|
||||
|
||||
error: constant pattern depends on a generic parameter
|
||||
--> $DIR/const-match-pat-generic.rs:21:9
|
||||
--> $DIR/const-match-pat-generic.rs:20:9
|
||||
|
|
||||
LL | const { f(V) } => {},
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: constant pattern depends on a generic parameter
|
||||
--> $DIR/const-match-pat-generic.rs:8:9
|
||||
|
|
||||
LL | const { V } => {},
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: constant pattern depends on a generic parameter
|
||||
--> $DIR/const-match-pat-generic.rs:21:9
|
||||
|
|
||||
LL | const { f(V) } => {},
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -3,22 +3,19 @@
|
|||
fn main() {
|
||||
match 5 {
|
||||
6 ..= 1 => { }
|
||||
//~^ ERROR lower range bound must be less than or equal to upper
|
||||
_ => { }
|
||||
};
|
||||
//~^^^ ERROR lower range bound must be less than or equal to upper
|
||||
//~| ERROR lower range bound must be less than or equal to upper
|
||||
|
||||
match 5 {
|
||||
0 .. 0 => { }
|
||||
//~^ ERROR lower range bound must be less than upper
|
||||
_ => { }
|
||||
};
|
||||
//~^^^ ERROR lower range bound must be less than upper
|
||||
//~| ERROR lower range bound must be less than upper
|
||||
|
||||
match 5u64 {
|
||||
0xFFFF_FFFF_FFFF_FFFF ..= 1 => { }
|
||||
//~^ ERROR lower range bound must be less than or equal to upper
|
||||
_ => { }
|
||||
};
|
||||
//~^^^ ERROR lower range bound must be less than or equal to upper
|
||||
//~| ERROR lower range bound must be less than or equal to upper
|
||||
}
|
||||
|
|
|
@ -5,36 +5,18 @@ LL | 6 ..= 1 => { }
|
|||
| ^ lower bound larger than upper bound
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/match-range-fail-2.rs:12:9
|
||||
--> $DIR/match-range-fail-2.rs:11:9
|
||||
|
|
||||
LL | 0 .. 0 => { }
|
||||
| ^
|
||||
|
||||
error[E0030]: lower range bound must be less than or equal to upper
|
||||
--> $DIR/match-range-fail-2.rs:19:9
|
||||
--> $DIR/match-range-fail-2.rs:17:9
|
||||
|
|
||||
LL | 0xFFFF_FFFF_FFFF_FFFF ..= 1 => { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ lower bound larger than upper bound
|
||||
|
||||
error[E0030]: lower range bound must be less than or equal to upper
|
||||
--> $DIR/match-range-fail-2.rs:5:9
|
||||
|
|
||||
LL | 6 ..= 1 => { }
|
||||
| ^ lower bound larger than upper bound
|
||||
|
||||
error[E0579]: lower range bound must be less than upper
|
||||
--> $DIR/match-range-fail-2.rs:12:9
|
||||
|
|
||||
LL | 0 .. 0 => { }
|
||||
| ^
|
||||
|
||||
error[E0030]: lower range bound must be less than or equal to upper
|
||||
--> $DIR/match-range-fail-2.rs:19:9
|
||||
|
|
||||
LL | 0xFFFF_FFFF_FFFF_FFFF ..= 1 => { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ lower bound larger than upper bound
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0030, E0579.
|
||||
For more information about an error, try `rustc --explain E0030`.
|
||||
|
|
|
@ -17,8 +17,8 @@ LL | B(inner::Wrapper<B>),
|
|||
= note: the matched value is of type `Either<(), !>`
|
||||
help: you might want to use `if let` to ignore the variant that isn't matched
|
||||
|
|
||||
LL | if let Either::A(()) = foo() { todo!() }
|
||||
| ++ ~~~~~~~~~~~
|
||||
LL | if let Either::A(()) = foo() { todo!() };
|
||||
| ++ +++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | match (0u8, 0u8) {
|
|||
= note: the matched value is of type `(u8, u8)`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ (0 | 1, 2 | 3) => {}
|
||||
LL ~ (0 | 1, 2 | 3) => {},
|
||||
LL + (2_u8..=u8::MAX, _) => todo!()
|
||||
|
|
||||
|
||||
|
@ -20,7 +20,7 @@ LL | match ((0u8,),) {
|
|||
= note: the matched value is of type `((u8,),)`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ ((0 | 1,) | (2 | 3,),) => {}
|
||||
LL ~ ((0 | 1,) | (2 | 3,),) => {},
|
||||
LL + ((4_u8..=u8::MAX)) => todo!()
|
||||
|
|
||||
|
||||
|
@ -33,7 +33,7 @@ LL | match (Some(0u8),) {
|
|||
= note: the matched value is of type `(Option<u8>,)`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ (None | Some(0 | 1),) => {}
|
||||
LL ~ (None | Some(0 | 1),) => {},
|
||||
LL + (Some(2_u8..=u8::MAX)) => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ LL | let (0 | (1 | 2)) = 0;
|
|||
= note: the matched value is of type `i32`
|
||||
help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | if let (0 | (1 | 2)) = 0 { todo!() }
|
||||
| ++ ~~~~~~~~~~~
|
||||
LL | if let (0 | (1 | 2)) = 0 { todo!() };
|
||||
| ++ +++++++++++
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
|
||||
--> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:3:11
|
||||
|
@ -21,7 +21,7 @@ LL | match 0 {
|
|||
= note: the matched value is of type `i32`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ 0 | (1 | 2) => {}
|
||||
LL ~ 0 | (1 | 2) => {},
|
||||
LL + i32::MIN..=-1_i32 | 3_i32..=i32::MAX => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ LL | let 5 = 6;
|
|||
= note: the matched value is of type `i32`
|
||||
help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | if let 5 = 6 { todo!() }
|
||||
| ++ ~~~~~~~~~~~
|
||||
LL | if let 5 = 6 { todo!() };
|
||||
| ++ +++++++++++
|
||||
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||
|
|
||||
LL | let _5 = 6;
|
||||
|
@ -20,7 +20,7 @@ error[E0005]: refutable pattern in local binding
|
|||
--> $DIR/issue-106552.rs:5:9
|
||||
|
|
||||
LL | let x @ 5 = 6;
|
||||
| ^^^^^ patterns `i32::MIN..=4_i32` and `6_i32..=i32::MAX` not covered
|
||||
| ^ patterns `i32::MIN..=4_i32` and `6_i32..=i32::MAX` not covered
|
||||
|
|
||||
= 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
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
error[E0158]: associated consts cannot be referenced in patterns
|
||||
--> $DIR/issue-68393-let-pat-assoc-constant.rs:20:40
|
||||
|
|
||||
LL | pub fn test<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
|
||||
| ^^^^
|
||||
|
||||
error[E0158]: associated consts cannot be referenced in patterns
|
||||
--> $DIR/issue-68393-let-pat-assoc-constant.rs:22:9
|
||||
|
|
||||
LL | let A::X = arg;
|
||||
| ^^^^
|
||||
|
||||
error[E0158]: associated consts cannot be referenced in patterns
|
||||
--> $DIR/issue-68393-let-pat-assoc-constant.rs:20:40
|
||||
|
|
||||
LL | pub fn test<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0158`.
|
||||
|
|
|
@ -4,7 +4,7 @@ fn main() {
|
|||
match Some(1) { //~ ERROR non-exhaustive patterns: `None` not covered
|
||||
Some(1) => {}
|
||||
// hello
|
||||
Some(_) => {}
|
||||
Some(_) => {},
|
||||
None => todo!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ note: `Option<i32>` defined here
|
|||
= note: the matched value is of type `Option<i32>`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ Some(_) => {}
|
||||
LL ~ Some(_) => {},
|
||||
LL + None => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -7,21 +7,6 @@ LL | FOO => {}
|
|||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:32:9
|
||||
|
|
||||
LL | FOO => {}
|
||||
| --- matches any value
|
||||
LL |
|
||||
LL | _ => {} // should not be emitting unreachable warning
|
||||
| ^ unreachable pattern
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/consts-opaque.rs:6:9
|
||||
|
|
||||
LL | #![deny(unreachable_patterns)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:37:9
|
||||
|
|
||||
|
@ -31,15 +16,6 @@ LL | FOO_REF => {}
|
|||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:39:9
|
||||
|
|
||||
LL | FOO_REF => {}
|
||||
| ------- matches any value
|
||||
LL |
|
||||
LL | Foo(_) => {} // should not be emitting unreachable warning
|
||||
| ^^^^^^ unreachable pattern
|
||||
|
||||
warning: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:45:9
|
||||
|
|
||||
|
@ -61,23 +37,6 @@ LL | BAR => {} // should not be emitting unreachable warning
|
|||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:53:9
|
||||
|
|
||||
LL | Bar => {}
|
||||
| --- matches any value
|
||||
LL | BAR => {} // should not be emitting unreachable warning
|
||||
| ^^^ unreachable pattern
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:56:9
|
||||
|
|
||||
LL | Bar => {}
|
||||
| --- matches any value
|
||||
...
|
||||
LL | _ => {}
|
||||
| ^ unreachable pattern
|
||||
|
||||
error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:61:9
|
||||
|
|
||||
|
@ -87,24 +46,6 @@ LL | BAR => {}
|
|||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:63:9
|
||||
|
|
||||
LL | BAR => {}
|
||||
| --- matches any value
|
||||
LL |
|
||||
LL | Bar => {} // should not be emitting unreachable warning
|
||||
| ^^^ unreachable pattern
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:65:9
|
||||
|
|
||||
LL | BAR => {}
|
||||
| --- matches any value
|
||||
...
|
||||
LL | _ => {}
|
||||
| ^ unreachable pattern
|
||||
|
||||
error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:70:9
|
||||
|
|
||||
|
@ -123,6 +64,92 @@ LL | BAR => {} // should not be emitting unreachable warning
|
|||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:80:9
|
||||
|
|
||||
LL | BAZ => {}
|
||||
| ^^^
|
||||
|
|
||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:90:9
|
||||
|
|
||||
LL | BAZ => {}
|
||||
| ^^^
|
||||
|
|
||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:97:9
|
||||
|
|
||||
LL | BAZ => {}
|
||||
| ^^^
|
||||
|
|
||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:32:9
|
||||
|
|
||||
LL | FOO => {}
|
||||
| --- matches any value
|
||||
LL |
|
||||
LL | _ => {} // should not be emitting unreachable warning
|
||||
| ^ unreachable pattern
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/consts-opaque.rs:6:9
|
||||
|
|
||||
LL | #![deny(unreachable_patterns)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:39:9
|
||||
|
|
||||
LL | FOO_REF => {}
|
||||
| ------- matches any value
|
||||
LL |
|
||||
LL | Foo(_) => {} // should not be emitting unreachable warning
|
||||
| ^^^^^^ unreachable pattern
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:53:9
|
||||
|
|
||||
LL | Bar => {}
|
||||
| --- matches any value
|
||||
LL | BAR => {} // should not be emitting unreachable warning
|
||||
| ^^^ unreachable pattern
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:56:9
|
||||
|
|
||||
LL | Bar => {}
|
||||
| --- matches any value
|
||||
...
|
||||
LL | _ => {}
|
||||
| ^ unreachable pattern
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:63:9
|
||||
|
|
||||
LL | BAR => {}
|
||||
| --- matches any value
|
||||
LL |
|
||||
LL | Bar => {} // should not be emitting unreachable warning
|
||||
| ^^^ unreachable pattern
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:65:9
|
||||
|
|
||||
LL | BAR => {}
|
||||
| --- matches any value
|
||||
...
|
||||
LL | _ => {}
|
||||
| ^ unreachable pattern
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:72:9
|
||||
|
|
||||
|
@ -141,15 +168,6 @@ LL | BAR => {}
|
|||
LL | _ => {} // should not be emitting unreachable warning
|
||||
| ^ unreachable pattern
|
||||
|
||||
error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:80:9
|
||||
|
|
||||
LL | BAZ => {}
|
||||
| ^^^
|
||||
|
|
||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:82:9
|
||||
|
|
||||
|
@ -168,15 +186,6 @@ LL | BAZ => {}
|
|||
LL | _ => {}
|
||||
| ^ unreachable pattern
|
||||
|
||||
error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:90:9
|
||||
|
|
||||
LL | BAZ => {}
|
||||
| ^^^
|
||||
|
|
||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:92:9
|
||||
|
|
||||
|
@ -186,15 +195,6 @@ LL |
|
|||
LL | _ => {}
|
||||
| ^ unreachable pattern
|
||||
|
||||
error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
--> $DIR/consts-opaque.rs:97:9
|
||||
|
|
||||
LL | BAZ => {}
|
||||
| ^^^
|
||||
|
|
||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
|
||||
|
||||
error: unreachable pattern
|
||||
--> $DIR/consts-opaque.rs:99:9
|
||||
|
|
||||
|
|
|
@ -12,7 +12,7 @@ LL | pub enum HiddenEnum {
|
|||
= note: the matched value is of type `HiddenEnum`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ HiddenEnum::B => {}
|
||||
LL ~ HiddenEnum::B => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
@ -33,7 +33,7 @@ LL | B,
|
|||
= note: the matched value is of type `HiddenEnum`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ HiddenEnum::C => {}
|
||||
LL ~ HiddenEnum::C => {},
|
||||
LL + HiddenEnum::B => todo!()
|
||||
|
|
||||
|
||||
|
@ -54,7 +54,7 @@ LL | B,
|
|||
= note: the matched value is of type `HiddenEnum`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ HiddenEnum::A => {}
|
||||
LL ~ HiddenEnum::A => {},
|
||||
LL + HiddenEnum::B | _ => todo!()
|
||||
|
|
||||
|
||||
|
@ -72,7 +72,7 @@ note: `Option<HiddenEnum>` defined here
|
|||
= note: the matched value is of type `Option<HiddenEnum>`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ Some(HiddenEnum::A) => {}
|
||||
LL ~ Some(HiddenEnum::A) => {},
|
||||
LL + Some(HiddenEnum::B) | Some(_) => todo!()
|
||||
|
|
||||
|
||||
|
@ -93,7 +93,7 @@ LL | C,
|
|||
= note: the matched value is of type `InCrate`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ InCrate::B => {}
|
||||
LL ~ InCrate::B => {},
|
||||
LL + InCrate::C => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@ LL | match_guarded_arm!(0u8);
|
|||
= note: the matched value is of type `u8`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
@ -180,7 +180,7 @@ LL | struct NonEmptyStruct1;
|
|||
= note: the matched value is of type `NonEmptyStruct1`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + NonEmptyStruct1 => todo!()
|
||||
|
|
||||
|
||||
|
@ -198,7 +198,7 @@ LL | struct NonEmptyStruct2(bool);
|
|||
= note: the matched value is of type `NonEmptyStruct2`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + NonEmptyStruct2(_) => todo!()
|
||||
|
|
||||
|
||||
|
@ -216,7 +216,7 @@ LL | union NonEmptyUnion1 {
|
|||
= note: the matched value is of type `NonEmptyUnion1`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + NonEmptyUnion1 { .. } => todo!()
|
||||
|
|
||||
|
||||
|
@ -234,7 +234,7 @@ LL | union NonEmptyUnion2 {
|
|||
= note: the matched value is of type `NonEmptyUnion2`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + NonEmptyUnion2 { .. } => todo!()
|
||||
|
|
||||
|
||||
|
@ -254,7 +254,7 @@ LL | Foo(bool),
|
|||
= note: the matched value is of type `NonEmptyEnum1`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + NonEmptyEnum1::Foo(_) => todo!()
|
||||
|
|
||||
|
||||
|
@ -276,7 +276,7 @@ LL | Bar,
|
|||
= note: the matched value is of type `NonEmptyEnum2`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
|
||||
|
|
||||
|
||||
|
@ -294,7 +294,7 @@ LL | enum NonEmptyEnum5 {
|
|||
= note: the matched value is of type `NonEmptyEnum5`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@ LL | match_guarded_arm!(0u8);
|
|||
= note: the matched value is of type `u8`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
@ -180,7 +180,7 @@ LL | struct NonEmptyStruct1;
|
|||
= note: the matched value is of type `NonEmptyStruct1`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + NonEmptyStruct1 => todo!()
|
||||
|
|
||||
|
||||
|
@ -198,7 +198,7 @@ LL | struct NonEmptyStruct2(bool);
|
|||
= note: the matched value is of type `NonEmptyStruct2`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + NonEmptyStruct2(_) => todo!()
|
||||
|
|
||||
|
||||
|
@ -216,7 +216,7 @@ LL | union NonEmptyUnion1 {
|
|||
= note: the matched value is of type `NonEmptyUnion1`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + NonEmptyUnion1 { .. } => todo!()
|
||||
|
|
||||
|
||||
|
@ -234,7 +234,7 @@ LL | union NonEmptyUnion2 {
|
|||
= note: the matched value is of type `NonEmptyUnion2`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + NonEmptyUnion2 { .. } => todo!()
|
||||
|
|
||||
|
||||
|
@ -254,7 +254,7 @@ LL | Foo(bool),
|
|||
= note: the matched value is of type `NonEmptyEnum1`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + NonEmptyEnum1::Foo(_) => todo!()
|
||||
|
|
||||
|
||||
|
@ -276,7 +276,7 @@ LL | Bar,
|
|||
= note: the matched value is of type `NonEmptyEnum2`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
|
||||
|
|
||||
|
||||
|
@ -294,7 +294,7 @@ LL | enum NonEmptyEnum5 {
|
|||
= note: the matched value is of type `NonEmptyEnum5`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
|
||||
|
|
||||
LL ~ _ if false => {}
|
||||
LL ~ _ if false => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | match 0.0 {
|
|||
= note: the matched value is of type `f64`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ 0.0..=1.0 => {}
|
||||
LL ~ 0.0..=1.0 => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | match 0u8 {
|
|||
= note: the matched value is of type `u8`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ 128 ..= 255 if true => {}
|
||||
LL ~ 128 ..= 255 if true => {},
|
||||
LL + 128_u8..=u8::MAX => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ LL | match 0i8 {
|
|||
= note: the matched value is of type `i8`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ 1 ..= i8::MAX => {}
|
||||
LL ~ 1 ..= i8::MAX => {},
|
||||
LL + 0_i8 => todo!()
|
||||
|
|
||||
|
||||
|
@ -140,7 +140,7 @@ LL | match (0u8, true) {
|
|||
= note: the matched value is of type `(u8, bool)`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ (0 ..= 255, true) => {}
|
||||
LL ~ (0 ..= 255, true) => {},
|
||||
LL + (126_u8..=127_u8, false) => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ LL | match 0usize {
|
|||
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ 0 ..= usize::MAX => {}
|
||||
LL ~ 0 ..= usize::MAX => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
@ -24,7 +24,7 @@ LL | match 0isize {
|
|||
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ isize::MIN ..= isize::MAX => {}
|
||||
LL ~ isize::MIN ..= isize::MAX => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
@ -147,7 +147,7 @@ LL | match 0isize {
|
|||
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ 1 ..= isize::MAX => {}
|
||||
LL ~ 1 ..= isize::MAX => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ LL | match 0usize {
|
|||
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ 0..=usize::MAX => {}
|
||||
LL ~ 0..=usize::MAX => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
@ -24,7 +24,7 @@ LL | match 0isize {
|
|||
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ isize::MIN..=isize::MAX => {}
|
||||
LL ~ isize::MIN..=isize::MAX => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | match (a, b) {
|
|||
= note: the matched value is of type `(Option<usize>, Option<usize>)`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ (Some(_), None) | (None, Some(_)) => {}
|
||||
LL ~ (Some(_), None) | (None, Some(_)) => {},
|
||||
LL + (None, None) | (Some(_), Some(_)) => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | match "world" {
|
|||
= note: the matched value is of type `&str`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ "hello" => {}
|
||||
LL ~ "hello" => {},
|
||||
LL + &_ => todo!()
|
||||
|
|
||||
|
||||
|
@ -20,7 +20,7 @@ LL | match "world" {
|
|||
= note: the matched value is of type `&str`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ "hello" => {}
|
||||
LL ~ "hello" => {},
|
||||
LL + &_ => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | match (A, ()) {
|
|||
= note: the matched value is of type `(Enum, ())`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
|
||||
|
|
||||
LL ~ (A, _) => {}
|
||||
LL ~ (A, _) => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
@ -20,7 +20,7 @@ LL | match (A, A) {
|
|||
= note: the matched value is of type `(Enum, Enum)`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
|
||||
|
|
||||
LL ~ (_, A) => {}
|
||||
LL ~ (_, A) => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
@ -33,7 +33,7 @@ LL | match ((A, ()), ()) {
|
|||
= note: the matched value is of type `((Enum, ()), ())`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
|
||||
|
|
||||
LL ~ ((A, ()), _) => {}
|
||||
LL ~ ((A, ()), _) => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
@ -46,7 +46,7 @@ LL | match ((A, ()), A) {
|
|||
= note: the matched value is of type `((Enum, ()), Enum)`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
|
||||
|
|
||||
LL ~ ((A, ()), _) => {}
|
||||
LL ~ ((A, ()), _) => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
@ -59,7 +59,7 @@ LL | match ((A, ()), ()) {
|
|||
= note: the matched value is of type `((Enum, ()), ())`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
|
||||
|
|
||||
LL ~ ((A, _), _) => {}
|
||||
LL ~ ((A, _), _) => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
@ -77,7 +77,7 @@ LL | struct S(Enum, ());
|
|||
= note: the matched value is of type `S`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
|
||||
|
|
||||
LL ~ S(A, _) => {}
|
||||
LL ~ S(A, _) => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
@ -95,7 +95,7 @@ LL | struct Sd { x: Enum, y: () }
|
|||
= note: the matched value is of type `Sd`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
|
||||
|
|
||||
LL ~ Sd { x: A, y: _ } => {}
|
||||
LL ~ Sd { x: A, y: _ } => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ note: `Box<ElementKind>` defined here
|
|||
= note: the matched value is of type `Box<ElementKind>`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => { true }
|
||||
LL ~ box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => { true },
|
||||
LL + box _ => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ LL | pub struct Tag(pub Context, pub u16);
|
|||
= note: the matched value is of type `Tag`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ Tag::ExifIFDPointer => {}
|
||||
LL ~ Tag::ExifIFDPointer => {},
|
||||
LL + Tag(Context::Exif, _) => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ LL | C(bool),
|
|||
= note: the matched value is of type `Foo`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ Foo::C(true) => {}
|
||||
LL ~ Foo::C(true) => {},
|
||||
LL + Foo::A(false) | Foo::B(false) | Foo::C(false) => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | match buf {
|
|||
= note: the matched value is of type `&[u8; 4]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ b"AAAA" => {}
|
||||
LL ~ b"AAAA" => {},
|
||||
LL + &[0_u8..=64_u8, _, _, _] | &[66_u8..=u8::MAX, _, _, _] => todo!()
|
||||
|
|
||||
|
||||
|
@ -20,7 +20,7 @@ LL | match buf {
|
|||
= note: the matched value is of type `&[u8]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
|
||||
|
|
||||
LL ~ b"AAAA" => {}
|
||||
LL ~ b"AAAA" => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ note: `Option<Private>` defined here
|
|||
= note: the matched value is of type `Option<Private>`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ }) => {}
|
||||
LL ~ }) => {},
|
||||
LL + Some(Private { misc: true, .. }) => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | match list {
|
|||
= note: the matched value is of type `&[Option<()>]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ &[.., Some(_), _] => {}
|
||||
LL ~ &[.., Some(_), _] => {},
|
||||
LL ~ &[_, Some(_), .., None, _] => todo!(),
|
||||
|
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ LL | C
|
|||
= note: the matched value is of type `E`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ E::A => {}
|
||||
LL ~ E::A => {},
|
||||
LL + E::B | E::C => todo!()
|
||||
|
|
||||
|
||||
|
@ -44,8 +44,8 @@ LL | C
|
|||
= note: the matched value is of type `E`
|
||||
help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | if let E::A = e { todo!() }
|
||||
| ++ ~~~~~~~~~~~
|
||||
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:50:11
|
||||
|
@ -67,7 +67,7 @@ LL | C
|
|||
= note: the matched value is of type `&E`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ E::A => {}
|
||||
LL ~ E::A => {},
|
||||
LL + &E::B | &E::C => todo!()
|
||||
|
|
||||
|
||||
|
@ -93,8 +93,8 @@ LL | C
|
|||
= note: the matched value is of type `&E`
|
||||
help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | if let E::A = e { todo!() }
|
||||
| ++ ~~~~~~~~~~~
|
||||
LL | if let E::A = e { todo!() };
|
||||
| ++ +++++++++++
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `&&mut &E::B` and `&&mut &E::C` not covered
|
||||
--> $DIR/non-exhaustive-defined-here.rs:66:11
|
||||
|
@ -116,7 +116,7 @@ LL | C
|
|||
= note: the matched value is of type `&&mut &E`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ E::A => {}
|
||||
LL ~ E::A => {},
|
||||
LL + &&mut &E::B | &&mut &E::C => todo!()
|
||||
|
|
||||
|
||||
|
@ -142,8 +142,8 @@ LL | C
|
|||
= 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
|
||||
|
|
||||
LL | if let E::A = e { todo!() }
|
||||
| ++ ~~~~~~~~~~~
|
||||
LL | if let E::A = e { todo!() };
|
||||
| ++ +++++++++++
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Opt::None` not covered
|
||||
--> $DIR/non-exhaustive-defined-here.rs:92:11
|
||||
|
@ -162,7 +162,7 @@ LL | None,
|
|||
= note: the matched value is of type `Opt`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ Opt::Some(ref _x) => {}
|
||||
LL ~ Opt::Some(ref _x) => {},
|
||||
LL + Opt::None => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ LL | enum T { A(U), B }
|
|||
= note: the matched value is of type `T`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ T::B => { panic!("goodbye"); }
|
||||
LL ~ T::B => { panic!("goodbye"); },
|
||||
LL + T::A(U::C) => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ LL | match true {
|
|||
= note: the matched value is of type `bool`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ true => {}
|
||||
LL ~ true => {},
|
||||
LL + false => todo!()
|
||||
|
|
||||
|
||||
|
@ -42,7 +42,7 @@ note: `Option<i32>` defined here
|
|||
= note: the matched value is of type `Option<i32>`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ None => {}
|
||||
LL ~ None => {},
|
||||
LL + Some(_) => todo!()
|
||||
|
|
||||
|
||||
|
@ -55,7 +55,7 @@ LL | match (2, 3, 4) {
|
|||
= note: the matched value is of type `(i32, i32, i32)`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ (_, _, 4) => {}
|
||||
LL ~ (_, _, 4) => {},
|
||||
LL + (_, _, i32::MIN..=3_i32) | (_, _, 5_i32..=i32::MAX) => todo!()
|
||||
|
|
||||
|
||||
|
@ -68,7 +68,7 @@ LL | match (T::A, T::A) {
|
|||
= note: the matched value is of type `(T, T)`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ (T::B, T::A) => {}
|
||||
LL ~ (T::B, T::A) => {},
|
||||
LL + (T::A, T::A) | (T::B, T::B) => todo!()
|
||||
|
|
||||
|
||||
|
@ -86,7 +86,7 @@ LL | enum T { A, B }
|
|||
= note: the matched value is of type `T`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ T::A => {}
|
||||
LL ~ T::A => {},
|
||||
LL + T::B => todo!()
|
||||
|
|
||||
|
||||
|
@ -99,7 +99,7 @@ LL | match *vec {
|
|||
= note: the matched value is of type `[Option<isize>]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ [None] => {}
|
||||
LL ~ [None] => {},
|
||||
LL + [] => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ LL | let (1, (Some(1), 2..=3)) = (1, (None, 2));
|
|||
= note: the matched value is of type `(i32, (Option<i32>, i32))`
|
||||
help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | if let (1, (Some(1), 2..=3)) = (1, (None, 2)) { todo!() }
|
||||
| ++ ~~~~~~~~~~~
|
||||
LL | if let (1, (Some(1), 2..=3)) = (1, (None, 2)) { todo!() };
|
||||
| ++ +++++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | match s2 {
|
|||
= note: the matched value is of type `&[bool; 2]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ [true, .., true] => {}
|
||||
LL ~ [true, .., true] => {},
|
||||
LL + &[false, _] => todo!()
|
||||
|
|
||||
|
||||
|
@ -20,7 +20,7 @@ LL | match s3 {
|
|||
= note: the matched value is of type `&[bool; 3]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ [true, .., true] => {}
|
||||
LL ~ [true, .., true] => {},
|
||||
LL + &[false, ..] => todo!()
|
||||
|
|
||||
|
||||
|
@ -33,7 +33,7 @@ LL | match s10 {
|
|||
= note: the matched value is of type `&[bool; 10]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ [true, .., true] => {}
|
||||
LL ~ [true, .., true] => {},
|
||||
LL + &[false, ..] => todo!()
|
||||
|
|
||||
|
||||
|
@ -46,7 +46,7 @@ LL | match s2 {
|
|||
= note: the matched value is of type `&[bool; 2]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ [.., false] => {}
|
||||
LL ~ [.., false] => {},
|
||||
LL + &[false, true] => todo!()
|
||||
|
|
||||
|
||||
|
@ -59,7 +59,7 @@ LL | match s3 {
|
|||
= note: the matched value is of type `&[bool; 3]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ [.., false] => {}
|
||||
LL ~ [.., false] => {},
|
||||
LL + &[false, .., true] => todo!()
|
||||
|
|
||||
|
||||
|
@ -72,7 +72,7 @@ LL | match s {
|
|||
= note: the matched value is of type `&[bool]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ [.., false] => {}
|
||||
LL ~ [.., false] => {},
|
||||
LL + &[false, .., true] => todo!()
|
||||
|
|
||||
|
||||
|
@ -85,7 +85,7 @@ LL | match s {
|
|||
= note: the matched value is of type `&[bool]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ [] => {}
|
||||
LL ~ [] => {},
|
||||
LL + &[_, ..] => todo!()
|
||||
|
|
||||
|
||||
|
@ -98,7 +98,7 @@ LL | match s {
|
|||
= note: the matched value is of type `&[bool]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ [_] => {}
|
||||
LL ~ [_] => {},
|
||||
LL + &[_, _, ..] => todo!()
|
||||
|
|
||||
|
||||
|
@ -111,7 +111,7 @@ LL | match s {
|
|||
= note: the matched value is of type `&[bool]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ [true, ..] => {}
|
||||
LL ~ [true, ..] => {},
|
||||
LL + &[false, ..] => todo!()
|
||||
|
|
||||
|
||||
|
@ -124,7 +124,7 @@ LL | match s {
|
|||
= note: the matched value is of type `&[bool]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ [true, ..] => {}
|
||||
LL ~ [true, ..] => {},
|
||||
LL + &[false, _, ..] => todo!()
|
||||
|
|
||||
|
||||
|
@ -137,7 +137,7 @@ LL | match s {
|
|||
= note: the matched value is of type `&[bool]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ [.., true] => {}
|
||||
LL ~ [.., true] => {},
|
||||
LL + &[_, .., false] => todo!()
|
||||
|
|
||||
|
||||
|
@ -150,7 +150,7 @@ LL | match s {
|
|||
= note: the matched value is of type `&[bool]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ [.., false] => {}
|
||||
LL ~ [.., false] => {},
|
||||
LL + &[_, _, .., true] => todo!()
|
||||
|
|
||||
|
||||
|
@ -163,7 +163,7 @@ LL | match s {
|
|||
= note: the matched value is of type `&[bool]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ [false, .., false] => {}
|
||||
LL ~ [false, .., false] => {},
|
||||
LL + &[true, _, .., _] => todo!()
|
||||
|
|
||||
|
||||
|
@ -176,7 +176,7 @@ LL | match s {
|
|||
= note: the matched value is of type `&[bool]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ &[true] => {}
|
||||
LL ~ &[true] => {},
|
||||
LL + &[] | &[_, _, ..] => todo!()
|
||||
|
|
||||
|
||||
|
@ -189,7 +189,7 @@ LL | match s {
|
|||
= note: the matched value is of type `&[bool]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ CONST => {}
|
||||
LL ~ CONST => {},
|
||||
LL + &[] | &[_, _, ..] => todo!()
|
||||
|
|
||||
|
||||
|
@ -202,7 +202,7 @@ LL | match s {
|
|||
= note: the matched value is of type `&[bool]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ &[false] => {}
|
||||
LL ~ &[false] => {},
|
||||
LL + &[] | &[_, _, ..] => todo!()
|
||||
|
|
||||
|
||||
|
@ -215,7 +215,7 @@ LL | match s {
|
|||
= note: the matched value is of type `&[bool]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ CONST => {}
|
||||
LL ~ CONST => {},
|
||||
LL + &[] | &[_, _, ..] => todo!()
|
||||
|
|
||||
|
||||
|
@ -228,7 +228,7 @@ LL | match s {
|
|||
= note: the matched value is of type `&[bool]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ CONST => {}
|
||||
LL ~ CONST => {},
|
||||
LL + &[_, _, ..] => todo!()
|
||||
|
|
||||
|
||||
|
@ -241,7 +241,7 @@ LL | match s {
|
|||
= note: the matched value is of type `&[bool]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ &[_, _, ..] => {}
|
||||
LL ~ &[_, _, ..] => {},
|
||||
LL + &[false] => todo!()
|
||||
|
|
||||
|
||||
|
@ -254,7 +254,7 @@ LL | match s1 {
|
|||
= note: the matched value is of type `&[bool; 1]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ CONST1 => {}
|
||||
LL ~ CONST1 => {},
|
||||
LL + &[false] => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ LL | Stable2,
|
|||
= note: the matched value is of type `UnstableEnum`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
|
||||
|
|
||||
LL ~ UnstableEnum::Stable => {}
|
||||
LL ~ UnstableEnum::Stable => {},
|
||||
LL + UnstableEnum::Stable2 | _ => todo!()
|
||||
|
|
||||
|
||||
|
@ -33,7 +33,7 @@ LL | pub enum UnstableEnum {
|
|||
= note: the matched value is of type `UnstableEnum`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ UnstableEnum::Stable2 => {}
|
||||
LL ~ UnstableEnum::Stable2 => {},
|
||||
LL + _ => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ LL | B { x: Option<isize> },
|
|||
= note: the matched value is of type `A`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ A::B { x: None } => {}
|
||||
LL ~ A::B { x: None } => {},
|
||||
LL + A::B { x: Some(_) } => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ LL | Unstable,
|
|||
= note: the matched value is of type `UnstableEnum`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ UnstableEnum::Stable2 => {}
|
||||
LL ~ UnstableEnum::Stable2 => {},
|
||||
LL + UnstableEnum::Unstable => todo!()
|
||||
|
|
||||
|
||||
|
|
|
@ -4,10 +4,8 @@ fn main() {
|
|||
match 0u8 {
|
||||
251..257 => {}
|
||||
//~^ ERROR literal out of range
|
||||
//~| ERROR literal out of range
|
||||
251..=256 => {}
|
||||
//~^ ERROR literal out of range
|
||||
//~| ERROR literal out of range
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,22 +5,10 @@ LL | 251..257 => {}
|
|||
| ^^^ this value doesn't fit in `u8` whose maximum value is `255`
|
||||
|
||||
error: literal out of range for `u8`
|
||||
--> $DIR/range-pattern-out-of-bounds-issue-68972.rs:8:15
|
||||
--> $DIR/range-pattern-out-of-bounds-issue-68972.rs:7:15
|
||||
|
|
||||
LL | 251..=256 => {}
|
||||
| ^^^ this value doesn't fit in `u8` whose maximum value is `255`
|
||||
|
||||
error: literal out of range for `u8`
|
||||
--> $DIR/range-pattern-out-of-bounds-issue-68972.rs:5:14
|
||||
|
|
||||
LL | 251..257 => {}
|
||||
| ^^^ this value doesn't fit in `u8` whose maximum value is `255`
|
||||
|
||||
error: literal out of range for `u8`
|
||||
--> $DIR/range-pattern-out-of-bounds-issue-68972.rs:8:15
|
||||
|
|
||||
LL | 251..=256 => {}
|
||||
| ^^^ this value doesn't fit in `u8` whose maximum value is `255`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | match sl {
|
|||
= note: the matched value is of type `&[u8]`
|
||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
||||
|
|
||||
LL ~ [first, remainder @ ..] => {}
|
||||
LL ~ [first, remainder @ ..] => {},
|
||||
LL ~ &[] => todo!(),
|
||||
|
|
||||
|
||||
|
|
|
@ -2,10 +2,7 @@ fn main() {
|
|||
let A = 3;
|
||||
//~^ 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
|
||||
//~| HELP you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
||||
const A: i32 = 2;
|
||||
//~^ constant defined here
|
||||
}
|
||||
|
|
|
@ -2,16 +2,15 @@ error[E0005]: refutable pattern in local binding
|
|||
--> $DIR/const-pat-non-exaustive-let-new-var.rs:2:9
|
||||
|
|
||||
LL | let A = 3;
|
||||
| ^
|
||||
| |
|
||||
| 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;
|
||||
| ------------ constant defined here
|
||||
| ^ patterns `i32::MIN..=1_i32` and `3_i32..=i32::MAX` not covered
|
||||
|
|
||||
= 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: the matched value is of type `i32`
|
||||
help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | if let A = 3 { todo!() };
|
||||
| ++ +++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue