@@ -19,6 +19,7 @@ use rustc_hir as hir;
1919use rustc_hir:: def:: DefKind ;
2020use rustc_hir:: def_id:: DefId ;
2121use rustc_hir:: intravisit:: Visitor ;
22+ use rustc_hir:: is_range_literal;
2223use rustc_hir:: lang_items:: LangItem ;
2324use rustc_hir:: { AsyncGeneratorKind , GeneratorKind , Node } ;
2425use rustc_hir:: { Expr , HirId } ;
@@ -1349,14 +1350,41 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
13491350 Applicability :: MaybeIncorrect ,
13501351 ) ;
13511352 } else {
1353+ // Issue #104961, we need to add parentheses properly for compond expressions
1354+ // for example, `x.starts_with("hi".to_string() + "you")`
1355+ // should be `x.starts_with(&("hi".to_string() + "you"))`
1356+ let Some ( body_id) = self . tcx . hir ( ) . maybe_body_owned_by ( obligation. cause . body_id ) else { return false ; } ;
1357+ let body = self . tcx . hir ( ) . body ( body_id) ;
1358+ let mut expr_finder = FindExprBySpan :: new ( span) ;
1359+ expr_finder. visit_expr ( body. value ) ;
1360+ let Some ( expr) = expr_finder. result else { return false ; } ;
1361+ let needs_parens = match expr. kind {
1362+ // parenthesize if needed (Issue #46756)
1363+ hir:: ExprKind :: Cast ( _, _) | hir:: ExprKind :: Binary ( _, _, _) => true ,
1364+ // parenthesize borrows of range literals (Issue #54505)
1365+ _ if is_range_literal ( expr) => true ,
1366+ _ => false ,
1367+ } ;
1368+
13521369 let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
1353- err. span_suggestion_verbose (
1354- span. shrink_to_lo ( ) ,
1355- & format ! (
1356- "consider{} borrowing here" ,
1357- if is_mut { " mutably" } else { "" }
1358- ) ,
1359- format ! ( "&{}" , if is_mut { "mut " } else { "" } ) ,
1370+ let span = if needs_parens { span } else { span. shrink_to_lo ( ) } ;
1371+ let sugg_prefix = format ! ( "&{}" , if is_mut { "mut " } else { "" } ) ;
1372+ let sugg_msg = & format ! (
1373+ "consider{} borrowing here" ,
1374+ if is_mut { " mutably" } else { "" }
1375+ ) ;
1376+
1377+ let suggestions = if !needs_parens {
1378+ vec ! [ ( span. shrink_to_lo( ) , format!( "{}" , sugg_prefix) ) ]
1379+ } else {
1380+ vec ! [
1381+ ( span. shrink_to_lo( ) , format!( "{}(" , sugg_prefix) ) ,
1382+ ( span. shrink_to_hi( ) , ")" . to_string( ) ) ,
1383+ ]
1384+ } ;
1385+ err. multipart_suggestion_verbose (
1386+ sugg_msg,
1387+ suggestions,
13601388 Applicability :: MaybeIncorrect ,
13611389 ) ;
13621390 }
0 commit comments