diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 556070bc68af9..20b05e790950d 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -79,12 +79,14 @@ struct TopInfo<'tcx> { span: Option, } -#[derive(Clone)] +#[derive(Copy, Clone)] struct PatInfo<'tcx, 'a> { binding_mode: BindingMode, top_info: TopInfo<'tcx>, decl_origin: Option>, - history: Vec>, + + parent_kind: Option>, + current_kind: Option>, } impl<'tcx> FnCtxt<'_, 'tcx> { @@ -154,8 +156,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { decl_origin: Option>, ) { let info = TopInfo { expected, origin_expr, span }; - let pat_info = - PatInfo { binding_mode: INITIAL_BM, top_info: info, decl_origin, history: Vec::new() }; + let pat_info = PatInfo { + binding_mode: INITIAL_BM, + top_info: info, + decl_origin, + parent_kind: None, + current_kind: None, + }; self.check_pat(pat, expected, pat_info); } @@ -166,7 +173,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Conversely, inside this module, `check_pat_top` should never be used. #[instrument(level = "debug", skip(self, pat_info))] fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>) { - let PatInfo { binding_mode: def_bm, top_info: ti, mut history, .. } = pat_info; + let PatInfo { binding_mode: def_bm, top_info: ti, current_kind, parent_kind, .. } = + pat_info; + + println!("{:#?} -> {:#?}", parent_kind, current_kind); + let path_res = match &pat.kind { PatKind::Path(qpath) => Some( self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span, None), @@ -175,12 +186,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res)); let (expected, def_bm) = self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode); - history.push(pat.kind); let pat_info = PatInfo { binding_mode: def_bm, top_info: ti, decl_origin: pat_info.decl_origin, - history, + parent_kind: current_kind, + current_kind: Some(pat.kind), }; let ty = match pat.kind { @@ -1054,7 +1065,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>, ) -> Ty<'tcx> { - let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, history } = pat_info; + let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, parent_kind, current_kind } = + pat_info; let tcx = self.tcx; let on_error = |e| { for pat in subpats { @@ -1065,7 +1077,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { binding_mode: def_bm, top_info: ti, decl_origin, - history: history.clone(), + parent_kind, + current_kind, }, ); } @@ -1140,7 +1153,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { binding_mode: def_bm, top_info: ti, decl_origin, - history: history.clone(), + parent_kind, + current_kind, }, ); @@ -2296,7 +2310,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ty: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>, ) -> ErrorGuaranteed { - let PatInfo { top_info: ti, history, .. } = pat_info; + let PatInfo { top_info: ti, parent_kind, .. } = pat_info; let mut err = struct_span_code_err!( self.dcx(), @@ -2334,9 +2348,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => (), } - let enclosure_is_struct = history - .get(history.len() - 2) - .map_or(false, |enclosure| matches!(enclosure, PatKind::Struct(..))); + let enclosure_is_struct = + parent_kind.map_or(false, |enclosure| matches!(enclosure, PatKind::Struct(..))); if is_slice_or_array_or_vector && !enclosure_is_struct { err.span_suggestion(