@@ -1198,6 +1198,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11981198 ) ;
11991199 return ;
12001200 }
1201+
1202+ // Do not suggest changing type if that is not under user control.
1203+ if self . is_closure_arg_with_non_locally_decided_type ( local) {
1204+ return ;
1205+ }
1206+
12011207 let decl_span = local_decl. source_info . span ;
12021208
12031209 let ( amp_mut_sugg, local_var_ty_info) = match * local_decl. local_info ( ) {
@@ -1500,6 +1506,62 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
15001506 Applicability :: HasPlaceholders ,
15011507 ) ;
15021508 }
1509+
1510+ /// Returns `true` if `local` is an argument in a closure passed to a
1511+ /// function defined in another crate.
1512+ ///
1513+ /// For example, in the following code this function returns `true` for `x`
1514+ /// since `Option::inspect()` is not defined in the current crate:
1515+ ///
1516+ /// ```ignore (only-for-syntax-highlight)
1517+ /// some_option.as_mut().inspect(|x| {
1518+ /// // ...
1519+ /// }
1520+ /// ```
1521+ fn is_closure_arg_with_non_locally_decided_type ( & self , local : Local ) -> bool {
1522+ // We don't care about regular local variables, only args.
1523+ if self . body . local_kind ( local) != LocalKind :: Arg {
1524+ return false ;
1525+ }
1526+
1527+ // Make sure we are inside a closure.
1528+ let InstanceKind :: Item ( body_def_id) = self . body . source . instance else {
1529+ return false ;
1530+ } ;
1531+ let Some ( Node :: Expr ( hir:: Expr { hir_id : body_hir_id, kind, .. } ) ) =
1532+ self . infcx . tcx . hir_get_if_local ( body_def_id)
1533+ else {
1534+ return false ;
1535+ } ;
1536+ let ExprKind :: Closure ( hir:: Closure { kind : hir:: ClosureKind :: Closure , .. } ) = kind else {
1537+ return false ;
1538+ } ;
1539+
1540+ // Check if the method/function that our closure is passed to is defined
1541+ // in another crate.
1542+ let Node :: Expr ( closure_parent) = self . infcx . tcx . parent_hir_node ( * body_hir_id) else {
1543+ return false ;
1544+ } ;
1545+ match closure_parent. kind {
1546+ ExprKind :: MethodCall ( method, _, _, _) => self
1547+ . infcx
1548+ . tcx
1549+ . typeck ( method. hir_id . owner . def_id )
1550+ . type_dependent_def_id ( closure_parent. hir_id )
1551+ . is_some_and ( |def_id| !def_id. is_local ( ) ) ,
1552+ ExprKind :: Call ( func, _) => self
1553+ . infcx
1554+ . tcx
1555+ . typeck ( func. hir_id . owner . def_id )
1556+ . node_type_opt ( func. hir_id )
1557+ . and_then ( |ty| match ty. kind ( ) {
1558+ ty:: FnDef ( def_id, _) => Some ( def_id) ,
1559+ _ => None ,
1560+ } )
1561+ . is_some_and ( |def_id| !def_id. is_local ( ) ) ,
1562+ _ => false ,
1563+ }
1564+ }
15031565}
15041566
15051567struct BindingFinder {
0 commit comments