Auto merge of #108504 - cjgillot:thir-pattern, r=compiler-errors,Nilstrieb

Check pattern refutability on THIR

The current `check_match` query is based on HIR, but partially re-lowers HIR into THIR.
This PR proposed to use the results of the `thir_body` query to check matches, instead of re-building THIR.

Most of the diagnostic changes are spans getting shorter, or commas/semicolons not getting removed.

This PR degrades the diagnostic for confusing constants in patterns (`let A = foo()` where `A` resolves to a `const A` somewhere): it does not point ot the definition of `const A` any more.
This commit is contained in:
bors 2023-04-06 12:42:01 +00:00
commit 0534655d9b
106 changed files with 1058 additions and 1499 deletions

View file

@ -2,7 +2,6 @@ use crate::def::{CtorOf, DefKind, Res};
use crate::def_id::DefId; use crate::def_id::DefId;
use crate::hir::{self, BindingAnnotation, ByRef, HirId, PatKind}; use crate::hir::{self, BindingAnnotation, ByRef, HirId, PatKind};
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_span::hygiene::DesugaringKind;
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
use rustc_span::Span; use rustc_span::Span;
@ -136,14 +135,4 @@ impl hir::Pat<'_> {
}); });
result 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
}
} }

View file

@ -765,7 +765,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
parallel!( parallel!(
{ {
sess.time("match_checking", || { sess.time("match_checking", || {
tcx.hir().par_body_owners(|def_id| tcx.ensure().check_match(def_id.to_def_id())) tcx.hir().par_body_owners(|def_id| tcx.ensure().check_match(def_id))
}); });
}, },
{ {

View file

@ -94,7 +94,7 @@ impl<'tcx> DepContext for TyCtxt<'tcx> {
} }
#[inline] #[inline]
fn dep_kind_info(&self, dep_kind: DepKind) -> &DepKindStruct<'tcx> { fn dep_kind_info(&self, dk: DepKind) -> &DepKindStruct<'tcx> {
&self.query_kinds[dep_kind as usize] &self.query_kinds[dk as usize]
} }
} }

View file

@ -2001,6 +2001,13 @@ impl<'tcx> Rvalue<'tcx> {
} }
impl BorrowKind { impl BorrowKind {
pub fn mutability(&self) -> Mutability {
match *self {
BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => Mutability::Not,
BorrowKind::Mut { .. } => Mutability::Mut,
}
}
pub fn allows_two_phase_borrow(&self) -> bool { pub fn allows_two_phase_borrow(&self) -> bool {
match *self { match *self {
BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => false, BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => false,

View file

@ -1114,9 +1114,9 @@ rustc_queries! {
desc { "converting literal to mir constant" } desc { "converting literal to mir constant" }
} }
query check_match(key: DefId) { query check_match(key: LocalDefId) {
desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) } desc { |tcx| "match-checking `{}`", tcx.def_path_str(key.to_def_id()) }
cache_on_disk_if { key.is_local() } cache_on_disk_if { true }
} }
/// Performs part of the privacy check and computes effective visibilities. /// Performs part of the privacy check and computes effective visibilities.

View file

@ -227,6 +227,9 @@ pub enum StmtKind<'tcx> {
/// The lint level for this `let` statement. /// The lint level for this `let` statement.
lint_level: LintLevel, lint_level: LintLevel,
/// Span of the `let <PAT> = <INIT>` part.
span: Span,
}, },
} }
@ -594,6 +597,55 @@ impl<'tcx> Pat<'tcx> {
_ => None, _ => None,
} }
} }
/// Call `f` on every "binding" in a pattern, e.g., on `a` in
/// `match foo() { Some(a) => (), None => () }`
pub fn each_binding(&self, mut f: impl FnMut(Symbol, BindingMode, Ty<'tcx>, Span)) {
self.walk_always(|p| {
if let PatKind::Binding { name, mode, ty, .. } = p.kind {
f(name, mode, ty, p.span);
}
});
}
/// Walk the pattern in left-to-right order.
///
/// If `it(pat)` returns `false`, the children are not visited.
pub fn walk(&self, mut it: impl FnMut(&Pat<'tcx>) -> bool) {
self.walk_(&mut it)
}
fn walk_(&self, it: &mut impl FnMut(&Pat<'tcx>) -> bool) {
if !it(self) {
return;
}
use PatKind::*;
match &self.kind {
Wild | Range(..) | Binding { subpattern: None, .. } | Constant { .. } => {}
AscribeUserType { subpattern, .. }
| Binding { subpattern: Some(subpattern), .. }
| Deref { subpattern } => subpattern.walk_(it),
Leaf { subpatterns } | Variant { subpatterns, .. } => {
subpatterns.iter().for_each(|field| field.pattern.walk_(it))
}
Or { pats } => pats.iter().for_each(|p| p.walk_(it)),
Array { box ref prefix, ref slice, box ref suffix }
| Slice { box ref prefix, ref slice, box ref suffix } => {
prefix.iter().chain(slice.iter()).chain(suffix.iter()).for_each(|p| p.walk_(it))
}
}
}
/// Walk the pattern in left-to-right order.
///
/// If you always want to recurse, prefer this method over `walk`.
pub fn walk_always(&self, mut it: impl FnMut(&Pat<'tcx>)) {
self.walk(|p| {
it(p);
true
})
}
} }
impl<'tcx> IntoDiagnosticArg for Pat<'tcx> { impl<'tcx> IntoDiagnosticArg for Pat<'tcx> {
@ -879,7 +931,7 @@ mod size_asserts {
static_assert_size!(ExprKind<'_>, 40); static_assert_size!(ExprKind<'_>, 40);
static_assert_size!(Pat<'_>, 72); static_assert_size!(Pat<'_>, 72);
static_assert_size!(PatKind<'_>, 56); static_assert_size!(PatKind<'_>, 56);
static_assert_size!(Stmt<'_>, 48); static_assert_size!(Stmt<'_>, 56);
static_assert_size!(StmtKind<'_>, 40); static_assert_size!(StmtKind<'_>, 48);
// tidy-alphabetical-end // tidy-alphabetical-end
} }

View file

@ -175,6 +175,7 @@ pub fn walk_stmt<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, stmt: &Stm
ref pattern, ref pattern,
lint_level: _, lint_level: _,
else_block, else_block,
span: _,
} => { } => {
if let Some(init) = initializer { if let Some(init) = initializer {
visitor.visit_expr(&visitor.thir()[*init]); visitor.visit_expr(&visitor.thir()[*init]);

View file

@ -239,19 +239,9 @@ mir_build_trailing_irrefutable_let_patterns = trailing irrefutable {$count ->
} into the body } into the body
mir_build_bindings_with_variant_name = 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 .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 -> mir_build_irrefutable_let_patterns_if_let = irrefutable `if let` {$count ->
[one] pattern [one] pattern
*[other] patterns *[other] patterns
@ -357,15 +347,13 @@ mir_build_inform_irrefutable = `let` bindings require an "irrefutable pattern",
mir_build_more_information = for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html mir_build_more_information = for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
mir_build_res_defined_here = {$res} defined here
mir_build_adt_defined_here = `{$ty}` defined here mir_build_adt_defined_here = `{$ty}` defined here
mir_build_variant_defined_here = not covered mir_build_variant_defined_here = not covered
mir_build_interpreted_as_const = introduce a variable instead mir_build_interpreted_as_const = introduce a variable instead
mir_build_confused = missing patterns are not covered because `{$variable}` is interpreted as {$article} {$res} pattern, not a new variable mir_build_confused = missing patterns are not covered because `{$variable}` is interpreted as a constant pattern, not a new variable
mir_build_suggest_if_let = you might want to use `if let` to ignore the {$count -> mir_build_suggest_if_let = you might want to use `if let` to ignore the {$count ->
[one] variant that isn't [one] variant that isn't

View file

@ -115,6 +115,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
initializer: Some(initializer), initializer: Some(initializer),
lint_level, lint_level,
else_block: Some(else_block), else_block: Some(else_block),
span: _,
} => { } => {
// When lowering the statement `let <pat> = <expr> else { <else> };`, // When lowering the statement `let <pat> = <expr> else { <else> };`,
// the `<else>` block is nested in the parent scope enclosing this statement. // the `<else>` block is nested in the parent scope enclosing this statement.
@ -278,6 +279,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
initializer, initializer,
lint_level, lint_level,
else_block: None, else_block: None,
span: _,
} => { } => {
let ignores_expr_result = matches!(pattern.kind, PatKind::Wild); let ignores_expr_result = matches!(pattern.kind, PatKind::Wild);
this.block_context.push(BlockFrame::Statement { ignores_expr_result }); this.block_context.push(BlockFrame::Statement { ignores_expr_result });

View file

@ -58,6 +58,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
ty::WithOptConstParam { did, const_param_did: None } => { ty::WithOptConstParam { did, const_param_did: None } => {
tcx.ensure_with_value().thir_check_unsafety(did); tcx.ensure_with_value().thir_check_unsafety(did);
tcx.ensure_with_value().thir_abstract_const(did); tcx.ensure_with_value().thir_abstract_const(did);
tcx.ensure_with_value().check_match(did);
} }
} }

View file

@ -6,11 +6,11 @@ use rustc_errors::{
error_code, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, error_code, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
Handler, IntoDiagnostic, MultiSpan, SubdiagnosticMessage, Handler, IntoDiagnostic, MultiSpan, SubdiagnosticMessage,
}; };
use rustc_hir::def::Res;
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
use rustc_middle::thir::Pat; use rustc_middle::thir::Pat;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
use rustc_span::{symbol::Ident, Span}; use rustc_span::symbol::Symbol;
use rustc_span::Span;
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
#[diag(mir_build_unconditional_recursion)] #[diag(mir_build_unconditional_recursion)]
@ -534,18 +534,10 @@ pub struct TrailingIrrefutableLetPatterns {
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
#[diag(mir_build_bindings_with_variant_name, code = "E0170")] #[diag(mir_build_bindings_with_variant_name, code = "E0170")]
pub struct BindingsWithVariantName { pub struct BindingsWithVariantName {
#[suggestion(code = "{ty_path}::{ident}", applicability = "machine-applicable")] #[suggestion(code = "{ty_path}::{name}", applicability = "machine-applicable")]
pub suggestion: Option<Span>, pub suggestion: Option<Span>,
pub ty_path: String, pub ty_path: String,
pub ident: Ident, pub name: Symbol,
}
#[derive(LintDiagnostic)]
#[diag(mir_build_irrefutable_let_patterns_generic_let)]
#[note]
#[help]
pub struct IrrefutableLetPatternsGenericLet {
pub count: usize,
} }
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
@ -584,13 +576,12 @@ pub struct IrrefutableLetPatternsWhileLet {
#[diag(mir_build_borrow_of_moved_value)] #[diag(mir_build_borrow_of_moved_value)]
pub struct BorrowOfMovedValue<'tcx> { pub struct BorrowOfMovedValue<'tcx> {
#[primary_span] #[primary_span]
pub span: Span,
#[label] #[label]
#[label(mir_build_occurs_because_label)] #[label(mir_build_occurs_because_label)]
pub binding_span: Span, pub binding_span: Span,
#[label(mir_build_value_borrowed_label)] #[label(mir_build_value_borrowed_label)]
pub conflicts_ref: Vec<Span>, pub conflicts_ref: Vec<Span>,
pub name: Ident, pub name: Symbol,
pub ty: Ty<'tcx>, pub ty: Ty<'tcx>,
#[suggestion(code = "ref ", applicability = "machine-applicable")] #[suggestion(code = "ref ", applicability = "machine-applicable")]
pub suggest_borrowing: Option<Span>, pub suggest_borrowing: Option<Span>,
@ -638,19 +629,19 @@ pub enum Conflict {
Mut { Mut {
#[primary_span] #[primary_span]
span: Span, span: Span,
name: Ident, name: Symbol,
}, },
#[label(mir_build_borrow)] #[label(mir_build_borrow)]
Ref { Ref {
#[primary_span] #[primary_span]
span: Span, span: Span,
name: Ident, name: Symbol,
}, },
#[label(mir_build_moved)] #[label(mir_build_moved)]
Moved { Moved {
#[primary_span] #[primary_span]
span: Span, span: Span,
name: Ident, name: Symbol,
}, },
} }
@ -802,8 +793,6 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> {
pub let_suggestion: Option<SuggestLet>, pub let_suggestion: Option<SuggestLet>,
#[subdiagnostic] #[subdiagnostic]
pub misc_suggestion: Option<MiscPatternSuggestion>, pub misc_suggestion: Option<MiscPatternSuggestion>,
#[subdiagnostic]
pub res_defined_here: Option<ResDefinedHere>,
} }
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]
@ -837,14 +826,6 @@ impl<'tcx> AddToDiagnostic for AdtDefinedHere<'tcx> {
} }
} }
#[derive(Subdiagnostic)]
#[label(mir_build_res_defined_here)]
pub struct ResDefinedHere {
#[primary_span]
pub def_span: Span,
pub res: Res,
}
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]
#[suggestion( #[suggestion(
mir_build_interpreted_as_const, mir_build_interpreted_as_const,
@ -855,9 +836,7 @@ pub struct ResDefinedHere {
pub struct InterpretedAsConst { pub struct InterpretedAsConst {
#[primary_span] #[primary_span]
pub span: Span, pub span: Span,
pub article: &'static str,
pub variable: String, pub variable: String,
pub res: Res,
} }
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]

View file

