diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index deaa0c7c7419..151adb69aa93 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -2055,35 +2055,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let (Some(span), true) = (ti.span, ti.origin_expr) && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - let any_target_ty = Autoderef::new( - &self.infcx, - self.param_env, - self.body_id, - span, - self.resolve_vars_if_possible(ti.expected), - span, - ) - .any(|(ty, _)| { - debug!("kind={:?}", ty.kind()); - match ty.kind() { - ty::Adt(adt_def, _) - if self.tcx.is_diagnostic_item(sym::Option, adt_def.did()) - || self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) => - { - // Slicing won't work here, but `.as_deref()` might (issue #91328). - err.span_suggestion( - span, - "consider using `as_deref` here", - format!("{snippet}.as_deref()"), - Applicability::MaybeIncorrect, - ); - false - } - _ => self.is_slice_or_array_or_vector(ty), + let ty = self.resolve_vars_if_possible(ti.expected); + let is_slice_or_array_or_vector = self.is_slice_or_array_or_vector(&mut err, snippet.clone(), ty); + match is_slice_or_array_or_vector.1.kind() { + ty::Adt(adt_def, _) + if self.tcx.is_diagnostic_item(sym::Option, adt_def.did()) + || self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) => + { + // Slicing won't work here, but `.as_deref()` might (issue #91328). + err.span_suggestion( + span, + "consider using `as_deref` here", + format!("{snippet}.as_deref()"), + Applicability::MaybeIncorrect, + ); } - }); - - if any_target_ty { + _ => () + } + if is_slice_or_array_or_vector.0 { err.span_suggestion( span, "consider slicing here", @@ -2096,12 +2085,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } - fn is_slice_or_array_or_vector(&self, ty: Ty<'tcx>) -> bool { + fn is_slice_or_array_or_vector( + &self, + err: &mut Diagnostic, + snippet: String, + ty: Ty<'tcx>, + ) -> (bool, Ty<'tcx>) { match ty.kind() { - ty::Adt(adt_def, _) if self.tcx.is_diagnostic_item(sym::Vec, adt_def.did()) => true, - ty::Ref(_, ty, _) => self.is_slice_or_array_or_vector(*ty), - ty::Slice(..) | ty::Array(..) => true, - _ => false, + ty::Adt(adt_def, _) if self.tcx.is_diagnostic_item(sym::Vec, adt_def.did()) => { + (true, ty) + } + ty::Ref(_, ty, _) => self.is_slice_or_array_or_vector(err, snippet, *ty), + ty::Slice(..) | ty::Array(..) => (true, ty), + _ => (false, ty), } } }