diff options
| author | Cameron Steffen <cam.steffen94@gmail.com> | 2021-10-25 23:33:12 -0500 |
|---|---|---|
| committer | Cameron Steffen <cam.steffen94@gmail.com> | 2021-11-21 08:15:21 -0600 |
| commit | 9c83f8c4d1e562cd73a29a00828d68e2b520a086 (patch) | |
| tree | a7b824c188a775e1de44c0e9c44dffe2d039c78f /compiler | |
| parent | 3bfde2f1f4fc9409ecb63dfe1370df66171cf861 (diff) | |
| download | rust-9c83f8c4d1e562cd73a29a00828d68e2b520a086.tar.gz rust-9c83f8c4d1e562cd73a29a00828d68e2b520a086.zip | |
Simplify for loop desugar
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_ast_lowering/src/expr.rs | 137 | ||||
| -rw-r--r-- | compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_borrowck/src/diagnostics/mod.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs | 24 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/hir.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/pat_util.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs | 24 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/lint.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/check_match.rs | 21 | ||||
| -rw-r--r-- | compiler/rustc_span/src/hygiene.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_span/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs | 7 |
13 files changed, 118 insertions, 149 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 405e9035c4c..a0a63620c08 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -13,7 +13,7 @@ use rustc_session::parse::feature_err; use rustc_span::hygiene::ExpnId; use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned}; use rustc_span::symbol::{sym, Ident, Symbol}; -use rustc_span::{hygiene::ForLoopLoc, DUMMY_SP}; +use rustc_span::DUMMY_SP; impl<'hir> LoweringContext<'_, 'hir> { fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] { @@ -1308,16 +1308,13 @@ impl<'hir> LoweringContext<'_, 'hir> { /// Desugar `ExprForLoop` from: `[opt_ident]: for <pat> in <head> <body>` into: /// ```rust /// { - /// let result = match ::std::iter::IntoIterator::into_iter(<head>) { + /// let result = match IntoIterator::into_iter(<head>) { /// mut iter => { /// [opt_ident]: loop { - /// let mut __next; - /// match ::std::iter::Iterator::next(&mut iter) { - /// ::std::option::Option::Some(val) => __next = val, - /// ::std::option::Option::None => break + /// match Iterator::next(&mut iter) { + /// None => break, + /// Some(<pat>) => <body>, /// }; - /// let <pat> = __next; - /// StmtKind::Expr(<body>); /// } /// } /// }; @@ -1332,133 +1329,75 @@ impl<'hir> LoweringContext<'_, 'hir> { body: &Block, opt_label: Option<Label>, ) -> hir::Expr<'hir> { - // expand <head> let head = self.lower_expr_mut(head); - let desugared_span = - self.mark_span_with_reason(DesugaringKind::ForLoop(ForLoopLoc::Head), head.span, None); - let e_span = self.lower_span(e.span); - - let iter = Ident::with_dummy_span(sym::iter); - - let next_ident = Ident::with_dummy_span(sym::__next); - let (next_pat, next_pat_hid) = self.pat_ident_binding_mode( - desugared_span, - next_ident, - hir::BindingAnnotation::Mutable, - ); - - // `::std::option::Option::Some(val) => __next = val` - let pat_arm = { - let val_ident = Ident::with_dummy_span(sym::val); - let pat_span = self.lower_span(pat.span); - let (val_pat, val_pat_hid) = self.pat_ident(pat_span, val_ident); - let val_expr = self.expr_ident(pat_span, val_ident, val_pat_hid); - let next_expr = self.expr_ident(pat_span, next_ident, next_pat_hid); - let assign = self.arena.alloc(self.expr( - pat_span, - hir::ExprKind::Assign(next_expr, val_expr, self.lower_span(pat_span)), - ThinVec::new(), - )); - let some_pat = self.pat_some(pat_span, val_pat); - self.arm(some_pat, assign) - }; + let pat = self.lower_pat(pat); + let for_span = + self.mark_span_with_reason(DesugaringKind::ForLoop, self.lower_span(e.span), None); + let head_span = self.mark_span_with_reason(DesugaringKind::ForLoop, head.span, None); + let pat_span = self.mark_span_with_reason(DesugaringKind::ForLoop, pat.span, None); - // `::std::option::Option::None => break` - let break_arm = { + // `None => break` + let none_arm = { let break_expr = - self.with_loop_scope(e.id, |this| this.expr_break_alloc(e_span, ThinVec::new())); - let pat = self.pat_none(e_span); + self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span, ThinVec::new())); + let pat = self.pat_none(for_span); self.arm(pat, break_expr) }; + // Some(<pat>) => <body>, + let some_arm = { + let some_pat = self.pat_some(pat_span, pat); + let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false)); + let body_expr = self.arena.alloc(self.expr_block(body_block, ThinVec::new())); + self.arm(some_pat, body_expr) + }; + // `mut iter` + let iter = Ident::with_dummy_span(sym::iter); let (iter_pat, iter_pat_nid) = - self.pat_ident_binding_mode(desugared_span, iter, hir::BindingAnnotation::Mutable); + self.pat_ident_binding_mode(head_span, iter, hir::BindingAnnotation::Mutable); - // `match ::std::iter::Iterator::next(&mut iter) { ... }` + // `match Iterator::next(&mut iter) { ... }` let match_expr = { - let iter = self.expr_ident(desugared_span, iter, iter_pat_nid); - let ref_mut_iter = self.expr_mut_addr_of(desugared_span, iter); + let iter = self.expr_ident(head_span, iter, iter_pat_nid); + let ref_mut_iter = self.expr_mut_addr_of(head_span, iter); let next_expr = self.expr_call_lang_item_fn( - desugared_span, + head_span, hir::LangItem::IteratorNext, arena_vec![self; ref_mut_iter], ); - let arms = arena_vec![self; pat_arm, break_arm]; + let arms = arena_vec![self; none_arm, some_arm]; - self.expr_match(desugared_span, next_expr, arms, hir::MatchSource::ForLoopDesugar) + self.expr_match(head_span, next_expr, arms, hir::MatchSource::ForLoopDesugar) }; - let match_stmt = self.stmt_expr(desugared_span, match_expr); - - let next_expr = self.expr_ident(desugared_span, next_ident, next_pat_hid); - - // `let mut __next` - let next_let = self.stmt_let_pat( - None, - desugared_span, - None, - next_pat, - hir::LocalSource::ForLoopDesugar, - ); + let match_stmt = self.stmt_expr(for_span, match_expr); - // `let <pat> = __next` - let pat = self.lower_pat(pat); - let pat_let = self.stmt_let_pat( - None, - desugared_span, - Some(next_expr), - pat, - hir::LocalSource::ForLoopDesugar, - ); - - let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false)); - let body_expr = self.expr_block(body_block, ThinVec::new()); - let body_stmt = self.stmt_expr(body_block.span, body_expr); - - let loop_block = self.block_all( - e_span, - arena_vec![self; next_let, match_stmt, pat_let, body_stmt], - None, - ); + let loop_block = self.block_all(for_span, arena_vec![self; match_stmt], None); // `[opt_ident]: loop { ... }` let kind = hir::ExprKind::Loop( loop_block, self.lower_label(opt_label), hir::LoopSource::ForLoop, - self.lower_span(e_span.with_hi(head.span.hi())), + self.lower_span(for_span.with_hi(head.span.hi())), ); - let loop_expr = self.arena.alloc(hir::Expr { - hir_id: self.lower_node_id(e.id), - kind, - span: self.lower_span(e.span), - }); + let loop_expr = + self.arena.alloc(hir::Expr { hir_id: self.lower_node_id(e.id), kind, span: for_span }); // `mut iter => { ... }` let iter_arm = self.arm(iter_pat, loop_expr); - let into_iter_span = self.mark_span_with_reason( - DesugaringKind::ForLoop(ForLoopLoc::IntoIter), - head.span, - None, - ); - // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }` let into_iter_expr = { self.expr_call_lang_item_fn( - into_iter_span, + head_span, hir::LangItem::IntoIterIntoIter, arena_vec![self; head], ) }; - // #82462: to correctly diagnose borrow errors, the block that contains - // the iter expr needs to have a span that covers the loop body. - let desugared_full_span = - self.mark_span_with_reason(DesugaringKind::ForLoop(ForLoopLoc::Head), e_span, None); - let match_expr = self.arena.alloc(self.expr_match( - desugared_full_span, + for_span, into_iter_expr, arena_vec![self; iter_arm], hir::MatchSource::ForLoopDesugar, @@ -1472,7 +1411,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // surrounding scope of the `match` since the `match` is not a terminating scope. // // Also, add the attributes to the outer returned expr node. - self.expr_drop_temps_mut(desugared_full_span, match_expr, attrs.into()) + self.expr_drop_temps_mut(for_span, match_expr, attrs.into()) } /// Desugar `ExprKind::Try` from: `<expr>?` into: diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 79973ab170c..db8268c8e2e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -13,7 +13,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::{self, RegionVid, TyCtxt}; use rustc_span::symbol::Symbol; -use rustc_span::Span; +use rustc_span::{sym, DesugaringKind, Span}; use crate::region_infer::BlameConstraint; use crate::{ @@ -135,7 +135,16 @@ impl BorrowExplanation { should_note_order, } => { let local_decl = &body.local_decls[dropped_local]; - let (dtor_desc, type_desc) = match local_decl.ty.kind() { + let mut ty = local_decl.ty; + if local_decl.source_info.span.desugaring_kind() == Some(DesugaringKind::ForLoop) { + if let ty::Adt(adt, substs) = local_decl.ty.kind() { + if tcx.is_diagnostic_item(sym::Option, adt.did) { + // in for loop desugaring, only look at the `Some(..)` inner type + ty = substs.type_at(0); + } + } + } + let (dtor_desc, type_desc) = match ty.kind() { // If type is an ADT that implements Drop, then // simplify output by reporting just the ADT name. ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => { diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index a4df277a7b0..79623e26eb7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -13,11 +13,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::print::Print; use rustc_middle::ty::{self, DefIdTree, Instance, Ty, TyCtxt}; use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult}; -use rustc_span::{ - hygiene::{DesugaringKind, ForLoopLoc}, - symbol::sym, - Span, -}; +use rustc_span::{hygiene::DesugaringKind, symbol::sym, Span}; use rustc_target::abi::VariantIdx; use super::borrow_set::BorrowData; @@ -955,10 +951,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let kind = kind.unwrap_or_else(|| { // This isn't a 'special' use of `self` debug!("move_spans: method_did={:?}, fn_call_span={:?}", method_did, fn_call_span); - let implicit_into_iter = matches!( - fn_call_span.desugaring_kind(), - Some(DesugaringKind::ForLoop(ForLoopLoc::IntoIter)) - ); + let implicit_into_iter = Some(method_did) == tcx.lang_items().into_iter_fn() + && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop); let parent_self_ty = parent .filter(|did| tcx.def_kind(*did) == rustc_hir::def::DefKind::Impl) .and_then(|did| match tcx.type_of(did).kind() { diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index d5ff4c6766f..46e2a99a0d0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -445,15 +445,23 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }, ))) => { // check if the RHS is from desugaring - let locations = self.body.find_assignments(local); - let opt_assignment_rhs_span = locations - .first() - .map(|&location| self.body.source_info(location).span); - let opt_desugaring_kind = - opt_assignment_rhs_span.and_then(|span| span.desugaring_kind()); - match opt_desugaring_kind { + let opt_assignment_rhs_span = + self.body.find_assignments(local).first().map(|&location| { + let stmt = &self.body[location.block].statements + [location.statement_index]; + match stmt.kind { + mir::StatementKind::Assign(box ( + _, + mir::Rvalue::Use(mir::Operand::Copy(place)), + )) => { + self.body.local_decls[place.local].source_info.span + } + _ => self.body.source_info(location).span, + } + }); + match opt_assignment_rhs_span.and_then(|s| s.desugaring_kind()) { // on for loops, RHS points to the iterator part - Some(DesugaringKind::ForLoop(_)) => { + Some(DesugaringKind::ForLoop) => { self.suggest_similar_mut_method_for_for_loop(&mut err); Some(( false, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index a4db57bfc11..c67d3df3ded 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1821,8 +1821,6 @@ impl<'hir> QPath<'hir> { pub enum LocalSource { /// A `match _ { .. }`. Normal, - /// A desugared `for _ in _ { .. }` loop. - ForLoopDesugar, /// When lowering async functions, we create locals within the `async move` so that /// all parameters are dropped after the future is polled. /// diff --git a/compiler/rustc_hir/src/pat_util.rs b/compiler/rustc_hir/src/pat_util.rs index b1f78a83e74..b30076100bb 100644 --- a/compiler/rustc_hir/src/pat_util.rs +++ b/compiler/rustc_hir/src/pat_util.rs @@ -2,6 +2,7 @@ use crate::def::{CtorOf, DefKind, Res}; use crate::def_id::DefId; use crate::hir::{self, HirId, PatKind}; use rustc_data_structures::stable_set::FxHashSet; +use rustc_span::hygiene::DesugaringKind; use rustc_span::symbol::Ident; use rustc_span::Span; @@ -143,4 +144,14 @@ impl hir::Pat<'_> { }); result } + + /// If the pattern is `Some(<pat>)` from a desugared for loop, returns the inner pattern + pub fn for_loop_some(&self) -> Option<&Self> { + if self.span.desugaring_kind() == Some(DesugaringKind::ForLoop) { + if let hir::PatKind::Struct(_, [pat_field], _) = self.kind { + return Some(pat_field.pat); + } + } + None + } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index e00003face9..a7e019a53ee 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -5,13 +5,12 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; -use rustc_hir::{Body, Expr, ExprKind, FnRetTy, HirId, Local, Pat}; +use rustc_hir::{Body, Expr, ExprKind, FnRetTy, HirId, Local, MatchSource, Pat}; use rustc_middle::hir::map::Map; use rustc_middle::infer::unify_key::ConstVariableOriginKind; use rustc_middle::ty::print::Print; use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; use rustc_middle::ty::{self, DefIdTree, InferConst, Ty, TyCtxt}; -use rustc_span::source_map::DesugaringKind; use rustc_span::symbol::kw; use rustc_span::Span; use std::borrow::Cow; @@ -26,6 +25,7 @@ struct FindHirNodeVisitor<'a, 'tcx> { found_closure: Option<&'tcx Expr<'tcx>>, found_method_call: Option<&'tcx Expr<'tcx>>, found_exact_method_call: Option<&'tcx Expr<'tcx>>, + found_for_loop_iter: Option<&'tcx Expr<'tcx>>, found_use_diagnostic: Option<UseDiagnostic<'tcx>>, } @@ -41,6 +41,7 @@ impl<'a, 'tcx> FindHirNodeVisitor<'a, 'tcx> { found_closure: None, found_method_call: None, found_exact_method_call: None, + found_for_loop_iter: None, found_use_diagnostic: None, } } @@ -111,6 +112,15 @@ impl<'a, 'tcx> Visitor<'tcx> for FindHirNodeVisitor<'a, 'tcx> { } fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { + if let ExprKind::Match(scrutinee, [_, arm], MatchSource::ForLoopDesugar) = expr.kind { + if let Some(pat) = arm.pat.for_loop_some() { + if let Some(ty) = self.node_ty_contains_target(pat.hir_id) { + self.found_for_loop_iter = Some(scrutinee); + self.found_node_ty = Some(ty); + return; + } + } + } if let ExprKind::MethodCall(_, call_span, exprs, _) = expr.kind { if call_span == self.target_span && Some(self.target) @@ -643,10 +653,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let msg = if let Some(simple_ident) = pattern.simple_ident() { match pattern.span.desugaring_kind() { None => format!("consider giving `{}` {}", simple_ident, suffix), - Some(DesugaringKind::ForLoop(_)) => { - "the element type for this iterator is not specified".to_string() - } - _ => format!("this needs {}", suffix), + Some(_) => format!("this needs {}", suffix), } } else { format!("consider giving this pattern {}", suffix) @@ -719,6 +726,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // = note: type must be known at this point self.annotate_method_call(segment, e, &mut err); } + } else if let Some(scrutinee) = local_visitor.found_for_loop_iter { + err.span_label( + scrutinee.span, + "the element type for this iterator is not specified".to_string(), + ); } // Instead of the following: // error[E0282]: type annotations needed diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 0e70d49ef49..881b14278e9 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -395,7 +395,7 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { match expn_data.kind { ExpnKind::Inlined | ExpnKind::Root - | ExpnKind::Desugaring(DesugaringKind::ForLoop(_) | DesugaringKind::WhileLoop) => false, + | ExpnKind::Desugaring(DesugaringKind::ForLoop | DesugaringKind::WhileLoop) => false, ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external" ExpnKind::Macro(MacroKind::Bang, _) => { // Dummy span for the `def_site` means it's an external macro. diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index e28fd2c5081..d74c53fae53 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -74,19 +74,16 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, '_, 'tcx> { let (msg, sp) = match loc.source { hir::LocalSource::Normal => ("local binding", Some(loc.span)), - 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(&loc.pat, Irrefutable); } 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(¶m.pat, Irrefutable); } } @@ -161,12 +158,12 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { fn check_match( &mut self, scrut: &hir::Expr<'_>, - arms: &'tcx [hir::Arm<'tcx>], + hir_arms: &'tcx [hir::Arm<'tcx>], source: hir::MatchSource, ) { let mut cx = self.new_cx(scrut.hir_id); - for arm in arms { + for arm in hir_arms { // Check the arm for some things unrelated to exhaustiveness. self.check_patterns(&arm.pat, Refutable); if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard { @@ -178,7 +175,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { let mut have_errors = false; - let arms: Vec<_> = arms + let arms: Vec<_> = hir_arms .iter() .map(|hir::Arm { pat, guard, .. }| MatchArm { pat: self.lower_pattern(&mut cx, pat, &mut have_errors), @@ -196,6 +193,9 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { let report = compute_match_usefulness(&cx, &arms, scrut.hir_id, scrut_ty); match source { + // Don't report arm reachability of desugared `match $iter.into_iter() { iter => .. }` + // when the iterator is an uninhabited type. unreachable_code will trigger instead. + hir::MatchSource::ForLoopDesugar if arms.len() == 1 => {} hir::MatchSource::ForLoopDesugar | hir::MatchSource::Normal => { report_arm_reachability(&cx, &report) } @@ -208,7 +208,13 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { let is_empty_match = arms.is_empty(); let witnesses = report.non_exhaustiveness_witnesses; if !witnesses.is_empty() { - non_exhaustive_match(&cx, scrut_ty, scrut.span, witnesses, is_empty_match); + if source == hir::MatchSource::ForLoopDesugar && hir_arms.len() == 2 { + // the for loop pattern is not irrefutable + let pat = hir_arms[1].pat.for_loop_some().unwrap(); + self.check_irrefutable(pat, "`for` loop binding", None); + } else { + non_exhaustive_match(&cx, scrut_ty, scrut.span, witnesses, is_empty_match); + } } } @@ -225,6 +231,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { let witnesses = report.non_exhaustiveness_witnesses; if witnesses.is_empty() { // The pattern is irrefutable. + self.check_patterns(pat, Irrefutable); return; } diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 724d1904dc3..d590776676b 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1099,18 +1099,11 @@ pub enum DesugaringKind { OpaqueTy, Async, Await, - ForLoop(ForLoopLoc), + ForLoop, LetElse, WhileLoop, } -/// A location in the desugaring of a `for` loop -#[derive(Clone, Copy, PartialEq, Debug, Encodable, Decodable, HashStable_Generic)] -pub enum ForLoopLoc { - Head, - IntoIter, -} - impl DesugaringKind { /// The description wording should combine well with "desugaring of {}". pub fn descr(self) -> &'static str { @@ -1121,7 +1114,7 @@ impl DesugaringKind { DesugaringKind::QuestionMark => "operator `?`", DesugaringKind::TryBlock => "`try` block", DesugaringKind::OpaqueTy => "`impl Trait`", - DesugaringKind::ForLoop(_) => "`for` loop", + DesugaringKind::ForLoop => "`for` loop", DesugaringKind::LetElse => "`let...else`", DesugaringKind::WhileLoop => "`while` loop", } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 1445c59710c..66c01140abc 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -41,7 +41,7 @@ pub mod edition; use edition::Edition; pub mod hygiene; use hygiene::Transparency; -pub use hygiene::{DesugaringKind, ExpnKind, ForLoopLoc, MacroKind}; +pub use hygiene::{DesugaringKind, ExpnKind, MacroKind}; pub use hygiene::{ExpnData, ExpnHash, ExpnId, LocalExpnId, SyntaxContext}; pub mod def_id; use def_id::{CrateNum, DefId, DefPathHash, LocalDefId, LOCAL_CRATE}; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9992b1f31fe..0d556b5eda6 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -269,7 +269,6 @@ symbols! { __D, __H, __S, - __next, __try_var, _args, _d, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index d5c7cf71116..a90140a9b50 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -27,7 +27,7 @@ use rustc_middle::ty::{TypeAndMut, TypeckResults}; use rustc_session::Limit; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::{BytePos, DesugaringKind, ExpnKind, ForLoopLoc, MultiSpan, Span, DUMMY_SP}; +use rustc_span::{BytePos, DesugaringKind, ExpnKind, MultiSpan, Span, DUMMY_SP}; use rustc_target::spec::abi; use std::fmt; @@ -685,7 +685,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { &obligation.cause.code { parent_code.clone() - } else if let ExpnKind::Desugaring(DesugaringKind::ForLoop(ForLoopLoc::IntoIter)) = + } else if let ExpnKind::Desugaring(DesugaringKind::ForLoop) = span.ctxt().outer_expn_data().kind { Lrc::new(obligation.cause.code.clone()) @@ -765,8 +765,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // This if is to prevent a special edge-case if matches!( span.ctxt().outer_expn_data().kind, - ExpnKind::Root - | ExpnKind::Desugaring(DesugaringKind::ForLoop(ForLoopLoc::IntoIter)) + ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) ) { // We don't want a borrowing suggestion on the fields in structs, // ``` |