@ -105,6 +105,10 @@ impl<'tcx> Cx<'tcx> {
} }
} }
let span = match local.init {
Some(init) => local.span.with_hi(init.span.hi()),
None => local.span,
};
let stmt = Stmt { let stmt = Stmt {
kind: StmtKind::Let { kind: StmtKind::Let {
remainder_scope, remainder_scope,
@ -116,6 +120,7 @@ impl<'tcx> Cx<'tcx> {
initializer: local.init.map(|init| self.mirror_expr(init)), initializer: local.init.map(|init| self.mirror_expr(init)),
else_block, else_block,
lint_level: LintLevel::Explicit(local.hir_id), lint_level: LintLevel::Explicit(local.hir_id),
span,
}, },
opt_destruction_scope: opt_dxn_ext, opt_destruction_scope: opt_dxn_ext,
}; };

View file

@ -2,45 +2,48 @@ use super::deconstruct_pat::{Constructor, DeconstructedPat};
use super::usefulness::{ use super::usefulness::{
compute_match_usefulness, MatchArm, MatchCheckCtxt, Reachability, UsefulnessReport, compute_match_usefulness, MatchArm, MatchCheckCtxt, Reachability, UsefulnessReport,
}; };
use super::{PatCtxt, PatternError};
use crate::errors::*; use crate::errors::*;
use hir::{ExprKind, PatKind};
use rustc_arena::TypedArena; use rustc_arena::TypedArena;
use rustc_ast::{LitKind, Mutability}; use rustc_ast::Mutability;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{ use rustc_errors::{
struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::*; use rustc_hir::def::*;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::HirId;
use rustc_hir::{HirId, Pat}; use rustc_middle::thir::visit::{self, Visitor};
use rustc_middle::thir::*;
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
use rustc_session::lint::builtin::{ use rustc_session::lint::builtin::{
BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS, BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS,
}; };
use rustc_session::Session; use rustc_session::Session;
use rustc_span::source_map::Spanned; use rustc_span::hygiene::DesugaringKind;
use rustc_span::{BytePos, Span}; use rustc_span::Span;
pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
let body_id = match def_id.as_local() {
None => return,
Some(def_id) => tcx.hir().body_owned_by(def_id),
};
pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let Ok((thir, expr)) = tcx.thir_body(ty::WithOptConstParam::unknown(def_id)) else { return };
let thir = thir.borrow();
let pattern_arena = TypedArena::default(); let pattern_arena = TypedArena::default();
let mut visitor = MatchVisitor { let mut visitor = MatchVisitor {
tcx, tcx,
typeck_results: tcx.typeck_body(body_id), thir: &*thir,
param_env: tcx.param_env(def_id), 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, 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( fn create_e0004(
@ -58,77 +61,132 @@ enum RefutableFlag {
} }
use RefutableFlag::*; use RefutableFlag::*;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum LetSource {
None,
IfLet,
IfLetGuard,
LetElse,
WhileLet,
}
struct MatchVisitor<'a, 'p, 'tcx> { struct MatchVisitor<'a, 'p, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
typeck_results: &'a ty::TypeckResults<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
thir: &'a Thir<'tcx>,
lint_level: HirId,
let_source: LetSource,
pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>, pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
} }
impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, '_, 'tcx> { impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> {
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { fn thir(&self) -> &'a Thir<'tcx> {
intravisit::walk_expr(self, ex); self.thir
match &ex.kind { }
hir::ExprKind::Match(scrut, arms, source) => {
self.check_match(scrut, arms, *source, ex.span) #[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, lhs, rhs } => {
self.check_let_chain(self.let_source, ex.span, lhs, rhs);
}
_ => {}
};
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)
} }
_ => {} _ => {}
} }
} visit::walk_stmt(self, stmt);
self.lint_level = old_lint_level;
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(&param.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 });
}
}
}
} }
} }
impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { 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)); pat.walk_always(|pat| check_borrow_conflicts_in_at_patterns(self, pat));
check_for_bindings_named_same_as_variants(self, pat, rf); check_for_bindings_named_same_as_variants(self, pat, rf);
} }
@ -136,73 +194,63 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
fn lower_pattern( fn lower_pattern(
&self, &self,
cx: &mut MatchCheckCtxt<'p, 'tcx>, cx: &mut MatchCheckCtxt<'p, 'tcx>,
pat: &'tcx hir::Pat<'tcx>, pattern: &Pat<'tcx>,
have_errors: &mut bool,
) -> &'p DeconstructedPat<'p, 'tcx> { ) -> &'p DeconstructedPat<'p, 'tcx> {
let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.typeck_results); cx.pattern_arena.alloc(DeconstructedPat::from_pat(cx, &pattern))
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
} }
fn new_cx(&self, hir_id: HirId) -> MatchCheckCtxt<'p, 'tcx> { fn new_cx(&self, hir_id: HirId, refutable: bool) -> MatchCheckCtxt<'p, 'tcx> {
MatchCheckCtxt { MatchCheckCtxt {
tcx: self.tcx, tcx: self.tcx,
param_env: self.param_env, param_env: self.param_env,
module: self.tcx.parent_module(hir_id).to_def_id(), module: self.tcx.parent_module(hir_id).to_def_id(),
pattern_arena: &self.pattern_arena, pattern_arena: &self.pattern_arena,
refutable,
} }
} }
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); self.check_patterns(pat, Refutable);
let mut cx = self.new_cx(scrutinee.hir_id); let mut cx = self.new_cx(self.lint_level, true);
let tpat = self.lower_pattern(&mut cx, pat, &mut false); let tpat = self.lower_pattern(&mut cx, pat);
self.check_let_reachability(&mut cx, pat.hir_id, tpat, span); self.check_let_reachability(&mut cx, self.lint_level, source, tpat, span);
} }
fn check_match( fn check_match(
&mut self, &mut self,
scrut: &hir::Expr<'_>, scrut: ExprId,
hir_arms: &'tcx [hir::Arm<'tcx>], arms: &[ArmId],
source: hir::MatchSource, source: hir::MatchSource,
expr_span: Span, expr_span: Span,
) { ) {
let mut cx = self.new_cx(scrut.hir_id); let mut cx = self.new_cx(self.lint_level, true);
for arm in hir_arms { for &arm in arms {
// Check the arm for some things unrelated to exhaustiveness. // Check the arm for some things unrelated to exhaustiveness.
self.check_patterns(&arm.pat, Refutable); let arm = &self.thir.arms[arm];
if let Some(hir::Guard::IfLet(ref let_expr)) = arm.guard { self.check_patterns(&arm.pattern, Refutable);
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 mut have_errors = false; let tarms: Vec<_> = arms
let arms: Vec<_> = hir_arms
.iter() .iter()
.map(|hir::Arm { pat, guard, .. }| MatchArm { .map(|&arm| {
pat: self.lower_pattern(&mut cx, pat, &mut have_errors), let arm = &self.thir.arms[arm];
hir_id: pat.hir_id, let hir_id = match arm.lint_level {
has_guard: guard.is_some(), 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(); .collect();
// Bail out early if lowering failed. let scrut = &self.thir[scrut];
if have_errors { let scrut_ty = scrut.ty;
return; let report = compute_match_usefulness(&cx, &tarms, self.lint_level, scrut_ty);
}
let scrut_ty = self.typeck_results.expr_ty_adjusted(scrut);
let report = compute_match_usefulness(&cx, &arms, scrut.hir_id, scrut_ty);
match source { match source {
// Don't report arm reachability of desugared `match $iter.into_iter() { iter => .. }` // Don't report arm reachability of desugared `match $iter.into_iter() { iter => .. }`
@ -219,12 +267,18 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
// Check if the match is exhaustive. // Check if the match is exhaustive.
let witnesses = report.non_exhaustiveness_witnesses; let witnesses = report.non_exhaustiveness_witnesses;
if !witnesses.is_empty() { 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 // the for loop pattern is not irrefutable
let pat = hir_arms[1].pat.for_loop_some().unwrap(); let pat = &self.thir[arms[1]].pattern;
self.check_irrefutable(pat, "`for` loop binding", None); // `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 { } 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,
);
} }
} }
} }
@ -233,114 +287,96 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
&mut self, &mut self,
cx: &mut MatchCheckCtxt<'p, 'tcx>, cx: &mut MatchCheckCtxt<'p, 'tcx>,
pat_id: HirId, pat_id: HirId,
source: LetSource,
pat: &'p DeconstructedPat<'p, 'tcx>, pat: &'p DeconstructedPat<'p, 'tcx>,
span: Span, 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,
let_source: LetSource,
top_expr_span: Span,
mut lhs: ExprId,
rhs: ExprId,
) {
if let LetSource::None = let_source {
return; return;
} }
if is_let_irrefutable(cx, pat_id, pat) { // Lint level enclosing the next `lhs`.
irrefutable_let_pattern(cx.tcx, pat_id, span); let mut cur_lint_level = self.lint_level;
}
}
fn check_let_chain(&mut self, cx: &mut MatchCheckCtxt<'p, 'tcx>, pat_id: HirId) -> bool { // Obtain the refutabilities of all exprs in the chain,
let hir = self.tcx.hir();
let parent = hir.parent_id(pat_id);
// 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,
// and record chain members that aren't let exprs. // and record chain members that aren't let exprs.
let mut chain_refutabilities = Vec::new(); 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); let add = |expr: ExprId, mut local_lint_level| {
Some((*span, refutable)) // `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, true);
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, _ => None,
}
}; };
chain_refutabilities.push(refutability);
}; // Let chains recurse on the left, so we start by adding the rightmost.
if let hir::Expr { chain_refutabilities.push(add(rhs, cur_lint_level));
kind: hir::ExprKind::Binary(Spanned { node: hir::BinOpKind::And, .. }, lhs, rhs),
.. loop {
} = cur_expr 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); chain_refutabilities.push(add(expr, cur_lint_level));
cur_expr = lhs; lhs = new_lhs;
} else { } else {
add(cur_expr); chain_refutabilities.push(add(lhs, cur_lint_level));
break; break;
} }
} }
debug!(?chain_refutabilities);
chain_refutabilities.reverse(); chain_refutabilities.reverse();
// Third, emit the actual warnings. // Third, emit the actual warnings.
if chain_refutabilities.iter().all(|r| matches!(*r, Some((_, false)))) { if chain_refutabilities.iter().all(|r| matches!(*r, Some((_, false)))) {
// The entire chain is made up of irrefutable `let` statements // The entire chain is made up of irrefutable `let` statements
let let_source = let_source_parent(self.tcx, top, None);
irrefutable_let_patterns( irrefutable_let_patterns(
cx.tcx, self.tcx,
top, self.lint_level,
let_source, let_source,
chain_refutabilities.len(), chain_refutabilities.len(),
top_expr.span, top_expr_span,
); );
return true; return;
} }
if let Some(until) = chain_refutabilities.iter().position(|r| !matches!(*r, Some((_, false)))) && until > 0 { 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. // The chain has a non-zero prefix of irrefutable `let` statements.
@ -350,7 +386,6 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
// so can't always be moved out. // so can't always be moved out.
// FIXME: Add checking whether the bindings are actually used in the prefix, // FIXME: Add checking whether the bindings are actually used in the prefix,
// and lint if they are not. // and lint if they are not.
let let_source = let_source_parent(self.tcx, top, None);
if !matches!(let_source, LetSource::WhileLet | LetSource::IfLetGuard) { if !matches!(let_source, LetSource::WhileLet | LetSource::IfLetGuard) {
// Emit the lint // Emit the lint
let prefix = &chain_refutabilities[..until]; let prefix = &chain_refutabilities[..until];
@ -358,9 +393,10 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
let span_end = prefix.last().unwrap().unwrap().0; let span_end = prefix.last().unwrap().unwrap().0;
let span = span_start.to(span_end); let span = span_start.to(span_end);
let count = prefix.len(); 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) { 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 // The chain has a non-empty suffix of irrefutable `let` statements
let suffix = &chain_refutabilities[from + 1..]; let suffix = &chain_refutabilities[from + 1..];
@ -368,18 +404,18 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
let span_end = suffix.last().unwrap().unwrap().0; let span_end = suffix.last().unwrap().unwrap().0;
let span = span_start.to(span_end); let span = span_start.to(span_end);
let count = suffix.len(); 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>) { #[instrument(level = "trace", skip(self))]
let mut cx = self.new_cx(pat.hir_id); fn check_irrefutable(&self, pat: &Pat<'tcx>, origin: &str, sp: Option<Span>) {
let mut cx = self.new_cx(self.lint_level, false);
let pattern = self.lower_pattern(&mut cx, pat, &mut false); let pattern = self.lower_pattern(&mut cx, pat);
let pattern_ty = pattern.ty(); let pattern_ty = pattern.ty();
let arm = MatchArm { pat: pattern, hir_id: pat.hir_id, has_guard: false }; let arm = MatchArm { pat: pattern, hir_id: self.lint_level, has_guard: false };
let report = compute_match_usefulness(&cx, &[arm], pat.hir_id, pattern_ty); 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 // Note: we ignore whether the pattern is unreachable (i.e. whether the type is empty). We
// only care about exhaustiveness here. // only care about exhaustiveness here.
@ -390,57 +426,44 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
return; return;
} }
let (inform, interpreted_as_const, res_defined_here,let_suggestion, misc_suggestion) = let inform = sp.is_some().then_some(Inform);
if let hir::PatKind::Path(hir::QPath::Resolved( let mut let_suggestion = None;
None, let mut misc_suggestion = None;
hir::Path { let mut interpreted_as_const = None;
segments: &[hir::PathSegment { args: None, res, ident, .. }], if let PatKind::Constant { .. } = pat.kind
.. && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span)
},
)) = &pat.kind
{ {
( // If the pattern to match is an integer literal:
None, if snippet.chars().all(|c| c.is_digit(10)) {
Some(InterpretedAsConst { // Then give a suggestion, the user might've meant to create a binding instead.
span: pat.span, misc_suggestion = Some(MiscPatternSuggestion::AttemptedIntegerLiteral {
article: res.article(), start_span: pat.span.shrink_to_lo()
variable: ident.to_string().to_lowercase(),
res,
}),
try {
ResDefinedHere {
def_span: cx.tcx.hir().res_span(res)?,
res,
}
},
None,
None,
)
} else if let Some(span) = sp && self.tcx.sess.source_map().is_span_accessible(span) {
let mut bindings = vec![];
pat.walk_always(&mut |pat: &hir::Pat<'_>| {
if let hir::PatKind::Binding(_, _, ident, _) = pat.kind {
bindings.push(ident);
}
}); });
let semi_span = span.shrink_to_hi().with_lo(span.hi() - BytePos(1)); } else if snippet.chars().all(|c| c.is_alphanumeric() || c == '_') {
interpreted_as_const = Some(InterpretedAsConst {
span: pat.span,
variable: snippet,
});
}
}
if let Some(span) = sp
&& self.tcx.sess.source_map().is_span_accessible(span)
&& interpreted_as_const.is_none()
{
let mut bindings = vec![];
pat.each_binding(|name, _, _, _| bindings.push(name));
let semi_span = span.shrink_to_hi();
let start_span = span.shrink_to_lo(); let start_span = span.shrink_to_lo();
let end_span = semi_span.shrink_to_lo(); let end_span = semi_span.shrink_to_lo();
let count = witnesses.len(); let count = witnesses.len();
// If the pattern to match is an integer literal: let_suggestion = Some(if bindings.is_empty() {
let int_suggestion = if SuggestLet::If { start_span, semi_span, count }
let PatKind::Lit(expr) = &pat.kind
&& bindings.is_empty()
&& let ExprKind::Lit(Spanned { node: LitKind::Int(_, _), span }) = expr.kind {
// 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 };
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)
} else { } else {
(sp.map(|_|Inform), None, None, None, None) SuggestLet::Else { end_span, count }
});
}; };
let adt_defined_here = try { let adt_defined_here = try {
@ -465,7 +488,6 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
pattern_ty, pattern_ty,
let_suggestion, let_suggestion,
misc_suggestion, misc_suggestion,
res_defined_here,
adt_defined_here, adt_defined_here,
}); });
} }
@ -477,14 +499,18 @@ fn check_for_bindings_named_same_as_variants(
rf: RefutableFlag, rf: RefutableFlag,
) { ) {
pat.walk_always(|p| { pat.walk_always(|p| {
if let hir::PatKind::Binding(_, _, ident, None) = p.kind if let PatKind::Binding {
&& let Some(ty::BindByValue(hir::Mutability::Not)) = name,
cx.typeck_results.extract_binding_mode(cx.tcx.sess, p.hir_id, p.span) mode: BindingMode::ByValue,
&& let pat_ty = cx.typeck_results.pat_ty(p).peel_refs() mutability: Mutability::Not,
&& let ty::Adt(edef, _) = pat_ty.kind() subpattern: None,
ty,
..
} = p.kind
&& let ty::Adt(edef, _) = ty.peel_refs().kind()
&& edef.is_enum() && edef.is_enum()
&& edef.variants().iter().any(|variant| { && 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(); let variant_count = edef.variants().len();
@ -493,7 +519,7 @@ fn check_for_bindings_named_same_as_variants(
}); });
cx.tcx.emit_spanned_lint( cx.tcx.emit_spanned_lint(
BINDINGS_WITH_VARIANT_NAME, BINDINGS_WITH_VARIANT_NAME,
p.hir_id, cx.lint_level,
p.span, p.span,
BindingsWithVariantName { BindingsWithVariantName {
// If this is an irrefutable pattern, and there's > 1 variant, // If this is an irrefutable pattern, and there's > 1 variant,
@ -503,7 +529,7 @@ fn check_for_bindings_named_same_as_variants(
Some(p.span) Some(p.span)
} else { None }, } else { None },
ty_path, ty_path,
ident, name,
}, },
) )
} }
@ -529,11 +555,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( fn irrefutable_let_patterns(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
id: HirId, id: HirId,
@ -548,7 +569,7 @@ fn irrefutable_let_patterns(
} }
match source { match source {
LetSource::GenericLet => emit_diag!(IrrefutableLetPatternsGenericLet), LetSource::None => bug!(),
LetSource::IfLet => emit_diag!(IrrefutableLetPatternsIfLet), LetSource::IfLet => emit_diag!(IrrefutableLetPatternsIfLet),
LetSource::IfLetGuard => emit_diag!(IrrefutableLetPatternsIfLetGuard), LetSource::IfLetGuard => emit_diag!(IrrefutableLetPatternsIfLetGuard),
LetSource::LetElse => emit_diag!(IrrefutableLetPatternsLetElse), LetSource::LetElse => emit_diag!(IrrefutableLetPatternsLetElse),
@ -604,10 +625,11 @@ fn report_arm_reachability<'p, 'tcx>(
/// Report that a match is not exhaustive. /// Report that a match is not exhaustive.
fn non_exhaustive_match<'p, 'tcx>( fn non_exhaustive_match<'p, 'tcx>(
cx: &MatchCheckCtxt<'p, 'tcx>, cx: &MatchCheckCtxt<'p, 'tcx>,
thir: &Thir<'tcx>,
scrut_ty: Ty<'tcx>, scrut_ty: Ty<'tcx>,
sp: Span, sp: Span,
witnesses: Vec<DeconstructedPat<'p, 'tcx>>, witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
arms: &[hir::Arm<'tcx>], arms: &[ArmId],
expr_span: Span, expr_span: Span,
) { ) {
let is_empty_match = arms.is_empty(); let is_empty_match = arms.is_empty();
@ -705,6 +727,7 @@ fn non_exhaustive_match<'p, 'tcx>(
)); ));
} }
[only] => { [only] => {
let only = &thir[*only];
let (pre_indentation, is_multiline) = if let Some(snippet) = sm.indentation_before(only.span) 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 == ',') && let Ok(with_trailing) = sm.span_extend_while(only.span, |c| c.is_whitespace() || c == ',')
&& sm.is_multiline(with_trailing) && sm.is_multiline(with_trailing)
@ -713,8 +736,9 @@ fn non_exhaustive_match<'p, 'tcx>(
} else { } else {
(" ".to_string(), false) (" ".to_string(), false)
}; };
let comma = if matches!(only.body.kind, hir::ExprKind::Block(..)) let only_body = &thir[only.body];
&& only.span.eq_ctxt(only.body.span) let comma = if matches!(only_body.kind, ExprKind::Block { .. })
&& only.span.eq_ctxt(only_body.span)
&& is_multiline && is_multiline
{ {
"" ""
@ -726,9 +750,13 @@ fn non_exhaustive_match<'p, 'tcx>(
format!("{}{}{} => todo!()", comma, pre_indentation, pattern), format!("{}{}{} => todo!()", comma, pre_indentation, pattern),
)); ));
} }
[.., prev, last] if prev.span.eq_ctxt(last.span) => { [.., prev, last] => {
let comma = if matches!(last.body.kind, hir::ExprKind::Block(..)) let prev = &thir[*prev];
&& last.span.eq_ctxt(last.body.span) 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 { } else {
@ -746,6 +774,7 @@ fn non_exhaustive_match<'p, 'tcx>(
)); ));
} }
} }
}
_ => {} _ => {}
} }
@ -863,10 +892,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`. /// 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. /// Check that there are no borrow or move conflicts in `binding @ subpat` patterns.
/// ///
/// For example, this would reject: /// For example, this would reject:
@ -877,45 +902,36 @@ fn is_binding_by_move(cx: &MatchVisitor<'_, '_, '_>, hir_id: HirId) -> bool {
/// - `x @ Some(ref mut? y)`. /// - `x @ Some(ref mut? y)`.
/// ///
/// This analysis is *not* subsumed by NLL. /// 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`. // Extract `sub` in `binding @ sub`.
let (name, sub) = match &pat.kind { let PatKind::Binding { name, mode, ty, subpattern: Some(box ref sub), .. } = pat.kind else { return };
hir::PatKind::Binding(.., name, Some(sub)) => (*name, sub),
_ => return, let is_binding_by_move = |ty: Ty<'tcx>| !ty.is_copy_modulo_regions(cx.tcx, cx.param_env);
};
let binding_span = pat.span.with_hi(name.span.hi());
let typeck_results = cx.typeck_results;
let sess = cx.tcx.sess; let sess = cx.tcx.sess;
// Get the binding move, extract the mutability if by-ref. // Get the binding move, extract the mutability if by-ref.
let mut_outer = match typeck_results.extract_binding_mode(sess, pat.hir_id, pat.span) { let mut_outer = match mode {
Some(ty::BindByValue(_)) if is_binding_by_move(cx, pat.hir_id) => { BindingMode::ByValue if is_binding_by_move(ty) => {
// We have `x @ pat` where `x` is by-move. Reject all borrows in `pat`. // We have `x @ pat` where `x` is by-move. Reject all borrows in `pat`.
let mut conflicts_ref = Vec::new(); let mut conflicts_ref = Vec::new();
sub.each_binding(|_, hir_id, span, _| { sub.each_binding(|_, mode, _, span| match mode {
match typeck_results.extract_binding_mode(sess, hir_id, span) { BindingMode::ByValue => {}
Some(ty::BindByValue(_)) | None => {} BindingMode::ByRef(_) => conflicts_ref.push(span),
Some(ty::BindByReference(_)) => conflicts_ref.push(span),
}
}); });
if !conflicts_ref.is_empty() { if !conflicts_ref.is_empty() {
sess.emit_err(BorrowOfMovedValue { sess.emit_err(BorrowOfMovedValue {
span: pat.span, binding_span: pat.span,
binding_span,
conflicts_ref, conflicts_ref,
name, name,
ty: typeck_results.node_type(pat.hir_id), ty,
suggest_borrowing: pat suggest_borrowing: Some(pat.span.shrink_to_lo()),
.span
.contains(binding_span)
.then(|| binding_span.shrink_to_lo()),
}); });
} }
return; return;
} }
Some(ty::BindByValue(_)) | None => return, BindingMode::ByValue => return,
Some(ty::BindByReference(m)) => m, BindingMode::ByRef(m) => m.mutability(),
}; };
// We now have `ref $mut_outer binding @ sub` (semantically). // We now have `ref $mut_outer binding @ sub` (semantically).
@ -923,9 +939,9 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
let mut conflicts_move = Vec::new(); let mut conflicts_move = Vec::new();
let mut conflicts_mut_mut = Vec::new(); let mut conflicts_mut_mut = Vec::new();
let mut conflicts_mut_ref = Vec::new(); let mut conflicts_mut_ref = Vec::new();
sub.each_binding(|_, hir_id, span, name| { sub.each_binding(|name, mode, ty, span| {
match typeck_results.extract_binding_mode(sess, hir_id, span) { match mode {
Some(ty::BindByReference(mut_inner)) => match (mut_outer, mut_inner) { BindingMode::ByRef(mut_inner) => match (mut_outer, mut_inner.mutability()) {
// Both sides are `ref`. // Both sides are `ref`.
(Mutability::Not, Mutability::Not) => {} (Mutability::Not, Mutability::Not) => {}
// 2x `ref mut`. // 2x `ref mut`.
@ -939,10 +955,10 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
conflicts_mut_ref.push(Conflict::Ref { span, name }) 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. 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.
} }
}); });
@ -951,8 +967,8 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
let report_move_conflict = !conflicts_move.is_empty(); let report_move_conflict = !conflicts_move.is_empty();
let mut occurences = match mut_outer { let mut occurences = match mut_outer {
Mutability::Mut => vec![Conflict::Mut { span: binding_span, name }], Mutability::Mut => vec![Conflict::Mut { span: pat.span, name }],
Mutability::Not => vec![Conflict::Ref { span: binding_span, name }], Mutability::Not => vec![Conflict::Ref { span: pat.span, name }],
}; };
occurences.extend(conflicts_mut_mut); occurences.extend(conflicts_mut_mut);
occurences.extend(conflicts_mut_ref); occurences.extend(conflicts_mut_ref);
@ -977,65 +993,3 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
sess.emit_err(MovedWhileBorrowed { span: pat.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
}

View file

@ -59,8 +59,6 @@ struct ConstToPat<'tcx> {
// inference context used for checking `T: Structural` bounds. // inference context used for checking `T: Structural` bounds.
infcx: InferCtxt<'tcx>, infcx: InferCtxt<'tcx>,
include_lint_checks: bool,
treat_byte_string_as_slice: bool, treat_byte_string_as_slice: bool,
} }
@ -93,7 +91,6 @@ impl<'tcx> ConstToPat<'tcx> {
span, span,
infcx, infcx,
param_env: pat_ctxt.param_env, param_env: pat_ctxt.param_env,
include_lint_checks: pat_ctxt.include_lint_checks,
saw_const_match_error: Cell::new(false), saw_const_match_error: Cell::new(false),
saw_const_match_lint: Cell::new(false), saw_const_match_lint: Cell::new(false),
behind_reference: Cell::new(false), behind_reference: Cell::new(false),
@ -134,7 +131,7 @@ impl<'tcx> ConstToPat<'tcx> {
}) })
}); });
if self.include_lint_checks && !self.saw_const_match_error.get() { if !self.saw_const_match_error.get() {
// If we were able to successfully convert the const to some pat, // If we were able to successfully convert the const to some pat,
// double-check that all types in the const implement `Structural`. // double-check that all types in the const implement `Structural`.
@ -239,21 +236,19 @@ impl<'tcx> ConstToPat<'tcx> {
let kind = match cv.ty().kind() { let kind = match cv.ty().kind() {
ty::Float(_) => { ty::Float(_) => {
if self.include_lint_checks {
tcx.emit_spanned_lint( tcx.emit_spanned_lint(
lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
id, id,
span, span,
FloatPattern, FloatPattern,
); );
}
PatKind::Constant { value: cv } PatKind::Constant { value: cv }
} }
ty::Adt(adt_def, _) if adt_def.is_union() => { ty::Adt(adt_def, _) if adt_def.is_union() => {
// Matching on union fields is unsafe, we can't hide it in constants // Matching on union fields is unsafe, we can't hide it in constants
self.saw_const_match_error.set(true); self.saw_const_match_error.set(true);
let err = UnionPattern { span }; let err = UnionPattern { span };
tcx.sess.create_err(err).emit_unless(!self.include_lint_checks); tcx.sess.emit_err(err);
PatKind::Wild PatKind::Wild
} }
ty::Adt(..) ty::Adt(..)
@ -267,7 +262,7 @@ impl<'tcx> ConstToPat<'tcx> {
{ {
self.saw_const_match_error.set(true); self.saw_const_match_error.set(true);
let err = TypeNotStructural { span, non_sm_ty }; let err = TypeNotStructural { span, non_sm_ty };
tcx.sess.create_err(err).emit_unless(!self.include_lint_checks); tcx.sess.emit_err(err);
PatKind::Wild PatKind::Wild
} }
// If the type is not structurally comparable, just emit the constant directly, // If the type is not structurally comparable, just emit the constant directly,
@ -280,8 +275,7 @@ impl<'tcx> ConstToPat<'tcx> {
// Backwards compatibility hack because we can't cause hard errors on these // Backwards compatibility hack because we can't cause hard errors on these
// types, so we compare them via `PartialEq::eq` at runtime. // types, so we compare them via `PartialEq::eq` at runtime.
ty::Adt(..) if !self.type_marked_structural(cv.ty()) && self.behind_reference.get() => { ty::Adt(..) if !self.type_marked_structural(cv.ty()) && self.behind_reference.get() => {
if self.include_lint_checks if !self.saw_const_match_error.get()
&& !self.saw_const_match_error.get()
&& !self.saw_const_match_lint.get() && !self.saw_const_match_lint.get()
{ {
self.saw_const_match_lint.set(true); self.saw_const_match_lint.set(true);
@ -305,7 +299,7 @@ impl<'tcx> ConstToPat<'tcx> {
); );
self.saw_const_match_error.set(true); self.saw_const_match_error.set(true);
let err = TypeNotStructural { span, non_sm_ty: cv.ty() }; let err = TypeNotStructural { span, non_sm_ty: cv.ty() };
tcx.sess.create_err(err).emit_unless(!self.include_lint_checks); tcx.sess.emit_err(err);
PatKind::Wild PatKind::Wild
} }
ty::Adt(adt_def, substs) if adt_def.is_enum() => { ty::Adt(adt_def, substs) if adt_def.is_enum() => {
@ -339,7 +333,7 @@ impl<'tcx> ConstToPat<'tcx> {
ty::Dynamic(..) => { ty::Dynamic(..) => {
self.saw_const_match_error.set(true); self.saw_const_match_error.set(true);
let err = InvalidPattern { span, non_sm_ty: cv.ty() }; let err = InvalidPattern { span, non_sm_ty: cv.ty() };
tcx.sess.create_err(err).emit_unless(!self.include_lint_checks); tcx.sess.emit_err(err);
PatKind::Wild PatKind::Wild
} }
// `&str` is represented as `ConstValue::Slice`, let's keep using this // `&str` is represented as `ConstValue::Slice`, let's keep using this
@ -406,8 +400,7 @@ impl<'tcx> ConstToPat<'tcx> {
// to figure out how to get a reference again. // to figure out how to get a reference again.
ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => { ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => {
if self.behind_reference.get() { if self.behind_reference.get() {
if self.include_lint_checks if !self.saw_const_match_error.get()
&& !self.saw_const_match_error.get()
&& !self.saw_const_match_lint.get() && !self.saw_const_match_lint.get()
{ {
self.saw_const_match_lint.set(true); self.saw_const_match_lint.set(true);
@ -423,7 +416,7 @@ impl<'tcx> ConstToPat<'tcx> {
if !self.saw_const_match_error.get() { if !self.saw_const_match_error.get() {
self.saw_const_match_error.set(true); self.saw_const_match_error.set(true);
let err = TypeNotStructural { span, non_sm_ty: *pointee_ty }; let err = TypeNotStructural { span, non_sm_ty: *pointee_ty };
tcx.sess.create_err(err).emit_unless(!self.include_lint_checks); tcx.sess.emit_err(err);
} }
PatKind::Wild PatKind::Wild
} }
@ -437,7 +430,7 @@ impl<'tcx> ConstToPat<'tcx> {
// (except slices, which are handled in a separate arm above). // (except slices, which are handled in a separate arm above).
let err = UnsizedPattern { span, non_sm_ty: *pointee_ty }; let err = UnsizedPattern { span, non_sm_ty: *pointee_ty };
tcx.sess.create_err(err).emit_unless(!self.include_lint_checks); tcx.sess.emit_err(err);
PatKind::Wild PatKind::Wild
} else { } else {
@ -465,8 +458,7 @@ impl<'tcx> ConstToPat<'tcx> {
// compilation choices change the runtime behaviour of the match. // compilation choices change the runtime behaviour of the match.
// See https://github.com/rust-lang/rust/issues/70861 for examples. // See https://github.com/rust-lang/rust/issues/70861 for examples.
ty::FnPtr(..) | ty::RawPtr(..) => { ty::FnPtr(..) | ty::RawPtr(..) => {
if self.include_lint_checks if !self.saw_const_match_error.get()
&& !self.saw_const_match_error.get()
&& !self.saw_const_match_lint.get() && !self.saw_const_match_lint.get()
{ {
self.saw_const_match_lint.set(true); self.saw_const_match_lint.set(true);
@ -482,13 +474,12 @@ impl<'tcx> ConstToPat<'tcx> {
_ => { _ => {
self.saw_const_match_error.set(true); self.saw_const_match_error.set(true);
let err = InvalidPattern { span, non_sm_ty: cv.ty() }; let err = InvalidPattern { span, non_sm_ty: cv.ty() };
tcx.sess.create_err(err).emit_unless(!self.include_lint_checks); tcx.sess.emit_err(err);
PatKind::Wild PatKind::Wild
} }
}; };
if self.include_lint_checks if !self.saw_const_match_error.get()
&& !self.saw_const_match_error.get()
&& !self.saw_const_match_lint.get() && !self.saw_const_match_lint.get()
&& mir_structural_match_violation && mir_structural_match_violation
// FIXME(#73448): Find a way to bring const qualification into parity with // FIXME(#73448): Find a way to bring const qualification into parity with

View file

@ -258,7 +258,7 @@ impl IntRange {
pcx: &PatCtxt<'_, 'p, 'tcx>, pcx: &PatCtxt<'_, 'p, 'tcx>,
pats: impl Iterator<Item = &'a DeconstructedPat<'p, 'tcx>>, pats: impl Iterator<Item = &'a DeconstructedPat<'p, 'tcx>>,
column_count: usize, column_count: usize,
hir_id: HirId, lint_root: HirId,
) { ) {
if self.is_singleton() { if self.is_singleton() {
return; return;
@ -290,7 +290,7 @@ impl IntRange {
if !overlap.is_empty() { if !overlap.is_empty() {
pcx.cx.tcx.emit_spanned_lint( pcx.cx.tcx.emit_spanned_lint(
lint::builtin::OVERLAPPING_RANGE_ENDPOINTS, lint::builtin::OVERLAPPING_RANGE_ENDPOINTS,
hir_id, lint_root,
pcx.span, pcx.span,
OverlappingRangeEndpoints { overlap, range: pcx.span }, OverlappingRangeEndpoints { overlap, range: pcx.span },
); );

View file

@ -31,20 +31,10 @@ use rustc_target::abi::FieldIdx;
use std::cmp::Ordering; use std::cmp::Ordering;
#[derive(Clone, Debug)]
enum PatternError {
AssocConstInPattern(Span),
ConstParamInPattern(Span),
StaticInPattern(Span),
NonConstPath(Span),
}
struct PatCtxt<'a, 'tcx> { struct PatCtxt<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
typeck_results: &'a ty::TypeckResults<'tcx>, typeck_results: &'a ty::TypeckResults<'tcx>,
errors: Vec<PatternError>,
include_lint_checks: bool,
} }
pub(super) fn pat_from_hir<'a, 'tcx>( pub(super) fn pat_from_hir<'a, 'tcx>(
@ -53,30 +43,13 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
typeck_results: &'a ty::TypeckResults<'tcx>, typeck_results: &'a ty::TypeckResults<'tcx>,
pat: &'tcx hir::Pat<'tcx>, pat: &'tcx hir::Pat<'tcx>,
) -> Box<Pat<'tcx>> { ) -> Box<Pat<'tcx>> {
let mut pcx = PatCtxt::new(tcx, param_env, typeck_results); let mut pcx = PatCtxt { tcx, param_env, typeck_results };
let result = pcx.lower_pattern(pat); 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);
}
debug!("pat_from_hir({:?}) = {:?}", pat, result); debug!("pat_from_hir({:?}) = {:?}", pat, result);
result result
} }
impl<'a, 'tcx> PatCtxt<'a, 'tcx> { impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
fn new(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typeck_results: &'a ty::TypeckResults<'tcx>,
) -> Self {
PatCtxt { tcx, param_env, typeck_results, errors: vec![], include_lint_checks: false }
}
fn include_lint_checks(&mut self) -> &mut Self {
self.include_lint_checks = true;
self
}
fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> { 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 // 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: // pattern has the type that results *after* dereferencing. For example, in this code:
@ -473,12 +446,15 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
| Res::SelfTyAlias { .. } | Res::SelfTyAlias { .. }
| Res::SelfCtor(..) => PatKind::Leaf { subpatterns }, | Res::SelfCtor(..) => PatKind::Leaf { subpatterns },
_ => { _ => {
let pattern_error = match res { match res {
Res::Def(DefKind::ConstParam, _) => PatternError::ConstParamInPattern(span), Res::Def(DefKind::ConstParam, _) => {
Res::Def(DefKind::Static(_), _) => PatternError::StaticInPattern(span), self.tcx.sess.emit_err(ConstParamInPattern { span })
_ => PatternError::NonConstPath(span), }
Res::Def(DefKind::Static(_), _) => {
self.tcx.sess.emit_err(StaticInPattern { span })
}
_ => self.tcx.sess.emit_err(NonConstPath { span }),
}; };
self.errors.push(pattern_error);
PatKind::Wild PatKind::Wild
} }
}; };
@ -531,7 +507,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// It should be assoc consts if there's no error but we cannot resolve it. // It should be assoc consts if there's no error but we cannot resolve it.
debug_assert!(is_associated_const); debug_assert!(is_associated_const);
self.errors.push(PatternError::AssocConstInPattern(span)); self.tcx.sess.emit_err(AssocConstInPattern { span });
return pat_from_kind(PatKind::Wild); return pat_from_kind(PatKind::Wild);
} }
@ -609,7 +585,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
match value { match value {
mir::ConstantKind::Ty(c) => match c.kind() { mir::ConstantKind::Ty(c) => match c.kind() {
ConstKind::Param(_) => { ConstKind::Param(_) => {
self.errors.push(PatternError::ConstParamInPattern(span)); self.tcx.sess.emit_err(ConstParamInPattern { span });
return PatKind::Wild; return PatKind::Wild;
} }
ConstKind::Error(_) => { ConstKind::Error(_) => {

View file

@ -300,7 +300,6 @@ use rustc_arena::TypedArena;
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::HirId; use rustc_hir::HirId;
use rustc_hir::Node;
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
@ -319,6 +318,8 @@ pub(crate) struct MatchCheckCtxt<'p, 'tcx> {
pub(crate) module: DefId, pub(crate) module: DefId,
pub(crate) param_env: ty::ParamEnv<'tcx>, pub(crate) param_env: ty::ParamEnv<'tcx>,
pub(crate) pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>, pub(crate) pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
/// Only produce `NON_EXHAUSTIVE_OMITTED_PATTERNS` lint on refutable patterns.
pub(crate) refutable: bool,
} }
impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
@ -765,13 +766,13 @@ impl<'p, 'tcx> Witness<'p, 'tcx> {
/// `is_under_guard` is used to inform if the pattern has a guard. If it /// `is_under_guard` is used to inform if the pattern has a guard. If it
/// has one it must not be inserted into the matrix. This shouldn't be /// has one it must not be inserted into the matrix. This shouldn't be
/// relied on for soundness. /// relied on for soundness.
#[instrument(level = "debug", skip(cx, matrix, hir_id), ret)] #[instrument(level = "debug", skip(cx, matrix, lint_root), ret)]
fn is_useful<'p, 'tcx>( fn is_useful<'p, 'tcx>(
cx: &MatchCheckCtxt<'p, 'tcx>, cx: &MatchCheckCtxt<'p, 'tcx>,
matrix: &Matrix<'p, 'tcx>, matrix: &Matrix<'p, 'tcx>,
v: &PatStack<'p, 'tcx>, v: &PatStack<'p, 'tcx>,
witness_preference: ArmType, witness_preference: ArmType,
hir_id: HirId, lint_root: HirId,
is_under_guard: bool, is_under_guard: bool,
is_top_level: bool, is_top_level: bool,
) -> Usefulness<'p, 'tcx> { ) -> Usefulness<'p, 'tcx> {
@ -804,7 +805,7 @@ fn is_useful<'p, 'tcx>(
for v in v.expand_or_pat() { for v in v.expand_or_pat() {
debug!(?v); debug!(?v);
let usefulness = ensure_sufficient_stack(|| { let usefulness = ensure_sufficient_stack(|| {
is_useful(cx, &matrix, &v, witness_preference, hir_id, is_under_guard, false) is_useful(cx, &matrix, &v, witness_preference, lint_root, is_under_guard, false)
}); });
debug!(?usefulness); debug!(?usefulness);
ret.extend(usefulness); ret.extend(usefulness);
@ -837,7 +838,7 @@ fn is_useful<'p, 'tcx>(
pcx, pcx,
matrix.heads(), matrix.heads(),
matrix.column_count().unwrap_or(0), matrix.column_count().unwrap_or(0),
hir_id, lint_root,
) )
} }
// We split the head constructor of `v`. // We split the head constructor of `v`.
@ -852,7 +853,15 @@ fn is_useful<'p, 'tcx>(
let spec_matrix = start_matrix.specialize_constructor(pcx, &ctor); let spec_matrix = start_matrix.specialize_constructor(pcx, &ctor);
let v = v.pop_head_constructor(pcx, &ctor); let v = v.pop_head_constructor(pcx, &ctor);
let usefulness = ensure_sufficient_stack(|| { let usefulness = ensure_sufficient_stack(|| {
is_useful(cx, &spec_matrix, &v, witness_preference, hir_id, is_under_guard, false) is_useful(
cx,
&spec_matrix,
&v,
witness_preference,
lint_root,
is_under_guard,
false,
)
}); });
let usefulness = usefulness.apply_constructor(pcx, start_matrix, &ctor); let usefulness = usefulness.apply_constructor(pcx, start_matrix, &ctor);
@ -860,6 +869,8 @@ fn is_useful<'p, 'tcx>(
// that has the potential to trigger the `non_exhaustive_omitted_patterns` lint. // that has the potential to trigger the `non_exhaustive_omitted_patterns` lint.
// To understand the workings checkout `Constructor::split` and `SplitWildcard::new/into_ctors` // To understand the workings checkout `Constructor::split` and `SplitWildcard::new/into_ctors`
if is_non_exhaustive_and_wild if is_non_exhaustive_and_wild
// Only emit a lint on refutable patterns.
&& cx.refutable
// We check that the match has a wildcard pattern and that wildcard is useful, // We check that the match has a wildcard pattern and that wildcard is useful,
// meaning there are variants that are covered by the wildcard. Without the check // meaning there are variants that are covered by the wildcard. Without the check
// for `witness_preference` the lint would trigger on `if let NonExhaustiveEnum::A = foo {}` // for `witness_preference` the lint would trigger on `if let NonExhaustiveEnum::A = foo {}`
@ -868,8 +879,6 @@ fn is_useful<'p, 'tcx>(
&ctor, &ctor,
Constructor::Missing { nonexhaustive_enum_missing_real_variants: true } Constructor::Missing { nonexhaustive_enum_missing_real_variants: true }
) )
// We don't want to lint patterns which are function arguments or locals
&& !matches!(cx.tcx.hir().find_parent(hir_id), Some(Node::Param(_)|Node::Local(_)))
{ {
let patterns = { let patterns = {
let mut split_wildcard = SplitWildcard::new(pcx); let mut split_wildcard = SplitWildcard::new(pcx);
@ -896,7 +905,7 @@ fn is_useful<'p, 'tcx>(
// NB: The partner lint for structs lives in `compiler/rustc_hir_analysis/src/check/pat.rs`. // NB: The partner lint for structs lives in `compiler/rustc_hir_analysis/src/check/pat.rs`.
cx.tcx.emit_spanned_lint( cx.tcx.emit_spanned_lint(
NON_EXHAUSTIVE_OMITTED_PATTERNS, NON_EXHAUSTIVE_OMITTED_PATTERNS,
hir_id, lint_root,
pcx.span, pcx.span,
NonExhaustiveOmittedPattern { NonExhaustiveOmittedPattern {
scrut_ty: pcx.ty, scrut_ty: pcx.ty,
@ -954,7 +963,7 @@ pub(crate) struct UsefulnessReport<'p, 'tcx> {
pub(crate) fn compute_match_usefulness<'p, 'tcx>( pub(crate) fn compute_match_usefulness<'p, 'tcx>(
cx: &MatchCheckCtxt<'p, 'tcx>, cx: &MatchCheckCtxt<'p, 'tcx>,
arms: &[MatchArm<'p, 'tcx>], arms: &[MatchArm<'p, 'tcx>],
scrut_hir_id: HirId, lint_root: HirId,
scrut_ty: Ty<'tcx>, scrut_ty: Ty<'tcx>,
) -> UsefulnessReport<'p, 'tcx> { ) -> UsefulnessReport<'p, 'tcx> {
let mut matrix = Matrix::empty(); let mut matrix = Matrix::empty();
@ -979,7 +988,7 @@ pub(crate) fn compute_match_usefulness<'p, 'tcx>(
let wild_pattern = cx.pattern_arena.alloc(DeconstructedPat::wildcard(scrut_ty, DUMMY_SP)); let wild_pattern = cx.pattern_arena.alloc(DeconstructedPat::wildcard(scrut_ty, DUMMY_SP));
let v = PatStack::from_pattern(wild_pattern); let v = PatStack::from_pattern(wild_pattern);
let usefulness = is_useful(cx, &matrix, &v, FakeExtraWildcard, scrut_hir_id, false, true); let usefulness = is_useful(cx, &matrix, &v, FakeExtraWildcard, lint_root, false, true);
let non_exhaustiveness_witnesses = match usefulness { let non_exhaustiveness_witnesses = match usefulness {
WithWitnesses(pats) => pats.into_iter().map(|w| w.single_pattern()).collect(), WithWitnesses(pats) => pats.into_iter().map(|w| w.single_pattern()).collect(),
NoWitnesses { .. } => bug!(), NoWitnesses { .. } => bug!(),

View file

@ -151,6 +151,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
initializer, initializer,
else_block, else_block,
lint_level, lint_level,
span,
} => { } => {
print_indented!(self, "kind: Let {", depth_lvl + 1); print_indented!(self, "kind: Let {", depth_lvl + 1);
print_indented!( print_indented!(
@ -181,6 +182,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
} }
print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 2); print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 2);
print_indented!(self, format!("span: {:?}", span), depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1); print_indented!(self, "}", depth_lvl + 1);
} }
} }

View file

@ -7,10 +7,10 @@ promoted[0] in FOO: &[&i32; 1] = {
let mut _3: *const i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 let mut _3: *const i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43
bb0: { bb0: {
_3 = const {alloc3: *const i32}; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 _3 = const {alloc2: *const i32}; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43
// mir::Constant // mir::Constant
// + span: $DIR/const_promotion_extern_static.rs:13:42: 13:43 // + span: $DIR/const_promotion_extern_static.rs:13:42: 13:43
// + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) } // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) }
_2 = &(*_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:41: +0:43 _2 = &(*_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:41: +0:43
_1 = [move _2]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 _1 = [move _2]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46
_0 = &_1; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 _0 = &_1; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
@ -18,4 +18,4 @@ promoted[0] in FOO: &[&i32; 1] = {
} }
} }
alloc3 (extern static: X) alloc2 (extern static: X)

View file

@ -18,11 +18,11 @@
- StorageLive(_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 - StorageLive(_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46
- StorageLive(_4); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:45 - StorageLive(_4); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:45
- StorageLive(_5); // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 - StorageLive(_5); // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43
- _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 - _5 = const {alloc2: *const i32}; // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43
+ _6 = const _; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 + _6 = const _; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
// mir::Constant // mir::Constant
- // + span: $DIR/const_promotion_extern_static.rs:13:42: 13:43 - // + span: $DIR/const_promotion_extern_static.rs:13:42: 13:43
- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) } - // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) }
- _4 = &(*_5); // scope 1 at $DIR/const_promotion_extern_static.rs:+0:41: +0:43 - _4 = &(*_5); // scope 1 at $DIR/const_promotion_extern_static.rs:+0:41: +0:43
- _3 = [move _4]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 - _3 = [move _4]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46
- _2 = &_3; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 - _2 = &_3; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
@ -50,5 +50,5 @@
} }
} }
- -
- alloc3 (extern static: X) - alloc2 (extern static: X)

View file

@ -2,18 +2,16 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:36:9 --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:36:9
| |
LL | ref foo @ [.., ref mut bar] => (), LL | ref foo @ [.., ref mut bar] => (),
| -------^^^^^^^^-----------^ | ^^^^^^^ ----------- value is mutably borrowed by `bar` here
| | | | |
| | value is mutably borrowed by `bar` here
| value is borrowed by `foo` here | value is borrowed by `foo` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:120:9 --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:120:9
| |
LL | ref foo @ Some(box ref mut s) => (), LL | ref foo @ Some(box ref mut s) => (),
| -------^^^^^^^^^^^^---------^ | ^^^^^^^ --------- value is mutably borrowed by `s` here
| | | | |
| | value is mutably borrowed by `s` here
| value is borrowed by `foo` here | value is borrowed by `foo` here
error[E0382]: borrow of moved value: `x` error[E0382]: borrow of moved value: `x`

View file

@ -14,14 +14,15 @@ LL | async fn foo(x: u32) -> u32 {
| ^^^query stack during panic: | ^^^query stack during panic:
#0 [typeck] type-checking `foo` #0 [typeck] type-checking `foo`
#1 [thir_body] building THIR for `foo` #1 [thir_body] building THIR for `foo`
#2 [mir_built] building MIR for `foo` #2 [check_match] match-checking `foo`
#3 [unsafety_check_result] unsafety-checking `foo` #3 [mir_built] building MIR for `foo`
#4 [mir_const] preparing `foo` for borrow checking #4 [unsafety_check_result] unsafety-checking `foo`
#5 [mir_promoted] processing MIR for `foo` #5 [mir_const] preparing `foo` for borrow checking
#6 [mir_borrowck] borrow-checking `foo` #6 [mir_promoted] processing MIR for `foo`
#7 [type_of] computing type of `foo::{opaque#0}` #7 [mir_borrowck] borrow-checking `foo`
#8 [check_mod_item_types] checking item types in top-level module #8 [type_of] computing type of `foo::{opaque#0}`
#9 [analysis] running analysis passes on this crate #9 [check_mod_item_types] checking item types in top-level module
#10 [analysis] running analysis passes on this crate
end of query stack end of query stack
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -14,7 +14,6 @@ fn main() {
match -128i8 { match -128i8 {
NEG_NEG_128 => println!("A"), NEG_NEG_128 => println!("A"),
//~^ ERROR could not evaluate constant pattern //~^ ERROR could not evaluate constant pattern
//~| ERROR could not evaluate constant pattern
_ => println!("B"), _ => println!("B"),
} }
} }

View file

@ -10,12 +10,6 @@ error: could not evaluate constant pattern
LL | NEG_NEG_128 => println!("A"), LL | NEG_NEG_128 => println!("A"),
| ^^^^^^^^^^^ | ^^^^^^^^^^^
error: could not evaluate constant pattern error: aborting due to 2 previous errors
--> $DIR/const-eval-overflow-2.rs:15:9
|
LL | NEG_NEG_128 => println!("A"),
| ^^^^^^^^^^^
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0080`. For more information about this error, try `rustc --explain E0080`.

View file

@ -1,5 +1,5 @@
error[E0080]: evaluation of constant value failed 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 }; LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
| ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -13,12 +13,6 @@ error: could not evaluate constant pattern
LL | 10..=BAR => {}, LL | 10..=BAR => {},
| ^^^ | ^^^
error: could not evaluate constant pattern error: aborting due to 2 previous errors
--> $DIR/ref_to_int_match.rs:7:14
|
LL | 10..=BAR => {},
| ^^^
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0080`. For more information about this error, try `rustc --explain E0080`.

View file

@ -1,5 +1,5 @@
error[E0080]: evaluation of constant value failed 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 }; LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
| ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@ -13,12 +13,6 @@ error: could not evaluate constant pattern
LL | 10..=BAR => {}, LL | 10..=BAR => {},
| ^^^ | ^^^
error: could not evaluate constant pattern error: aborting due to 2 previous errors
--> $DIR/ref_to_int_match.rs:7:14
|
LL | 10..=BAR => {},
| ^^^
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0080`. For more information about this error, try `rustc --explain E0080`.

View file

@ -5,7 +5,6 @@ fn main() {
match n { match n {
0..=10 => {}, 0..=10 => {},
10..=BAR => {}, //~ ERROR could not evaluate constant pattern 10..=BAR => {}, //~ ERROR could not evaluate constant pattern
//~| ERROR could not evaluate constant pattern
_ => {}, _ => {},
} }
} }

View file

@ -9,8 +9,8 @@ LL | A = { let 0 = 0; 0 },
= note: the matched value is of type `i32` = note: the matched value is of type `i32`
help: you might want to use `if let` to ignore the variants that aren't matched 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 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 }, LL | A = { let _0 = 0; 0 },

View file

@ -9,8 +9,8 @@ LL | let x: [i32; { let 0 = 0; 0 }] = [];
= note: the matched value is of type `i32` = note: the matched value is of type `i32`
help: you might want to use `if let` to ignore the variants that aren't matched 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 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 }] = []; LL | let x: [i32; { let _0 = 0; 0 }] = [];

View file

@ -9,8 +9,8 @@ LL | const X: i32 = { let 0 = 0; 0 };
= note: the matched value is of type `i32` = note: the matched value is of type `i32`
help: you might want to use `if let` to ignore the variants that aren't matched 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 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 }; 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` = note: the matched value is of type `i32`
help: you might want to use `if let` to ignore the variants that aren't matched 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 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 }; 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` = note: the matched value is of type `i32`
help: you might want to use `if let` to ignore the variants that aren't matched 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 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 }; 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` = note: the matched value is of type `i32`
help: you might want to use `if let` to ignore the variants that aren't matched 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 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 }; LL | const X: i32 = { let _0 = 0; 0 };

View file

@ -1,9 +1,6 @@
error[E0005]: refutable pattern in local binding error[E0005]: refutable pattern in local binding
--> $DIR/const-pattern-irrefutable.rs:12:9 --> $DIR/const-pattern-irrefutable.rs:12:9
| |
LL | const a: u8 = 2;
| ----------- constant defined here
...
LL | let a = 4; LL | let a = 4;
| ^ | ^
| | | |
@ -11,14 +8,13 @@ LL | let a = 4;
| missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable | missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable
| help: introduce a variable instead: `a_var` | help: introduce a variable instead: `a_var`
| |
= 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` = note: the matched value is of type `u8`
error[E0005]: refutable pattern in local binding error[E0005]: refutable pattern in local binding
--> $DIR/const-pattern-irrefutable.rs:17:9 --> $DIR/const-pattern-irrefutable.rs:17:9
| |
LL | pub const b: u8 = 2;
| --------------- constant defined here
...
LL | let c = 4; LL | let c = 4;
| ^ | ^
| | | |
@ -26,14 +22,13 @@ LL | let c = 4;
| missing patterns are not covered because `c` is interpreted as a constant pattern, not a new variable | missing patterns are not covered because `c` is interpreted as a constant pattern, not a new variable
| help: introduce a variable instead: `c_var` | help: introduce a variable instead: `c_var`
| |
= 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` = note: the matched value is of type `u8`
error[E0005]: refutable pattern in local binding error[E0005]: refutable pattern in local binding
--> $DIR/const-pattern-irrefutable.rs:22:9 --> $DIR/const-pattern-irrefutable.rs:22:9
| |
LL | pub const d: u8 = 2;
| --------------- constant defined here
...
LL | let d = 4; LL | let d = 4;
| ^ | ^
| | | |
@ -41,6 +36,8 @@ LL | let d = 4;
| missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable | missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable
| help: introduce a variable instead: `d_var` | help: introduce a variable instead: `d_var`
| |
= 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` = note: the matched value is of type `u8`
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View file

@ -19,7 +19,7 @@ LL | match &[][..] {
= note: the matched value is of type `&[E]` = 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 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!() LL + &_ => todo!()
| |

View file

@ -7,7 +7,6 @@ fn main() {
match 1 { match 1 {
NUM => unimplemented!(), NUM => unimplemented!(),
//~^ ERROR could not evaluate constant pattern //~^ ERROR could not evaluate constant pattern
//~| ERROR could not evaluate constant pattern
_ => unimplemented!(), _ => unimplemented!(),
} }
} }

View file

@ -12,12 +12,6 @@ error: could not evaluate constant pattern
LL | NUM => unimplemented!(), LL | NUM => unimplemented!(),
| ^^^ | ^^^
error: could not evaluate constant pattern error: aborting due to 2 previous errors
--> $DIR/issue-43105.rs:8:9
|
LL | NUM => unimplemented!(),
| ^^^
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0015`. For more information about this error, try `rustc --explain E0015`.

View file

@ -19,7 +19,6 @@ impl<T: 'static> GetTypeId<T> {
const fn check_type_id<T: 'static>() -> bool { const fn check_type_id<T: 'static>() -> bool {
matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE) matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
//~^ ERROR constant pattern depends on a generic parameter //~^ ERROR constant pattern depends on a generic parameter
//~| ERROR constant pattern depends on a generic parameter
} }
pub struct GetTypeNameLen<T>(T); pub struct GetTypeNameLen<T>(T);
@ -31,7 +30,6 @@ impl<T: 'static> GetTypeNameLen<T> {
const fn check_type_name_len<T: 'static>() -> bool { const fn check_type_name_len<T: 'static>() -> bool {
matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE) matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
//~^ ERROR constant pattern depends on a generic parameter //~^ ERROR constant pattern depends on a generic parameter
//~| ERROR constant pattern depends on a generic parameter
} }
fn main() { fn main() {

View file

@ -5,22 +5,10 @@ LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
| ^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^
error: constant pattern depends on a generic parameter 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) LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: constant pattern depends on a generic parameter error: aborting due to 2 previous errors
--> $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

View file

@ -6,5 +6,4 @@ const FOO: *const u32 = {
fn main() { fn main() {
let FOO = FOO; let FOO = FOO;
//~^ ERROR could not evaluate constant pattern //~^ ERROR could not evaluate constant pattern
//~| ERROR could not evaluate constant pattern
} }

View file

@ -17,12 +17,6 @@ error: could not evaluate constant pattern
LL | let FOO = FOO; LL | let FOO = FOO;
| ^^^ | ^^^
error: could not evaluate constant pattern error: aborting due to 2 previous errors
--> $DIR/issue-78655.rs:7:9
|
LL | let FOO = FOO;
| ^^^
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0381`. For more information about this error, try `rustc --explain E0381`.

View file

@ -11,7 +11,6 @@ impl<T> GetVariantCount<T> {
const fn check_variant_count<T>() -> bool { const fn check_variant_count<T>() -> bool {
matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE) matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
//~^ ERROR constant pattern depends on a generic parameter //~^ ERROR constant pattern depends on a generic parameter
//~| ERROR constant pattern depends on a generic parameter
} }
fn main() { fn main() {

View file

@ -4,11 +4,5 @@ error: constant pattern depends on a generic parameter
LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE) LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: constant pattern depends on a generic parameter error: aborting due to previous error
--> $DIR/issue-79137-toogeneric.rs:12:43
|
LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors

View file

@ -27,7 +27,7 @@ LL | const U8_MUT: &u8 = {
} }
error: could not evaluate constant pattern 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, LL | U8_MUT => true,
| ^^^^^^ | ^^^^^^
@ -39,7 +39,7 @@ LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
error: could not evaluate constant pattern 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, LL | U8_MUT2 => true,
| ^^^^^^^ | ^^^^^^^
@ -51,31 +51,7 @@ LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None =>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
error: could not evaluate constant pattern 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,
| ^^^^^^^
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
| |
LL | U8_MUT3 => true, 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!() } } 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`. For more information about this error, try `rustc --explain E0080`.

View file

@ -27,7 +27,7 @@ LL | const U8_MUT: &u8 = {
} }
error: could not evaluate constant pattern 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, LL | U8_MUT => true,
| ^^^^^^ | ^^^^^^
@ -39,7 +39,7 @@ LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
error: could not evaluate constant pattern 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, LL | U8_MUT2 => true,
| ^^^^^^^ | ^^^^^^^
@ -51,31 +51,7 @@ LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None =>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
error: could not evaluate constant pattern 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,
| ^^^^^^^
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
| |
LL | U8_MUT3 => true, 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!() } } 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`. For more information about this error, try `rustc --explain E0080`.

View file

@ -33,7 +33,6 @@ pub fn test(x: &[u8; 1]) -> bool {
match x { match x {
SLICE_MUT => true, SLICE_MUT => true,
//~^ ERROR could not evaluate constant pattern //~^ ERROR could not evaluate constant pattern
//~| ERROR could not evaluate constant pattern
&[1..] => false, &[1..] => false,
} }
} }
@ -42,7 +41,6 @@ pub fn test2(x: &u8) -> bool {
match x { match x {
U8_MUT => true, U8_MUT => true,
//~^ ERROR could not evaluate constant pattern //~^ ERROR could not evaluate constant pattern
//~| ERROR could not evaluate constant pattern
&(1..) => false, &(1..) => false,
} }
} }
@ -53,7 +51,6 @@ pub fn test3(x: &u8) -> bool {
match x { match x {
U8_MUT2 => true, U8_MUT2 => true,
//~^ ERROR could not evaluate constant pattern //~^ ERROR could not evaluate constant pattern
//~| ERROR could not evaluate constant pattern
&(1..) => false, &(1..) => false,
} }
} }
@ -61,7 +58,6 @@ pub fn test4(x: &u8) -> bool {
match x { match x {
U8_MUT3 => true, U8_MUT3 => true,
//~^ ERROR could not evaluate constant pattern //~^ ERROR could not evaluate constant pattern
//~| ERROR could not evaluate constant pattern
&(1..) => false, &(1..) => false,
} }
} }

View file

@ -14,7 +14,7 @@ LL | HastaLaVistaBaby,
= note: the matched value is of type `Terminator` = 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 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!() LL + Terminator::HastaLaVistaBaby => todo!()
| |

View file

@ -4,6 +4,5 @@ fn main() {
match 5u32 { match 5u32 {
1000 ..= 5 => {} 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
//~| ERROR lower range bound must be less than or equal to upper
} }
} }

View file

@ -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. = 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 error: aborting due to previous error
--> $DIR/E0030-teach.rs:5:9
|
LL | 1000 ..= 5 => {}
| ^^^^ lower bound larger than upper bound
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0030`. For more information about this error, try `rustc --explain E0030`.

View file

@ -2,6 +2,5 @@ fn main() {
match 5u32 { match 5u32 {
1000 ..= 5 => {} 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
//~| ERROR lower range bound must be less than or equal to upper
} }
} }

View file

@ -4,12 +4,6 @@ error[E0030]: lower range bound must be less than or equal to upper
LL | 1000 ..= 5 => {} LL | 1000 ..= 5 => {}
| ^^^^ lower bound larger than upper bound | ^^^^ lower bound larger than upper bound
error[E0030]: lower range bound must be less than or equal to upper error: aborting due to previous error
--> $DIR/E0030.rs:3:9
|
LL | 1000 ..= 5 => {}
| ^^^^ lower bound larger than upper bound
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0030`. For more information about this error, try `rustc --explain E0030`.

View file

@ -115,7 +115,7 @@ LL | A, B, C,
= note: the matched value is of type `Foo` = 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 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!() LL + Foo::C => todo!()
| |

View file

@ -9,7 +9,7 @@ LL | match 0usize {
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = 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 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!() 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: 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 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!() LL + _ => todo!()
| |

View file

@ -10,44 +10,31 @@ macro_rules! m {
fn main() { fn main() {
m!(0, ..u8::MIN); m!(0, ..u8::MIN);
//~^ 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
m!(0, ..u16::MIN); m!(0, ..u16::MIN);
//~^ 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
m!(0, ..u32::MIN); m!(0, ..u32::MIN);
//~^ 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
m!(0, ..u64::MIN); m!(0, ..u64::MIN);
//~^ 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
m!(0, ..u128::MIN); m!(0, ..u128::MIN);
//~^ 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
m!(0, ..i8::MIN); m!(0, ..i8::MIN);
//~^ 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
m!(0, ..i16::MIN); m!(0, ..i16::MIN);
//~^ 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
m!(0, ..i32::MIN); m!(0, ..i32::MIN);
//~^ 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
m!(0, ..i64::MIN); m!(0, ..i64::MIN);
//~^ 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
m!(0, ..i128::MIN); m!(0, ..i128::MIN);
//~^ 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
m!(0f32, ..f32::NEG_INFINITY); m!(0f32, ..f32::NEG_INFINITY);
//~^ 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
m!(0f64, ..f64::NEG_INFINITY); m!(0f64, ..f64::NEG_INFINITY);
//~^ 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
m!('a', ..'\u{0}'); m!('a', ..'\u{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
} }

View file

@ -5,155 +5,77 @@ LL | m!(0, ..u8::MIN);
| ^^^^^^^^^ | ^^^^^^^^^
error[E0579]: lower range bound must be less than upper 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); LL | m!(0, ..u16::MIN);
| ^^^^^^^^^^ | ^^^^^^^^^^
error[E0579]: lower range bound must be less than upper 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); 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 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: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); LL | m!(0, ..u64::MIN);
| ^^^^^^^^^^ | ^^^^^^^^^^
error[E0579]: lower range bound must be less than upper 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); LL | m!(0, ..u128::MIN);
| ^^^^^^^^^^^ | ^^^^^^^^^^^
error[E0579]: lower range bound must be less than upper 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); LL | m!(0, ..i8::MIN);
| ^^^^^^^^^ | ^^^^^^^^^
error[E0579]: lower range bound must be less than upper 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); LL | m!(0, ..i16::MIN);
| ^^^^^^^^^^ | ^^^^^^^^^^
error[E0579]: lower range bound must be less than upper 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); LL | m!(0, ..i32::MIN);
| ^^^^^^^^^^ | ^^^^^^^^^^
error[E0579]: lower range bound must be less than upper 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); LL | m!(0, ..i64::MIN);
| ^^^^^^^^^^ | ^^^^^^^^^^
error[E0579]: lower range bound must be less than upper 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); LL | m!(0, ..i128::MIN);
| ^^^^^^^^^^^ | ^^^^^^^^^^^
error[E0579]: lower range bound must be less than upper 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); LL | m!(0f32, ..f32::NEG_INFINITY);
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
error[E0579]: lower range bound must be less than upper 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); LL | m!(0f64, ..f64::NEG_INFINITY);
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
error[E0579]: lower range bound must be less than upper 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}'); 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`. For more information about this error, try `rustc --explain E0579`.

View file

@ -29,6 +29,11 @@ note: ...which requires building MIR for `cycle1`...
| |
LL | fn cycle1() -> impl Clone { 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`... note: ...which requires building THIR for `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1 --> $DIR/auto-trait-leak.rs:12:1
| |
@ -70,6 +75,11 @@ note: ...which requires building MIR for `cycle2`...
| |
LL | fn cycle2() -> impl Clone { 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`... note: ...which requires building THIR for `cycle2`...
--> $DIR/auto-trait-leak.rs:19:1 --> $DIR/auto-trait-leak.rs:19:1
| |

View file

@ -7,7 +7,6 @@ fn foo<const V: usize>() {
match 0 { match 0 {
const { V } => {}, const { V } => {},
//~^ ERROR constant pattern depends on a generic parameter //~^ 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 { match 0 {
const { f(V) } => {}, const { f(V) } => {},
//~^ ERROR constant pattern depends on a generic parameter //~^ ERROR constant pattern depends on a generic parameter
//~| ERROR constant pattern depends on a generic parameter
_ => {}, _ => {},
} }
} }

View file

@ -5,22 +5,10 @@ LL | const { V } => {},
| ^^^^^^^^^^^ | ^^^^^^^^^^^
error: constant pattern depends on a generic parameter 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) } => {}, LL | const { f(V) } => {},
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error: constant pattern depends on a generic parameter error: aborting due to 2 previous errors
--> $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

View file

@ -3,22 +3,19 @@
fn main() { fn main() {
match 5 { match 5 {
6 ..= 1 => { } 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 { match 5 {
0 .. 0 => { } 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 { match 5u64 {
0xFFFF_FFFF_FFFF_FFFF ..= 1 => { } 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
} }

View file

@ -5,36 +5,18 @@ LL | 6 ..= 1 => { }
| ^ lower bound larger than upper bound | ^ lower bound larger than upper bound
error[E0579]: lower range bound must be less than upper 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 => { } LL | 0 .. 0 => { }
| ^ | ^
error[E0030]: lower range bound must be less than or equal to upper 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 => { } LL | 0xFFFF_FFFF_FFFF_FFFF ..= 1 => { }
| ^^^^^^^^^^^^^^^^^^^^^ lower bound larger than upper bound | ^^^^^^^^^^^^^^^^^^^^^ lower bound larger than upper bound
error[E0030]: lower range bound must be less than or equal to upper error: aborting due to 3 previous errors
--> $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
Some errors have detailed explanations: E0030, E0579. Some errors have detailed explanations: E0030, E0579.
For more information about an error, try `rustc --explain E0030`. For more information about an error, try `rustc --explain E0030`.

View file

@ -17,8 +17,8 @@ LL | B(inner::Wrapper<B>),
= note: the matched value is of type `Either<(), !>` = note: the matched value is of type `Either<(), !>`
help: you might want to use `if let` to ignore the variant that isn't matched 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 error: aborting due to previous error

View file

@ -7,7 +7,7 @@ LL | match (0u8, 0u8) {
= note: the matched value is of type `(u8, u8)` = 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 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!() LL + (2_u8..=u8::MAX, _) => todo!()
| |
@ -20,7 +20,7 @@ LL | match ((0u8,),) {
= note: the matched value is of type `((u8,),)` = 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 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!() LL + ((4_u8..=u8::MAX)) => todo!()
| |
@ -33,7 +33,7 @@ LL | match (Some(0u8),) {
= note: the matched value is of type `(Option<u8>,)` = 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 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!() LL + (Some(2_u8..=u8::MAX)) => todo!()
| |

View file

@ -9,8 +9,8 @@ LL | let (0 | (1 | 2)) = 0;
= note: the matched value is of type `i32` = note: the matched value is of type `i32`
help: you might want to use `if let` to ignore the variants that aren't matched 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 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 --> $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` = 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 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!() LL + i32::MIN..=-1_i32 | 3_i32..=i32::MAX => todo!()
| |

View file

@ -2,18 +2,16 @@ error: cannot move out of value because it is borrowed
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:12:14 --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:12:14
| |
LL | Some(ref _y @ _z) => {} LL | Some(ref _y @ _z) => {}
| ------^^^-- | ^^^^^^ -- value is moved into `_z` here
| | | | |
| | value is moved into `_z` here
| value is borrowed by `_y` here | value is borrowed by `_y` here
error: borrow of moved value error: borrow of moved value
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:19:14 --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:19:14
| |
LL | Some(_z @ ref _y) => {} LL | Some(_z @ ref _y) => {}
| --^^^------ | ^^ ------ value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `_z` here | value moved into `_z` here
| move occurs because `_z` has type `X` which does not implement the `Copy` trait | move occurs because `_z` has type `X` which does not implement the `Copy` trait
| |
@ -26,18 +24,16 @@ error: cannot move out of value because it is borrowed
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:26:14 --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:26:14
| |
LL | Some(ref mut _y @ _z) => {} LL | Some(ref mut _y @ _z) => {}
| ----------^^^-- | ^^^^^^^^^^ -- value is moved into `_z` here
| | | | |
| | value is moved into `_z` here
| value is mutably borrowed by `_y` here | value is mutably borrowed by `_y` here
error: borrow of moved value error: borrow of moved value
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:33:14 --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:33:14
| |
LL | Some(_z @ ref mut _y) => {} LL | Some(_z @ ref mut _y) => {}
| --^^^---------- | ^^ ---------- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `_z` here | value moved into `_z` here
| move occurs because `_z` has type `X` which does not implement the `Copy` trait | move occurs because `_z` has type `X` which does not implement the `Copy` trait
| |

View file

@ -2,72 +2,64 @@ error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-at-and-box.rs:31:9 --> $DIR/borrowck-pat-at-and-box.rs:31:9
| |
LL | let ref a @ box b = Box::new(NC); LL | let ref a @ box b = Box::new(NC);
| -----^^^^^^^- | ^^^^^ - value is moved into `b` here
| | | | |
| | value is moved into `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:34:9 --> $DIR/borrowck-pat-at-and-box.rs:34:9
| |
LL | let ref a @ box ref mut b = Box::new(nc()); LL | let ref a @ box ref mut b = Box::new(nc());
| -----^^^^^^^--------- | ^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:36:9 --> $DIR/borrowck-pat-at-and-box.rs:36:9
| |
LL | let ref a @ box ref mut b = Box::new(NC); LL | let ref a @ box ref mut b = Box::new(NC);
| -----^^^^^^^--------- | ^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:38:9 --> $DIR/borrowck-pat-at-and-box.rs:38:9
| |
LL | let ref a @ box ref mut b = Box::new(NC); LL | let ref a @ box ref mut b = Box::new(NC);
| -----^^^^^^^--------- | ^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:42:9 --> $DIR/borrowck-pat-at-and-box.rs:42:9
| |
LL | let ref a @ box ref mut b = Box::new(NC); LL | let ref a @ box ref mut b = Box::new(NC);
| -----^^^^^^^--------- | ^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:48:9 --> $DIR/borrowck-pat-at-and-box.rs:48:9
| |
LL | let ref mut a @ box ref b = Box::new(NC); LL | let ref mut a @ box ref b = Box::new(NC);
| ---------^^^^^^^----- | ^^^^^^^^^ ----- value is borrowed by `b` here
| | | | |
| | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:62:9 --> $DIR/borrowck-pat-at-and-box.rs:62:9
| |
LL | ref mut a @ box ref b => { LL | ref mut a @ box ref b => {
| ---------^^^^^^^----- | ^^^^^^^^^ ----- value is borrowed by `b` here
| | | | |
| | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:54:11 --> $DIR/borrowck-pat-at-and-box.rs:54:11
| |
LL | fn f5(ref mut a @ box ref b: Box<NC>) { LL | fn f5(ref mut a @ box ref b: Box<NC>) {
| ---------^^^^^^^----- | ^^^^^^^^^ ----- value is borrowed by `b` here
| | | | |
| | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error[E0382]: borrow of moved value error[E0382]: borrow of moved value

View file

@ -2,9 +2,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse-promotion.rs:6:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse-promotion.rs:6:9
| |
LL | let a @ ref b = U; LL | let a @ ref b = U;
| -^^^----- | ^ ----- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `U` which does not implement the `Copy` trait | move occurs because `a` has type `U` which does not implement the `Copy` trait
| |

View file

@ -2,9 +2,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:22:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:22:9
| |
LL | let a @ ref b = U; LL | let a @ ref b = U;
| -^^^----- | ^ ----- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `U` which does not implement the `Copy` trait | move occurs because `a` has type `U` which does not implement the `Copy` trait
| |
@ -17,9 +16,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:9
| |
LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
| -^^^^^^^^^^^^---------^^^^^^-----^ | ^ --------- ----- value borrowed here after move
| | | | | | |
| | | value borrowed here after move
| | value borrowed here after move | | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait
@ -33,9 +31,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:14 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:14
| |
LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
| -----^^^--------- | ^^^^^ --------- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `b` here | value moved into `b` here
| move occurs because `b` has type `U` which does not implement the `Copy` trait | move occurs because `b` has type `U` which does not implement the `Copy` trait
| |
@ -48,9 +45,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:33 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:33
| |
LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
| -^^^----- | ^ ----- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `d` here | value moved into `d` here
| move occurs because `d` has type `U` which does not implement the `Copy` trait | move occurs because `d` has type `U` which does not implement the `Copy` trait
| |
@ -63,9 +59,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:29:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:29:9
| |
LL | let a @ [ref mut b, ref c] = [U, U]; LL | let a @ [ref mut b, ref c] = [U, U];
| -^^^^---------^^-----^ | ^ --------- ----- value borrowed here after move
| | | | | | |
| | | value borrowed here after move
| | value borrowed here after move | | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait | move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait
@ -79,9 +74,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:9
| |
LL | let a @ ref b = u(); LL | let a @ ref b = u();
| -^^^----- | ^ ----- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `U` which does not implement the `Copy` trait | move occurs because `a` has type `U` which does not implement the `Copy` trait
| |
@ -94,9 +88,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:33:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:33:9
| |
LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
| -^^^^^^^^^^^^---------^^^^^^-----^ | ^ --------- ----- value borrowed here after move
| | | | | | |
| | | value borrowed here after move
| | value borrowed here after move | | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait
@ -110,9 +103,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:33:14 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:33:14
| |
LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
| -----^^^--------- | ^^^^^ --------- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `b` here | value moved into `b` here
| move occurs because `b` has type `U` which does not implement the `Copy` trait | move occurs because `b` has type `U` which does not implement the `Copy` trait
| |
@ -125,9 +117,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:33:33 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:33:33
| |
LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
| -^^^----- | ^ ----- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `d` here | value moved into `d` here
| move occurs because `d` has type `U` which does not implement the `Copy` trait | move occurs because `d` has type `U` which does not implement the `Copy` trait
| |
@ -140,9 +131,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:38:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:38:9
| |
LL | let a @ [ref mut b, ref c] = [u(), u()]; LL | let a @ [ref mut b, ref c] = [u(), u()];
| -^^^^---------^^-----^ | ^ --------- ----- value borrowed here after move
| | | | | | |
| | | value borrowed here after move
| | value borrowed here after move | | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait | move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait
@ -156,9 +146,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:42:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:42:9
| |
LL | a @ Some(ref b) => {} LL | a @ Some(ref b) => {}
| -^^^^^^^^-----^ | ^ ----- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `Option<U>` which does not implement the `Copy` trait | move occurs because `a` has type `Option<U>` which does not implement the `Copy` trait
| |
@ -171,9 +160,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:47:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:47:9
| |
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| -^^^^^^^^^^^^^^^^^---------^^^^^^-----^^ | ^ --------- ----- value borrowed here after move
| | | | | | |
| | | value borrowed here after move
| | value borrowed here after move | | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `Option<(U, U)>` which does not implement the `Copy` trait | move occurs because `a` has type `Option<(U, U)>` which does not implement the `Copy` trait
@ -187,9 +175,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:47:19 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:47:19
| |
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| -----^^^--------- | ^^^^^ --------- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `b` here | value moved into `b` here
| move occurs because `b` has type `U` which does not implement the `Copy` trait | move occurs because `b` has type `U` which does not implement the `Copy` trait
| |
@ -202,9 +189,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:47:38 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:47:38
| |
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| -^^^----- | ^ ----- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `d` here | value moved into `d` here
| move occurs because `d` has type `U` which does not implement the `Copy` trait | move occurs because `d` has type `U` which does not implement the `Copy` trait
| |
@ -217,9 +203,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:55:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:55:9
| |
LL | mut a @ Some([ref b, ref mut c]) => {} LL | mut a @ Some([ref b, ref mut c]) => {}
| -----^^^^^^^^^-----^^---------^^ | ^^^^^ ----- --------- value borrowed here after move
| | | | | | |
| | | value borrowed here after move
| | value borrowed here after move | | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `Option<[U; 2]>` which does not implement the `Copy` trait | move occurs because `a` has type `Option<[U; 2]>` which does not implement the `Copy` trait
@ -233,9 +218,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:9
| |
LL | a @ Some(ref b) => {} LL | a @ Some(ref b) => {}
| -^^^^^^^^-----^ | ^ ----- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `Option<U>` which does not implement the `Copy` trait | move occurs because `a` has type `Option<U>` which does not implement the `Copy` trait
| |
@ -248,9 +232,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:9
| |
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| -^^^^^^^^^^^^^^^^^---------^^^^^^-----^^ | ^ --------- ----- value borrowed here after move
| | | | | | |
| | | value borrowed here after move
| | value borrowed here after move | | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `Option<(U, U)>` which does not implement the `Copy` trait | move occurs because `a` has type `Option<(U, U)>` which does not implement the `Copy` trait
@ -264,9 +247,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:19 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:19
| |
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| -----^^^--------- | ^^^^^ --------- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `b` here | value moved into `b` here
| move occurs because `b` has type `U` which does not implement the `Copy` trait | move occurs because `b` has type `U` which does not implement the `Copy` trait
| |
@ -279,9 +261,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:38 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:38
| |
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| -^^^----- | ^ ----- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `d` here | value moved into `d` here
| move occurs because `d` has type `U` which does not implement the `Copy` trait | move occurs because `d` has type `U` which does not implement the `Copy` trait
| |
@ -294,9 +275,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:75:9 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:75:9
| |
LL | mut a @ Some([ref b, ref mut c]) => {} LL | mut a @ Some([ref b, ref mut c]) => {}
| -----^^^^^^^^^-----^^---------^^ | ^^^^^ ----- --------- value borrowed here after move
| | | | | | |
| | | value borrowed here after move
| | value borrowed here after move | | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `Option<[U; 2]>` which does not implement the `Copy` trait | move occurs because `a` has type `Option<[U; 2]>` which does not implement the `Copy` trait
@ -310,9 +290,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:11:11 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:11:11
| |
LL | fn f1(a @ ref b: U) {} LL | fn f1(a @ ref b: U) {}
| -^^^----- | ^ ----- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `U` which does not implement the `Copy` trait | move occurs because `a` has type `U` which does not implement the `Copy` trait
| |
@ -325,9 +304,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11
| |
LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
| -----^^^^^^^^-----^^^^^^^^^^-----^ | ^^^^^ ----- ----- value borrowed here after move
| | | | | | |
| | | value borrowed here after move
| | value borrowed here after move | | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait
@ -341,9 +319,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:20 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:20
| |
LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
| -^^^----- | ^ ----- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `b` here | value moved into `b` here
| move occurs because `b` has type `U` which does not implement the `Copy` trait | move occurs because `b` has type `U` which does not implement the `Copy` trait
| |
@ -356,9 +333,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:31 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:31
| |
LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
| -----^^^----- | ^^^^^ ----- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `d` here | value moved into `d` here
| move occurs because `d` has type `U` which does not implement the `Copy` trait | move occurs because `d` has type `U` which does not implement the `Copy` trait
| |
@ -371,9 +347,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:19:11 --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:19:11
| |
LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {}
| -^^^^---------^^-----^ | ^ --------- ----- value borrowed here after move
| | | | | | |
| | | value borrowed here after move
| | value borrowed here after move | | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait | move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait

View file

@ -2,18 +2,16 @@ error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:24:9 --> $DIR/borrowck-pat-by-move-and-ref.rs:24:9
| |
LL | let ref a @ b = U; LL | let ref a @ b = U;
| -----^^^- | ^^^^^ - value is moved into `b` here
| | | | |
| | value is moved into `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:26:9 --> $DIR/borrowck-pat-by-move-and-ref.rs:26:9
| |
LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U); LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
| -----^^^^^^^^^^^^-----^^^^^^^^^^-^ | ^^^^^ ----- - value is moved into `e` here
| | | | | | |
| | | value is moved into `e` here
| | value is moved into `c` here | | value is moved into `c` here
| value is borrowed by `a` here | value is borrowed by `a` here
@ -21,27 +19,24 @@ error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:26:18 --> $DIR/borrowck-pat-by-move-and-ref.rs:26:18
| |
LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U); LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
| -----^^^----- | ^^^^^ ----- value is moved into `c` here
| | | | |
| | value is moved into `c` here
| value is borrowed by `b` here | value is borrowed by `b` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:26:33 --> $DIR/borrowck-pat-by-move-and-ref.rs:26:33
| |
LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U); LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
| -----^^^- | ^^^^^ - value is moved into `e` here
| | | | |
| | value is moved into `e` here
| value is borrowed by `d` here | value is borrowed by `d` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:30:9 --> $DIR/borrowck-pat-by-move-and-ref.rs:30:9
| |
LL | let ref mut a @ [b, mut c] = [U, U]; LL | let ref mut a @ [b, mut c] = [U, U];
| ---------^^^^-^^-----^ | ^^^^^^^^^ - ----- value is moved into `c` here
| | | | | | |
| | | value is moved into `c` here
| | value is moved into `b` here | | value is moved into `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
@ -49,18 +44,16 @@ error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:33:9 --> $DIR/borrowck-pat-by-move-and-ref.rs:33:9
| |
LL | let ref a @ b = u(); LL | let ref a @ b = u();
| -----^^^- | ^^^^^ - value is moved into `b` here
| | | | |
| | value is moved into `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:36:9 --> $DIR/borrowck-pat-by-move-and-ref.rs:36:9
| |
LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
| -----^^^^^^^^^^^^-----^^^^^^^^^^-^ | ^^^^^ ----- - value is moved into `e` here
| | | | | | |
| | | value is moved into `e` here
| | value is moved into `c` here | | value is moved into `c` here
| value is borrowed by `a` here | value is borrowed by `a` here
@ -68,27 +61,24 @@ error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:36:18 --> $DIR/borrowck-pat-by-move-and-ref.rs:36:18
| |
LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
| -----^^^----- | ^^^^^ ----- value is moved into `c` here
| | | | |
| | value is moved into `c` here
| value is borrowed by `b` here | value is borrowed by `b` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:36:33 --> $DIR/borrowck-pat-by-move-and-ref.rs:36:33
| |
LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
| -----^^^- | ^^^^^ - value is moved into `e` here
| | | | |
| | value is moved into `e` here
| value is borrowed by `d` here | value is borrowed by `d` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:42:9 --> $DIR/borrowck-pat-by-move-and-ref.rs:42:9
| |
LL | let ref mut a @ [b, mut c] = [u(), u()]; LL | let ref mut a @ [b, mut c] = [u(), u()];
| ---------^^^^-^^-----^ | ^^^^^^^^^ - ----- value is moved into `c` here
| | | | | | |
| | | value is moved into `c` here
| | value is moved into `b` here | | value is moved into `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
@ -96,18 +86,16 @@ error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:47:9 --> $DIR/borrowck-pat-by-move-and-ref.rs:47:9
| |
LL | ref a @ Some(b) => {} LL | ref a @ Some(b) => {}
| -----^^^^^^^^-^ | ^^^^^ - value is moved into `b` here
| | | | |
| | value is moved into `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:52:9 --> $DIR/borrowck-pat-by-move-and-ref.rs:52:9
| |
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^ | ^^^^^ ----- - value is moved into `e` here
| | | | | | |
| | | value is moved into `e` here
| | value is moved into `c` here | | value is moved into `c` here
| value is borrowed by `a` here | value is borrowed by `a` here
@ -115,27 +103,24 @@ error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:52:23 --> $DIR/borrowck-pat-by-move-and-ref.rs:52:23
| |
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| -----^^^----- | ^^^^^ ----- value is moved into `c` here
| | | | |
| | value is moved into `c` here
| value is borrowed by `b` here | value is borrowed by `b` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:52:38 --> $DIR/borrowck-pat-by-move-and-ref.rs:52:38
| |
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| -----^^^- | ^^^^^ - value is moved into `e` here
| | | | |
| | value is moved into `e` here
| value is borrowed by `d` here | value is borrowed by `d` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:59:9 --> $DIR/borrowck-pat-by-move-and-ref.rs:59:9
| |
LL | ref mut a @ Some([b, mut c]) => {} LL | ref mut a @ Some([b, mut c]) => {}
| ---------^^^^^^^^^-^^-----^^ | ^^^^^^^^^ - ----- value is moved into `c` here
| | | | | | |
| | | value is moved into `c` here
| | value is moved into `b` here | | value is moved into `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
@ -143,18 +128,16 @@ error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:64:9 --> $DIR/borrowck-pat-by-move-and-ref.rs:64:9
| |
LL | ref a @ Some(b) => {} LL | ref a @ Some(b) => {}
| -----^^^^^^^^-^ | ^^^^^ - value is moved into `b` here
| | | | |
| | value is moved into `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:69:9 --> $DIR/borrowck-pat-by-move-and-ref.rs:69:9
| |
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^ | ^^^^^ ----- - value is moved into `e` here
| | | | | | |
| | | value is moved into `e` here
| | value is moved into `c` here | | value is moved into `c` here
| value is borrowed by `a` here | value is borrowed by `a` here
@ -162,27 +145,24 @@ error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:69:23 --> $DIR/borrowck-pat-by-move-and-ref.rs:69:23
| |
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| -----^^^----- | ^^^^^ ----- value is moved into `c` here
| | | | |
| | value is moved into `c` here
| value is borrowed by `b` here | value is borrowed by `b` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:69:38 --> $DIR/borrowck-pat-by-move-and-ref.rs:69:38
| |
LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| -----^^^- | ^^^^^ - value is moved into `e` here
| | | | |
| | value is moved into `e` here
| value is borrowed by `d` here | value is borrowed by `d` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:78:9 --> $DIR/borrowck-pat-by-move-and-ref.rs:78:9
| |
LL | ref mut a @ Some([b, mut c]) => {} LL | ref mut a @ Some([b, mut c]) => {}
| ---------^^^^^^^^^-^^-----^^ | ^^^^^^^^^ - ----- value is moved into `c` here
| | | | | | |
| | | value is moved into `c` here
| | value is moved into `b` here | | value is moved into `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
@ -190,18 +170,16 @@ error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:11:11 --> $DIR/borrowck-pat-by-move-and-ref.rs:11:11
| |
LL | fn f1(ref a @ b: U) {} LL | fn f1(ref a @ b: U) {}
| -----^^^- | ^^^^^ - value is moved into `b` here
| | | | |
| | value is moved into `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:14:11 --> $DIR/borrowck-pat-by-move-and-ref.rs:14:11
| |
LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
| -----^^^^^^^^^^^^-----^^^^^^^^^^-^ | ^^^^^ ----- - value is moved into `e` here
| | | | | | |
| | | value is moved into `e` here
| | value is moved into `c` here | | value is moved into `c` here
| value is borrowed by `a` here | value is borrowed by `a` here
@ -209,27 +187,24 @@ error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:14:20 --> $DIR/borrowck-pat-by-move-and-ref.rs:14:20
| |
LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
| -----^^^----- | ^^^^^ ----- value is moved into `c` here
| | | | |
| | value is moved into `c` here
| value is borrowed by `b` here | value is borrowed by `b` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:14:35 --> $DIR/borrowck-pat-by-move-and-ref.rs:14:35
| |
LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
| -----^^^- | ^^^^^ - value is moved into `e` here
| | | | |
| | value is moved into `e` here
| value is borrowed by `d` here | value is borrowed by `d` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-by-move-and-ref.rs:20:11 --> $DIR/borrowck-pat-by-move-and-ref.rs:20:11
| |
LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {} LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {}
| ---------^^^^-^^-----^ | ^^^^^^^^^ - ----- value is moved into `c` here
| | | | | | |
| | | value is moved into `c` here
| | value is moved into `b` here | | value is moved into `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here

View file

@ -2,18 +2,16 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:8:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:8:9
| |
LL | ref mut z @ &mut Some(ref a) => { LL | ref mut z @ &mut Some(ref a) => {
| ---------^^^^^^^^^^^^^-----^ | ^^^^^^^^^ ----- value is borrowed by `a` here
| | | | |
| | value is borrowed by `a` here
| value is mutably borrowed by `z` here | value is mutably borrowed by `z` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:33:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:33:9
| |
LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
| ---------^^^^-----------------^ | ^^^^^^^^^ ----- --------- value is mutably borrowed by `c` here
| | | | | | |
| | | value is mutably borrowed by `c` here
| | value is borrowed by `b` here | | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
@ -21,36 +19,32 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:33:22 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:33:22
| |
LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
| -----^^^--------- | ^^^^^ --------- value is mutably borrowed by `c` here
| | | | |
| | value is mutably borrowed by `c` here
| value is borrowed by `b` here | value is borrowed by `b` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:37:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:37:9
| |
LL | let ref a @ ref mut b = U; LL | let ref a @ ref mut b = U;
| -----^^^--------- | ^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9
| |
LL | let ref mut a @ ref b = U; LL | let ref mut a @ ref b = U;
| ---------^^^----- | ^^^^^^^^^ ----- value is borrowed by `b` here
| | | | |
| | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9
| |
LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^ | ^^^^^ --------- --------- value is mutably borrowed by `c` here
| | | | | | |
| | | value is mutably borrowed by `c` here
| | value is mutably borrowed by `b` here | | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
@ -58,9 +52,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:43:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:43:9
| |
LL | let ref mut a @ (ref b, ref c) = (U, U); LL | let ref mut a @ (ref b, ref c) = (U, U);
| ---------^^^^-----^^-----^ | ^^^^^^^^^ ----- ----- value is borrowed by `c` here
| | | | | | |
| | | value is borrowed by `c` here
| | value is borrowed by `b` here | | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
@ -68,153 +61,136 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:46:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:46:9
| |
LL | let ref mut a @ ref b = u(); LL | let ref mut a @ ref b = u();
| ---------^^^----- | ^^^^^^^^^ ----- value is borrowed by `b` here
| | | | |
| | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:51:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:51:9
| |
LL | let ref a @ ref mut b = u(); LL | let ref a @ ref mut b = u();
| -----^^^--------- | ^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:57:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:57:9
| |
LL | let ref mut a @ ref b = U; LL | let ref mut a @ ref b = U;
| ---------^^^----- | ^^^^^^^^^ ----- value is borrowed by `b` here
| | | | |
| | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:61:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:61:9
| |
LL | let ref a @ ref mut b = U; LL | let ref a @ ref mut b = U;
| -----^^^--------- | ^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:67:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:67:9
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
| ---------^^^^^^-----^ | ^^^^^^^^^ ----- value is borrowed by `b` here
| | | | |
| | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:67:33 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:67:33
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
| ---------^^^^^^^-----^ | ^^^^^^^^^ ----- value is borrowed by `b` here
| | | | |
| | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:9
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
| -----^^^^^^---------^ | ^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:33 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:33
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
| -----^^^^^^^---------^ | ^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:9
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
| -----^^^^^^---------^ | ^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:33 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:33
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
| -----^^^^^^^---------^ | ^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:9
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
| ---------^^^^^^-----^ | ^^^^^^^^^ ----- value is borrowed by `b` here
| | | | |
| | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:33 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:33
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
| ---------^^^^^^^-----^ | ^^^^^^^^^ ----- value is borrowed by `b` here
| | | | |
| | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:9
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| -----^^^^^^---------^ | ^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:33 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:33
| |
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| -----^^^^^^^---------^ | ^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:109:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:109:9
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ---------^^^^^^-----^ | ^^^^^^^^^ ----- value is borrowed by `b` here
| | | | |
| | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:109:33 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:109:33
| |
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ---------^^^^^^^-----^ | ^^^^^^^^^ ----- value is borrowed by `b` here
| | | | |
| | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:117:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:117:9
| |
LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^ | ^^^^^ --------- --------- value is mutably borrowed by `c` here
| | | | | | |
| | | value is mutably borrowed by `c` here
| | value is mutably borrowed by `b` here | | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
@ -222,9 +198,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:123:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:123:9
| |
LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^ | ^^^^^ --------- --------- value is mutably borrowed by `c` here
| | | | | | |
| | | value is mutably borrowed by `c` here
| | value is mutably borrowed by `b` here | | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
@ -232,9 +207,8 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:129:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:129:9
| |
LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^ | ^^^^^ --------- --------- value is mutably borrowed by `c` here
| | | | | | |
| | | value is mutably borrowed by `c` here
| | value is mutably borrowed by `b` here | | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
@ -242,9 +216,8 @@ error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:134:9 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:134:9
| |
LL | let ref mut a @ (ref b, ref c) = (U, U); LL | let ref mut a @ (ref b, ref c) = (U, U);
| ---------^^^^-----^^-----^ | ^^^^^^^^^ ----- ----- value is borrowed by `c` here
| | | | | | |
| | | value is borrowed by `c` here
| | value is borrowed by `b` here | | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
@ -252,36 +225,32 @@ error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:22:11 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:22:11
| |
LL | fn f1(ref a @ ref mut b: U) {} LL | fn f1(ref a @ ref mut b: U) {}
| -----^^^--------- | ^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as immutable because it is also borrowed as mutable error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11
| |
LL | fn f2(ref mut a @ ref b: U) {} LL | fn f2(ref mut a @ ref b: U) {}
| ---------^^^----- | ^^^^^^^^^ ----- value is borrowed by `b` here
| | | | |
| | value is borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11
| |
LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {}
| -----^^^^^^^^^^^----------------^^^^^^^^ | ^^^^^ ----------- value is mutably borrowed by `mid` here
| | | | |
| | value is mutably borrowed by `mid` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot borrow value as mutable because it is also borrowed as immutable error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:22 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:22
| |
LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {}
| -----^^^------------- | ^^^^^ --------- - value is moved into `c` here
| | | | | | |
| | | value is moved into `c` here
| | value is mutably borrowed by `b` here | | value is mutably borrowed by `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
@ -289,9 +258,8 @@ error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:30 --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:30
| |
LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {}
| ---------^^^- | ^^^^^^^^^ - value is moved into `c` here
| | | | |
| | value is moved into `c` here
| value is mutably borrowed by `b` here | value is mutably borrowed by `b` here
error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable

View file

@ -2,98 +2,80 @@ error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:26:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:26:9
| |
LL | let ref mut a @ ref mut b = U; LL | let ref mut a @ ref mut b = U;
| ---------^^^--------- | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:29:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:29:9
| |
LL | let ref mut a @ ref mut b = U; LL | let ref mut a @ ref mut b = U;
| ---------^^^--------- | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:33:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:33:9
| |
LL | let ref mut a @ ref mut b = U; LL | let ref mut a @ ref mut b = U;
| ---------^^^--------- | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:36:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:36:9
| |
LL | let ref mut a @ ref mut b = U; LL | let ref mut a @ ref mut b = U;
| ---------^^^--------- | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:39:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:39:9
| |
LL | let ref mut a @ ref mut b = U; LL | let ref mut a @ ref mut b = U;
| ---------^^^--------- | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:44:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:44:9
| |
LL | let ref mut a @ ( LL | let ref mut a @ (
| ^-------- | ^^^^^^^^^ value is mutably borrowed by `a` here
| | LL |
| _________value is mutably borrowed by `a` here LL | ref mut b,
| | | --------- value is mutably borrowed by `b` here
LL | | LL | [
LL | | ref mut b, LL | ref mut c,
| | --------- value is mutably borrowed by `b` here | --------- value is mutably borrowed by `c` here
LL | | [ LL | ref mut d,
LL | | ref mut c, | --------- value is mutably borrowed by `d` here
| | --------- value is mutably borrowed by `c` here LL | ref e,
LL | | ref mut d, | ----- value is borrowed by `e` here
| | --------- value is mutably borrowed by `d` here
LL | | ref e,
| | ----- value is borrowed by `e` here
LL | | ]
LL | | ) = (U, [U, U, U]);
| |_____^
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:54:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:54:9
| |
LL | let ref mut a @ ( LL | let ref mut a @ (
| ^-------- | ^^^^^^^^^ value is mutably borrowed by `a` here
| | LL |
| _________value is mutably borrowed by `a` here LL | ref mut b,
| | | --------- value is mutably borrowed by `b` here
LL | | LL | [
LL | | ref mut b, LL | ref mut c,
| | --------- value is mutably borrowed by `b` here | --------- value is mutably borrowed by `c` here
LL | | [ LL | ref mut d,
LL | | ref mut c, | --------- value is mutably borrowed by `d` here
| | --------- value is mutably borrowed by `c` here LL | ref e,
LL | | ref mut d, | ----- value is borrowed by `e` here
| | --------- value is mutably borrowed by `d` here
LL | | ref e,
| | ----- value is borrowed by `e` here
LL | | ]
LL | | ) = (u(), [u(), u(), u()]);
| |_________^
error: borrow of moved value error: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:64:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:64:9
| |
LL | let a @ (ref mut b, ref mut c) = (U, U); LL | let a @ (ref mut b, ref mut c) = (U, U);
| -^^^^---------^^---------^ | ^ --------- --------- value borrowed here after move
| | | | | | |
| | | value borrowed here after move
| | value borrowed here after move | | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait
@ -107,9 +89,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:67:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:67:9
| |
LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- LL | let a @ (b, [c, d]) = &mut val; // Same as ^--
| -^^^^-^^^-^^-^^ | ^ - - - value borrowed here after move
| | | | | | | | |
| | | | value borrowed here after move
| | | value borrowed here after move | | | value borrowed here after move
| | value borrowed here after move | | value borrowed here after move
| value moved into `a` here | value moved into `a` here
@ -124,9 +105,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:70:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:70:9
| |
LL | let a @ &mut ref mut b = &mut U; LL | let a @ &mut ref mut b = &mut U;
| -^^^^^^^^--------- | ^ --------- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `&mut U` which does not implement the `Copy` trait | move occurs because `a` has type `&mut U` which does not implement the `Copy` trait
| |
@ -139,9 +119,8 @@ error: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:72:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:72:9
| |
LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U);
| -^^^^^^^^^---------^^---------^ | ^ --------- --------- value borrowed here after move
| | | | | | |
| | | value borrowed here after move
| | value borrowed here after move | | value borrowed here after move
| value moved into `a` here | value moved into `a` here
| move occurs because `a` has type `&mut (U, U)` which does not implement the `Copy` trait | move occurs because `a` has type `&mut (U, U)` which does not implement the `Copy` trait
@ -155,117 +134,99 @@ error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:76:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:76:9
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^ | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:76:37 --> $DIR/borrowck-pat-ref-mut-twice.rs:76:37
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^ | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:82:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:82:9
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^ | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:82:37 --> $DIR/borrowck-pat-ref-mut-twice.rs:82:37
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^ | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:89:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:89:9
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^ | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:89:37 --> $DIR/borrowck-pat-ref-mut-twice.rs:89:37
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^ | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:101:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:101:9
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^ | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:101:37 --> $DIR/borrowck-pat-ref-mut-twice.rs:101:37
| |
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^ | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:8:11 --> $DIR/borrowck-pat-ref-mut-twice.rs:8:11
| |
LL | fn f1(ref mut a @ ref mut b: U) {} LL | fn f1(ref mut a @ ref mut b: U) {}
| ---------^^^--------- | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:10:11 --> $DIR/borrowck-pat-ref-mut-twice.rs:10:11
| |
LL | fn f2(ref mut a @ ref mut b: U) {} LL | fn f2(ref mut a @ ref mut b: U) {}
| ---------^^^--------- | ^^^^^^^^^ --------- value is mutably borrowed by `b` here
| | | | |
| | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:13:9 --> $DIR/borrowck-pat-ref-mut-twice.rs:13:9
| |
LL | ref mut a @ [ LL | ref mut a @ [
| ^-------- | ^^^^^^^^^ value is mutably borrowed by `a` here
| | LL |
| _________value is mutably borrowed by `a` here LL | [ref b @ .., _],
| | | ----- value is borrowed by `b` here
LL | | LL | [_, ref mut mid @ ..],
LL | | [ref b @ .., _], | ----------- value is mutably borrowed by `mid` here
| | ---------- value is borrowed by `b` here
LL | | [_, ref mut mid @ ..],
| | ---------------- value is mutably borrowed by `mid` here
LL | | ..,
LL | | [..],
LL | | ] : [[U; 4]; 5]
| |_________^
error: cannot borrow value as mutable more than once at a time error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:21:22 --> $DIR/borrowck-pat-ref-mut-twice.rs:21:22
| |
LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {}
| ---------^^^------------- | ^^^^^^^^^ --------- - value is moved into `c` here
| | | | | | |
| | | value is moved into `c` here
| | value is mutably borrowed by `b` here | | value is mutably borrowed by `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
@ -273,9 +234,8 @@ error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-ref-mut-twice.rs:21:34 --> $DIR/borrowck-pat-ref-mut-twice.rs:21:34
| |
LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {}
| ---------^^^- | ^^^^^^^^^ - value is moved into `c` here
| | | | |
| | value is moved into `c` here
| value is mutably borrowed by `b` here | value is mutably borrowed by `b` here
error[E0499]: cannot borrow value as mutable more than once at a time error[E0499]: cannot borrow value as mutable more than once at a time

View file

@ -2,36 +2,32 @@ error: cannot move out of value because it is borrowed
--> $DIR/default-binding-modes-both-sides-independent.rs:26:9 --> $DIR/default-binding-modes-both-sides-independent.rs:26:9
| |
LL | let ref a @ b = NotCopy; LL | let ref a @ b = NotCopy;
| -----^^^- | ^^^^^ - value is moved into `b` here
| | | | |
| | value is moved into `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/default-binding-modes-both-sides-independent.rs:29:9 --> $DIR/default-binding-modes-both-sides-independent.rs:29:9
| |
LL | let ref mut a @ b = NotCopy; LL | let ref mut a @ b = NotCopy;
| ---------^^^- | ^^^^^^^^^ - value is moved into `b` here
| | | | |
| | value is moved into `b` here
| value is mutably borrowed by `a` here | value is mutably borrowed by `a` here
error: cannot move out of value because it is borrowed error: cannot move out of value because it is borrowed
--> $DIR/default-binding-modes-both-sides-independent.rs:34:12 --> $DIR/default-binding-modes-both-sides-independent.rs:34:12
| |
LL | Ok(ref a @ b) | Err(b @ ref a) => { LL | Ok(ref a @ b) | Err(b @ ref a) => {
| -----^^^- | ^^^^^ - value is moved into `b` here
| | | | |
| | value is moved into `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error: borrow of moved value error: borrow of moved value
--> $DIR/default-binding-modes-both-sides-independent.rs:34:29 --> $DIR/default-binding-modes-both-sides-independent.rs:34:29
| |
LL | Ok(ref a @ b) | Err(b @ ref a) => { LL | Ok(ref a @ b) | Err(b @ ref a) => {
| -^^^----- | ^ ----- value borrowed here after move
| | | | |
| | value borrowed here after move
| value moved into `b` here | value moved into `b` here
| move occurs because `b` has type `NotCopy` which does not implement the `Copy` trait | move occurs because `b` has type `NotCopy` which does not implement the `Copy` trait
| |
@ -44,9 +40,8 @@ error: cannot move out of value because it is borrowed
--> $DIR/default-binding-modes-both-sides-independent.rs:42:9 --> $DIR/default-binding-modes-both-sides-independent.rs:42:9
| |
LL | ref a @ b => { LL | ref a @ b => {
| -----^^^- | ^^^^^ - value is moved into `b` here
| | | | |
| | value is moved into `b` here
| value is borrowed by `a` here | value is borrowed by `a` here
error[E0382]: borrow of moved value error[E0382]: borrow of moved value

View file

@ -9,8 +9,8 @@ LL | let 5 = 6;
= note: the matched value is of type `i32` = note: the matched value is of type `i32`
help: you might want to use `if let` to ignore the variants that aren't matched 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 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; LL | let _5 = 6;
@ -20,7 +20,7 @@ error[E0005]: refutable pattern in local binding
--> $DIR/issue-106552.rs:5:9 --> $DIR/issue-106552.rs:5:9
| |
LL | let x @ 5 = 6; 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: `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: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html

View file

@ -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 error[E0158]: associated consts cannot be referenced in patterns
--> $DIR/issue-68393-let-pat-assoc-constant.rs:22:9 --> $DIR/issue-68393-let-pat-assoc-constant.rs:22:9
| |
LL | let A::X = arg; 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 error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0158`. For more information about this error, try `rustc --explain E0158`.

View file

@ -4,7 +4,7 @@ fn main() {
match Some(1) { //~ ERROR non-exhaustive patterns: `None` not covered match Some(1) { //~ ERROR non-exhaustive patterns: `None` not covered
Some(1) => {} Some(1) => {}
// hello // hello
Some(_) => {} Some(_) => {},
None => todo!() None => todo!()
} }
} }

View file

@ -12,7 +12,7 @@ note: `Option<i32>` defined here
= note: the matched value is of type `Option<i32>` = 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 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!() LL + None => todo!()
| |

View file

@ -7,21 +7,6 @@ LL | FOO => {}
= note: the traits must be derived, manual `impl`s are not sufficient = 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 = 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)]` 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 --> $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: 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 = 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)]` 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 --> $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: 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 = 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)]` 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 --> $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: 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 = 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)]` 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 --> $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: 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 = 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 error: unreachable pattern
--> $DIR/consts-opaque.rs:72:9 --> $DIR/consts-opaque.rs:72:9
| |
@ -141,15 +168,6 @@ LL | BAR => {}
LL | _ => {} // should not be emitting unreachable warning LL | _ => {} // should not be emitting unreachable warning
| ^ unreachable pattern | ^ 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 error: unreachable pattern
--> $DIR/consts-opaque.rs:82:9 --> $DIR/consts-opaque.rs:82:9
| |
@ -168,15 +186,6 @@ LL | BAZ => {}
LL | _ => {} LL | _ => {}
| ^ unreachable pattern | ^ 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 error: unreachable pattern
--> $DIR/consts-opaque.rs:92:9 --> $DIR/consts-opaque.rs:92:9
| |
@ -186,15 +195,6 @@ LL |
LL | _ => {} LL | _ => {}
| ^ unreachable pattern | ^ 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 error: unreachable pattern
--> $DIR/consts-opaque.rs:99:9 --> $DIR/consts-opaque.rs:99:9
| |

View file

@ -12,7 +12,7 @@ LL | pub enum HiddenEnum {
= note: the matched value is of type `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 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!() LL + _ => todo!()
| |
@ -33,7 +33,7 @@ LL | B,
= note: the matched value is of type `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 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!() LL + HiddenEnum::B => todo!()
| |
@ -54,7 +54,7 @@ LL | B,
= note: the matched value is of type `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, a match arm with multiple or-patterns as shown, or multiple match arms 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!() LL + HiddenEnum::B | _ => todo!()
| |
@ -72,7 +72,7 @@ note: `Option<HiddenEnum>` defined here
= note: the matched value is of type `Option<HiddenEnum>` = 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 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!() LL + Some(HiddenEnum::B) | Some(_) => todo!()
| |
@ -93,7 +93,7 @@ LL | C,
= note: the matched value is of type `InCrate` = 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 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!() LL + InCrate::C => todo!()
| |

View file

@ -162,7 +162,7 @@ LL | match_guarded_arm!(0u8);
= note: the matched value is of type `u8` = 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 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!() LL + _ => todo!()
| |
@ -180,7 +180,7 @@ LL | struct NonEmptyStruct1;
= note: the matched value is of type `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 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!() LL + NonEmptyStruct1 => todo!()
| |
@ -198,7 +198,7 @@ LL | struct NonEmptyStruct2(bool);
= note: the matched value is of type `NonEmptyStruct2` = 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 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!() LL + NonEmptyStruct2(_) => todo!()
| |
@ -216,7 +216,7 @@ LL | union NonEmptyUnion1 {
= note: the matched value is of type `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 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!() LL + NonEmptyUnion1 { .. } => todo!()
| |
@ -234,7 +234,7 @@ LL | union NonEmptyUnion2 {
= note: the matched value is of type `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 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!() LL + NonEmptyUnion2 { .. } => todo!()
| |
@ -254,7 +254,7 @@ LL | Foo(bool),
= note: the matched value is of type `NonEmptyEnum1` = 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 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!() LL + NonEmptyEnum1::Foo(_) => todo!()
| |
@ -276,7 +276,7 @@ LL | Bar,
= note: the matched value is of type `NonEmptyEnum2` = 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 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!() LL + NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
| |
@ -294,7 +294,7 @@ LL | enum NonEmptyEnum5 {
= note: the matched value is of type `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 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!() LL + _ => todo!()
| |

View file

@ -162,7 +162,7 @@ LL | match_guarded_arm!(0u8);
= note: the matched value is of type `u8` = 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 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!() LL + _ => todo!()
| |
@ -180,7 +180,7 @@ LL | struct NonEmptyStruct1;
= note: the matched value is of type `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 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!() LL + NonEmptyStruct1 => todo!()
| |
@ -198,7 +198,7 @@ LL | struct NonEmptyStruct2(bool);
= note: the matched value is of type `NonEmptyStruct2` = 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 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!() LL + NonEmptyStruct2(_) => todo!()
| |
@ -216,7 +216,7 @@ LL | union NonEmptyUnion1 {
= note: the matched value is of type `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 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!() LL + NonEmptyUnion1 { .. } => todo!()
| |
@ -234,7 +234,7 @@ LL | union NonEmptyUnion2 {
= note: the matched value is of type `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 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!() LL + NonEmptyUnion2 { .. } => todo!()
| |
@ -254,7 +254,7 @@ LL | Foo(bool),
= note: the matched value is of type `NonEmptyEnum1` = 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 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!() LL + NonEmptyEnum1::Foo(_) => todo!()
| |
@ -276,7 +276,7 @@ LL | Bar,
= note: the matched value is of type `NonEmptyEnum2` = 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 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!() LL + NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
| |
@ -294,7 +294,7 @@ LL | enum NonEmptyEnum5 {
= note: the matched value is of type `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 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!() LL + _ => todo!()
| |

View file

@ -7,7 +7,7 @@ LL | match 0.0 {
= note: the matched value is of type `f64` = 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 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!() LL + _ => todo!()
| |

View file

@ -7,7 +7,7 @@ LL | match 0u8 {
= note: the matched value is of type `u8` = 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 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!() LL + 128_u8..=u8::MAX => todo!()
| |

View file

@ -91,7 +91,7 @@ LL | match 0i8 {
= note: the matched value is of type `i8` = 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 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!() LL + 0_i8 => todo!()
| |
@ -140,7 +140,7 @@ LL | match (0u8, true) {
= note: the matched value is of type `(u8, bool)` = 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 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!() LL + (126_u8..=127_u8, false) => todo!()
| |

View file

@ -9,7 +9,7 @@ LL | match 0usize {
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = 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 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!() 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: 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 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!() 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: 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 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!() LL + _ => todo!()
| |

View file

@ -9,7 +9,7 @@ LL | match 0usize {
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching = 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 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!() 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: 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 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!() LL + _ => todo!()
| |

View file

@ -7,7 +7,7 @@ LL | match (a, b) {
= note: the matched value is of type `(Option<usize>, Option<usize>)` = 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 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!() LL + (None, None) | (Some(_), Some(_)) => todo!()
| |

View file

@ -7,7 +7,7 @@ LL | match "world" {
= note: the matched value is of type `&str` = 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 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!() LL + &_ => todo!()
| |
@ -20,7 +20,7 @@ LL | match "world" {
= note: the matched value is of type `&str` = 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 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!() LL + &_ => todo!()
| |

View file

@ -7,7 +7,7 @@ LL | match (A, ()) {
= note: the matched value is of type `(Enum, ())` = 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 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!() LL + _ => todo!()
| |
@ -20,7 +20,7 @@ LL | match (A, A) {
= note: the matched value is of type `(Enum, Enum)` = 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 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!() LL + _ => todo!()
| |
@ -33,7 +33,7 @@ LL | match ((A, ()), ()) {
= note: the matched value is of type `((Enum, ()), ())` = 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 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!() LL + _ => todo!()
| |
@ -46,7 +46,7 @@ LL | match ((A, ()), A) {
= note: the matched value is of type `((Enum, ()), Enum)` = 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 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!() LL + _ => todo!()
| |
@ -59,7 +59,7 @@ LL | match ((A, ()), ()) {
= note: the matched value is of type `((Enum, ()), ())` = 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 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!() LL + _ => todo!()
| |
@ -77,7 +77,7 @@ LL | struct S(Enum, ());
= note: the matched value is of type `S` = 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 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!() LL + _ => todo!()
| |
@ -95,7 +95,7 @@ LL | struct Sd { x: Enum, y: () }
= note: the matched value is of type `Sd` = 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 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!() LL + _ => todo!()
| |

View file

@ -9,7 +9,7 @@ note: `Box<ElementKind>` defined here
= note: the matched value is of type `Box<ElementKind>` = 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 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!() LL + box _ => todo!()
| |

View file

@ -12,7 +12,7 @@ LL | pub struct Tag(pub Context, pub u16);
= note: the matched value is of type `Tag` = 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 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!() LL + Tag(Context::Exif, _) => todo!()
| |

View file

@ -18,7 +18,7 @@ LL | C(bool),
= note: the matched value is of type `Foo` = 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 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!() LL + Foo::A(false) | Foo::B(false) | Foo::C(false) => todo!()
| |

View file

@ -7,7 +7,7 @@ LL | match buf {
= note: the matched value is of type `&[u8; 4]` = 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 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!() 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]` = 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 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!() LL + _ => todo!()
| |

View file

@ -12,7 +12,7 @@ note: `Option<Private>` defined here
= note: the matched value is of type `Option<Private>` = 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 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!() LL + Some(Private { misc: true, .. }) => todo!()
| |

View file

@ -7,7 +7,7 @@ LL | match list {
= note: the matched value is of type `&[Option<()>]` = 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 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!(), LL ~ &[_, Some(_), .., None, _] => todo!(),
| |

View file

@ -18,7 +18,7 @@ LL | C
= note: the matched value is of type `E` = 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 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!() LL + E::B | E::C => todo!()
| |
@ -44,8 +44,8 @@ LL | C
= note: the matched value is of type `E` = note: the matched value is of type `E`
help: you might want to use `if let` to ignore the variants that aren't matched 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 error[E0004]: non-exhaustive patterns: `&E::B` and `&E::C` not covered
--> $DIR/non-exhaustive-defined-here.rs:50:11 --> $DIR/non-exhaustive-defined-here.rs:50:11
@ -67,7 +67,7 @@ LL | C
= note: the matched value is of type `&E` = 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 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!() LL + &E::B | &E::C => todo!()
| |
@ -93,8 +93,8 @@ LL | C
= note: the matched value is of type `&E` = note: the matched value is of type `&E`
help: you might want to use `if let` to ignore the variants that aren't matched 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 error[E0004]: non-exhaustive patterns: `&&mut &E::B` and `&&mut &E::C` not covered
--> $DIR/non-exhaustive-defined-here.rs:66:11 --> $DIR/non-exhaustive-defined-here.rs:66:11
@ -116,7 +116,7 @@ LL | C
= note: the matched value is of type `&&mut &E` = 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 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!() LL + &&mut &E::B | &&mut &E::C => todo!()
| |
@ -142,8 +142,8 @@ LL | C
= note: the matched value is of type `&&mut &E` = 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 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 error[E0004]: non-exhaustive patterns: `Opt::None` not covered
--> $DIR/non-exhaustive-defined-here.rs:92:11 --> $DIR/non-exhaustive-defined-here.rs:92:11
@ -162,7 +162,7 @@ LL | None,
= note: the matched value is of type `Opt` = 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 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!() LL + Opt::None => todo!()
| |

View file

@ -25,7 +25,7 @@ LL | enum T { A(U), B }
= note: the matched value is of type `T` = 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 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!() LL + T::A(U::C) => todo!()
| |

View file

@ -24,7 +24,7 @@ LL | match true {
= note: the matched value is of type `bool` = 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 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!() LL + false => todo!()
| |
@ -42,7 +42,7 @@ note: `Option<i32>` defined here
= note: the matched value is of type `Option<i32>` = 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 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!() LL + Some(_) => todo!()
| |
@ -55,7 +55,7 @@ LL | match (2, 3, 4) {
= note: the matched value is of type `(i32, i32, i32)` = 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 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!() 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)` = 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 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!() 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` = 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 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!() LL + T::B => todo!()
| |
@ -99,7 +99,7 @@ LL | match *vec {
= note: the matched value is of type `[Option<isize>]` = 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 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!() LL + [] => todo!()
| |

View file

@ -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))` = 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 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 error: aborting due to 2 previous errors

View file

@ -5,6 +5,10 @@ LL | let f = |3: isize| println!("hello");
| ^ pattern `_` not covered | ^ pattern `_` not covered
| |
= note: the matched value is of type `isize` = note: the matched value is of type `isize`
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
LL | let f = |_3: isize| println!("hello");
| +
error: aborting due to previous error error: aborting due to previous error

View file

@ -7,7 +7,7 @@ LL | match s2 {
= note: the matched value is of type `&[bool; 2]` = 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 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!() LL + &[false, _] => todo!()
| |
@ -20,7 +20,7 @@ LL | match s3 {
= note: the matched value is of type `&[bool; 3]` = 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 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!() LL + &[false, ..] => todo!()
| |
@ -33,7 +33,7 @@ LL | match s10 {
= note: the matched value is of type `&[bool; 10]` = 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 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!() LL + &[false, ..] => todo!()
| |
@ -46,7 +46,7 @@ LL | match s2 {
= note: the matched value is of type `&[bool; 2]` = 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 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!() LL + &[false, true] => todo!()
| |
@ -59,7 +59,7 @@ LL | match s3 {
= note: the matched value is of type `&[bool; 3]` = 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 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!() LL + &[false, .., true] => todo!()
| |
@ -72,7 +72,7 @@ LL | match s {
= note: the matched value is of type `&[bool]` = 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 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!() LL + &[false, .., true] => todo!()
| |
@ -85,7 +85,7 @@ LL | match s {
= note: the matched value is of type `&[bool]` = 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 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!() LL + &[_, ..] => todo!()
| |
@ -98,7 +98,7 @@ LL | match s {
= note: the matched value is of type `&[bool]` = 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 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!() LL + &[_, _, ..] => todo!()
| |
@ -111,7 +111,7 @@ LL | match s {
= note: the matched value is of type `&[bool]` = 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 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!() LL + &[false, ..] => todo!()
| |
@ -124,7 +124,7 @@ LL | match s {
= note: the matched value is of type `&[bool]` = 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 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!() LL + &[false, _, ..] => todo!()
| |
@ -137,7 +137,7 @@ LL | match s {
= note: the matched value is of type `&[bool]` = 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 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!() LL + &[_, .., false] => todo!()
| |
@ -150,7 +150,7 @@ LL | match s {
= note: the matched value is of type `&[bool]` = 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 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!() LL + &[_, _, .., true] => todo!()
| |
@ -163,7 +163,7 @@ LL | match s {
= note: the matched value is of type `&[bool]` = 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 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!() LL + &[true, _, .., _] => todo!()
| |
@ -176,7 +176,7 @@ LL | match s {
= note: the matched value is of type `&[bool]` = 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 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!() LL + &[] | &[_, _, ..] => todo!()
| |
@ -189,7 +189,7 @@ LL | match s {
= note: the matched value is of type `&[bool]` = 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 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!() LL + &[] | &[_, _, ..] => todo!()
| |
@ -202,7 +202,7 @@ LL | match s {
= note: the matched value is of type `&[bool]` = 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 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!() LL + &[] | &[_, _, ..] => todo!()
| |
@ -215,7 +215,7 @@ LL | match s {
= note: the matched value is of type `&[bool]` = 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 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!() LL + &[] | &[_, _, ..] => todo!()
| |
@ -228,7 +228,7 @@ LL | match s {
= note: the matched value is of type `&[bool]` = 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 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!() LL + &[_, _, ..] => todo!()
| |
@ -241,7 +241,7 @@ LL | match s {
= note: the matched value is of type `&[bool]` = 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 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!() LL + &[false] => todo!()
| |
@ -254,7 +254,7 @@ LL | match s1 {
= note: the matched value is of type `&[bool; 1]` = 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 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!() LL + &[false] => todo!()
| |

View file

@ -15,7 +15,7 @@ LL | Stable2,
= note: the matched value is of type `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, a match arm with multiple or-patterns as shown, or multiple match arms 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!() LL + UnstableEnum::Stable2 | _ => todo!()
| |
@ -33,7 +33,7 @@ LL | pub enum UnstableEnum {
= note: the matched value is of type `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 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!() LL + _ => todo!()
| |

View file

@ -14,7 +14,7 @@ LL | B { x: Option<isize> },
= note: the matched value is of type `A` = 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 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!() LL + A::B { x: Some(_) } => todo!()
| |

View file

@ -15,7 +15,7 @@ LL | Unstable,
= note: the matched value is of type `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 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!() LL + UnstableEnum::Unstable => todo!()
| |

View file

@ -4,10 +4,8 @@ fn main() {
match 0u8 { match 0u8 {
251..257 => {} 251..257 => {}
//~^ ERROR literal out of range //~^ ERROR literal out of range
//~| ERROR literal out of range
251..=256 => {} 251..=256 => {}
//~^ ERROR literal out of range //~^ ERROR literal out of range
//~| ERROR literal out of range
_ => {} _ => {}
} }
} }

Some files were not shown because too many files have changed in this diff Show more