Change:
Given : Current error, for the motivating use case above: It should be possible for rustc to suggest replacing this specific instantiation of with . Maybe similarly for some other common cases: . Originally posted by in label -T-rustdoc T-compiler

Discussion:
&mut err, ); <ins> self.suggest_deref_unwrap_or( &mut err, error_span, callee_ty, call_ident, expected_ty, provided_ty, provided_args[*provided_idx], is_method, ); </ins> // Call out where the function is defined self.label_fn_like( &mut err,

true } <ins> // Suggest to change `Option<&Vec<T>>::unwrap_or(&[])` to `Option::map_or(&[], |v| v)`. #[instrument(level = "trace", skip(self, err, provided_expr))] pub(crate) fn suggest_deref_unwrap_or( &self, err: &mut Diag<'_>, error_span: Span, callee_ty: Option<Ty<'tcx>>, call_ident: Option<Ident>, expected_ty: Ty<'tcx>, provided_ty: Ty<'tcx>, provided_expr: &Expr<'tcx>, is_method: bool, ) { if !is_method { return; } let Some(callee_ty) = callee_ty else { return; }; let ty::Adt(callee_adt, _) = callee_ty.peel_refs().kind() else { return; }; let adt_name = if self.tcx.is_diagnostic_item(sym::Option, callee_adt.did()) { "Option" } else if self.tcx.is_diagnostic_item(sym::Result, callee_adt.did()) { "Result" } else { return; }; let Some(call_ident) = call_ident else { return; }; if call_ident.name != sym::unwrap_or { return; } let ty::Ref(_, peeled, _mutability) = provided_ty.kind() else { return; }; // NOTE: Can we reuse `suggest_deref_or_ref`? // Create an dummy type `&[_]` so that both &[] and `&Vec<T>` can coerce to it. let dummy_ty = if let ty::Array(elem_ty, size) = peeled.kind() && let ty::Infer(_) = elem_ty.kind() && size.try_eval_target_usize(self.tcx, self.param_env) == Some(0) { let slice = Ty::new_slice(self.tcx, *elem_ty); Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_static, slice) } else { provided_ty }; if !self.can_coerce(expected_ty, dummy_ty) { return; } let msg = format!("use `{adt_name}::map_or` to deref inner value of `{adt_name}`"); err.multipart_suggestion_verbose( msg, vec![ (call_ident.span, "map_or".to_owned()), (provided_expr.span.shrink_to_hi(), ", |v| v".to_owned()), ], Applicability::MachineApplicable, ); } </ins> /// Suggest wrapping the block in square brackets instead of curly braces /// in case the block was mistaken array syntax, e.g. `{ 1 }` -> `[ 1 ]`. pub(crate) fn suggest_block_to_brackets(

pub fn foo(arg: Option<&Vec<i32>>) -> Option<&[i32]> { arg //~ ERROR 5:5: 5:8: mismatched types [E0308] } <ins> pub fn bar(arg: Option<&Vec<i32>>) -> &[i32] { arg.unwrap_or(&[]) //~ ERROR 9:19: 9:22: mismatched types [E0308] } pub fn barzz<'a>(arg: Option<&'a Vec<i32>>, v: &'a [i32]) -> &'a [i32] { arg.unwrap_or(v) //~ ERROR 13:19: 13:20: mismatched types [E0308] } pub fn convert_result(arg: Result<&Vec<i32>, ()>) -> &[i32] { arg.unwrap_or(&[]) //~ ERROR 17:19: 17:22: mismatched types [E0308] } </ins>

LL |     arg.map(|v| &**v) |        ++++++++++++++ <del> error: aborting due to 1 previous error </del> <ins> error[E0308]: mismatched types --> $DIR/transforming-option-ref-issue-127545.rs:9:19 | LL |     arg.unwrap_or(&[]) |         --------- ^^^ expected `&Vec<i32>`, found `&[_; 0]` |         | |         arguments to this method are incorrect | = note: expected reference `&Vec<i32>` found reference `&[_; 0]` help: the return type of this call is `&[_; 0]` due to the type of the argument passed --> $DIR/transforming-option-ref-issue-127545.rs:9:5 | LL |     arg.unwrap_or(&[]) |     ^^^^^^^^^^^^^^---^ |                   | |                   this argument influences the return type of `unwrap_or` note: method defined here --> $SRC_DIR/core/src/option.rs:LL:COL help: use `Option::map_or` to deref inner value of `Option` | LL |     arg.map_or(&[], |v| v) |         ~~~~~~    +++++++ error[E0308]: mismatched types --> $DIR/transforming-option-ref-issue-127545.rs:13:19 | LL |     arg.unwrap_or(v) |         --------- ^ expected `&Vec<i32>`, found `&[i32]` |         | |         arguments to this method are incorrect | = note: expected reference `&Vec<i32>` found reference `&'a [i32]` help: the return type of this call is `&'a [i32]` due to the type of the argument passed --> $DIR/transforming-option-ref-issue-127545.rs:13:5 | LL |     arg.unwrap_or(v) |     ^^^^^^^^^^^^^^-^ |                   | |                   this argument influences the return type of `unwrap_or` note: method defined here --> $SRC_DIR/core/src/option.rs:LL:COL help: use `Option::map_or` to deref inner value of `Option` | LL |     arg.map_or(v, |v| v) |         ~~~~~~  +++++++ error[E0308]: mismatched types --> $DIR/transforming-option-ref-issue-127545.rs:17:19 | LL |     arg.unwrap_or(&[]) |         --------- ^^^ expected `&Vec<i32>`, found `&[_; 0]` |         | |         arguments to this method are incorrect | = note: expected reference `&Vec<i32>` found reference `&[_; 0]` help: the return type of this call is `&[_; 0]` due to the type of the argument passed --> $DIR/transforming-option-ref-issue-127545.rs:17:5 | LL |     arg.unwrap_or(&[]) |     ^^^^^^^^^^^^^^---^ |                   | |                   this argument influences the return type of `unwrap_or` note: method defined here --> $SRC_DIR/core/src/result.rs:LL:COL help: use `Result::map_or` to deref inner value of `Result` | LL |     arg.map_or(&[], |v| v) |         ~~~~~~    +++++++ error: aborting due to 4 previous errors </ins> For more information about this error, try `rustc --explain E0308`.