stop using Autoderef

This commit is contained in:
Takayuki Maeda 2022-04-18 12:51:12 +09:00
parent a59cc5774b
commit 5924ef874e

View file

@ -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),
}
}
}