hir::LocalSource::ForLoopDesugar => ("`for` loop binding", None),
hir::LocalSource::AsyncFn => ("async fn binding", None),
hir::LocalSource::AwaitDesugar => ("`await` future binding", None),
+ hir::LocalSource::AssignDesugar(_) => ("destructuring assignment binding", None),
};
self.check_irrefutable(&loc.pat, msg, sp);
- self.check_patterns(false, &loc.pat);
+ self.check_patterns(&loc.pat);
}
fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
intravisit::walk_param(self, param);
self.check_irrefutable(¶m.pat, "function argument", None);
- self.check_patterns(false, ¶m.pat);
+ self.check_patterns(¶m.pat);
}
}
}
PatternError::FloatBug => {
// FIXME(#31407) this is only necessary because float parsing is buggy
- ::rustc_middle::mir::interpret::struct_error(
+ rustc_middle::mir::interpret::struct_error(
self.tcx.at(pat_span),
"could not evaluate float literal (see issue #31407)",
)
.emit();
}
PatternError::NonConstPath(span) => {
- ::rustc_middle::mir::interpret::struct_error(
+ rustc_middle::mir::interpret::struct_error(
self.tcx.at(span),
"runtime values cannot be referenced in patterns",
)
}
impl<'tcx> MatchVisitor<'_, 'tcx> {
- fn check_patterns(&mut self, has_guard: bool, pat: &Pat<'_>) {
- if !self.tcx.features().move_ref_pattern {
- check_legality_of_move_bindings(self, has_guard, pat);
- }
+ fn check_patterns(&mut self, pat: &Pat<'_>) {
pat.walk_always(|pat| check_borrow_conflicts_in_at_patterns(self, pat));
if !self.tcx.features().bindings_after_at {
check_legality_of_bindings_in_at_patterns(self, pat);
patcx.include_lint_checks();
let pattern = patcx.lower_pattern(pat);
let pattern_ty = pattern.ty;
- let pattern: &_ = cx.pattern_arena.alloc(expand_pattern(cx, pattern));
+ let pattern: &_ = cx.pattern_arena.alloc(expand_pattern(pattern));
if !patcx.errors.is_empty() {
*have_errors = true;
patcx.report_inlining_errors(pat.span);
) {
for arm in arms {
// Check the arm for some things unrelated to exhaustiveness.
- self.check_patterns(arm.guard.is_some(), &arm.pat);
+ self.check_patterns(&arm.pat);
}
let mut cx = self.new_cx(scrut.hir_id);
hir::MatchSource::AwaitDesugar | hir::MatchSource::TryDesugar => {}
}
}
- Useful(unreachable_subpatterns) => {
- for span in unreachable_subpatterns {
+ Useful(unreachables) => {
+ let mut unreachables: Vec<_> = unreachables.into_iter().flatten().collect();
+ // Emit lints in the order in which they occur in the file.
+ unreachables.sort_unstable();
+ for span in unreachables {
unreachable_pattern(cx.tcx, span, id, None);
}
}
!cx.typeck_results.node_type(hir_id).is_copy_modulo_regions(cx.tcx.at(span), cx.param_env)
}
-/// Check the legality of legality of by-move bindings.
-fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: bool, pat: &Pat<'_>) {
- let sess = cx.tcx.sess;
- let typeck_results = cx.typeck_results;
-
- // Find all by-ref spans.
- let mut by_ref_spans = Vec::new();
- pat.each_binding(|_, hir_id, span, _| {
- if let Some(ty::BindByReference(_)) =
- typeck_results.extract_binding_mode(sess, hir_id, span)
- {
- by_ref_spans.push(span);
- }
- });
-
- // Find bad by-move spans:
- let by_move_spans = &mut Vec::new();
- let mut check_move = |p: &Pat<'_>, sub: Option<&Pat<'_>>| {
- // Check legality of moving out of the enum.
- //
- // `x @ Foo(..)` is legal, but `x @ Foo(y)` isn't.
- if sub.map_or(false, |p| p.contains_bindings()) {
- struct_span_err!(sess, p.span, E0007, "cannot bind by-move with sub-bindings")
- .span_label(p.span, "binds an already bound by-move value by moving it")
- .emit();
- } else if !has_guard && !by_ref_spans.is_empty() {
- by_move_spans.push(p.span);
- }
- };
- pat.walk_always(|p| {
- if let hir::PatKind::Binding(.., sub) = &p.kind {
- if let Some(ty::BindByValue(_)) =
- typeck_results.extract_binding_mode(sess, p.hir_id, p.span)
- {
- if is_binding_by_move(cx, p.hir_id, p.span) {
- check_move(p, sub.as_deref());
- }
- }
- }
- });
-
- // Found some bad by-move spans, error!
- if !by_move_spans.is_empty() {
- let mut err = feature_err(
- &sess.parse_sess,
- sym::move_ref_pattern,
- by_move_spans.clone(),
- "binding by-move and by-ref in the same pattern is unstable",
- );
- for span in by_ref_spans.iter() {
- err.span_label(*span, "by-ref pattern here");
- }
- for span in by_move_spans.iter() {
- err.span_label(*span, "by-move pattern here");
- }
- err.emit();
- }
-}
-
/// Check that there are no borrow or move conflicts in `binding @ subpat` patterns.
///
/// For example, this would reject: