@@ -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,60 @@ 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+ /// ```text
1517+ /// some_option.as_mut().inspect(|x| {
1518+ /// ```
1519+ fn is_closure_arg_with_non_locally_decided_type ( & self , local : Local ) -> bool {
1520+ // We don't care about regular local variables, only args.
1521+ if self . body . local_kind ( local) != LocalKind :: Arg {
1522+ return false ;
1523+ }
1524+
1525+ // Make sure we are inside a closure.
1526+ let InstanceKind :: Item ( body_def_id) = self . body . source . instance else {
1527+ return false ;
1528+ } ;
1529+ let Some ( Node :: Expr ( hir:: Expr { hir_id : body_hir_id, kind, .. } ) ) =
1530+ self . infcx . tcx . hir_get_if_local ( body_def_id)
1531+ else {
1532+ return false ;
1533+ } ;
1534+ let ExprKind :: Closure ( hir:: Closure { kind : hir:: ClosureKind :: Closure , .. } ) = kind else {
1535+ return false ;
1536+ } ;
1537+
1538+ // Check if the method/function that our closure is passed to is defined
1539+ // in another crate.
1540+ let Node :: Expr ( closure_parent) = self . infcx . tcx . parent_hir_node ( * body_hir_id) else {
1541+ return false ;
1542+ } ;
1543+ match closure_parent. kind {
1544+ ExprKind :: MethodCall ( method, _, _, _) => self
1545+ . infcx
1546+ . tcx
1547+ . typeck ( method. hir_id . owner . def_id )
1548+ . type_dependent_def_id ( closure_parent. hir_id )
1549+ . is_some_and ( |def_id| !def_id. is_local ( ) ) ,
1550+ ExprKind :: Call ( func, _) => self
1551+ . infcx
1552+ . tcx
1553+ . typeck ( func. hir_id . owner . def_id )
1554+ . node_type_opt ( func. hir_id )
1555+ . and_then ( |ty| match ty. kind ( ) {
1556+ ty:: FnDef ( def_id, _) => Some ( def_id) ,
1557+ _ => None ,
1558+ } )
1559+ . is_some_and ( |def_id| !def_id. is_local ( ) ) ,
1560+ _ => false ,
1561+ }
1562+ }
15031563}
15041564
15051565struct BindingFinder {
0 commit comments