Skip to content

Commit

Permalink
Add suggestion for Option<&Vec<T>> -> Option<&[T]
Browse files Browse the repository at this point in the history
  • Loading branch information
tesuji committed Jul 11, 2024
1 parent 252dc87 commit 8acf2e4
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 16 deletions.
51 changes: 35 additions & 16 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::method::probe;
use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
use core::cmp::min;
use core::iter;
use hir::def_id::LocalDefId;
use hir::def_id::{LocalDefId};
use rustc_ast::util::parser::{ExprPrecedence, PREC_UNAMBIGUOUS};
use rustc_data_structures::packed::Pu128;
use rustc_errors::{Applicability, Diag, MultiSpan};
Expand Down Expand Up @@ -466,21 +466,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
borrow_removal_span,
});
return true;
} else if let Some((deref_ty, _)) =
self.autoderef(expr.span, found_ty_inner).silence_errors().nth(1)
&& self.can_eq(self.param_env, deref_ty, peeled)
&& error_tys_equate_as_ref
{
let sugg = prefix_wrap(".as_deref()");
err.subdiagnostic(errors::SuggestConvertViaMethod {
span: expr.span.shrink_to_hi(),
sugg,
expected,
found,
borrow_removal_span,
});
return true;
} else if let ty::Adt(adt, _) = found_ty_inner.peel_refs().kind()
} else if let ty::Ref(_, peeled_found_ty, _) = found_ty_inner.kind()
&& let ty::Adt(adt, _) = peeled_found_ty.peel_refs().kind()
&& self.tcx.is_lang_item(adt.did(), LangItem::String)
&& peeled.is_str()
// `Result::map`, conversely, does not take ref of the error type.
Expand All @@ -496,6 +483,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Applicability::MachineApplicable,
);
return true;
} else {
if !error_tys_equate_as_ref {
return false;
}
let mut steps = self.autoderef(expr.span, found_ty_inner).silence_errors();
if let Some((deref_ty, _)) = steps.nth(1)
&& self.can_eq(self.param_env, deref_ty, peeled)
{
let sugg = prefix_wrap(".as_deref()");
err.subdiagnostic(errors::SuggestConvertViaMethod {
span: expr.span.shrink_to_hi(),
sugg,
expected,
found,
borrow_removal_span,
});
return true;
}
for (deref_ty, n_step) in steps {
if self.can_eq(self.param_env, deref_ty, peeled) {
let explicit_deref = "*".repeat(n_step);
let sugg = prefix_wrap(&format!(".map(|v| &{explicit_deref}v)"));
err.subdiagnostic(errors::SuggestConvertViaMethod {
span: expr.span.shrink_to_hi(),
sugg,
expected,
found,
borrow_removal_span,
});
return true;
}
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions tests/ui/mismatched_types/issue-127545-option-of-ref.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ LL | arg
|
= note: expected enum `Option<&[i32]>`
found enum `Option<&Vec<i32>>`
help: try using `.map(|v| &**v)` to convert `Option<&Vec<i32>>` to `Option<&[i32]>`
|
LL | arg.map(|v| &**v)
| ++++++++++++++

error[E0308]: mismatched types
--> $DIR/issue-127545-option-of-ref.rs:9:19
Expand Down

0 comments on commit 8acf2e4

Please sign in to comment.