@@ -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 } ;
@@ -1350,14 +1351,41 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
13501351 Applicability :: MaybeIncorrect ,
13511352 ) ;
13521353 } else {
1354+ // Issue #104961, we need to add parentheses properly for compond expressions
1355+ // for example, `x.starts_with("hi".to_string() + "you")`
1356+ // should be `x.starts_with(&("hi".to_string() + "you"))`
1357+ let Some ( body_id) = self . tcx . hir ( ) . maybe_body_owned_by ( obligation. cause . body_id ) else { return false ; } ;
1358+ let body = self . tcx . hir ( ) . body ( body_id) ;
1359+ let mut expr_finder = FindExprBySpan :: new ( span) ;
1360+ expr_finder. visit_expr ( body. value ) ;
1361+ let Some ( expr) = expr_finder. result else { return false ; } ;
1362+ let needs_parens = match expr. kind {
1363+ // parenthesize if needed (Issue #46756)
1364+ hir:: ExprKind :: Cast ( _, _) | hir:: ExprKind :: Binary ( _, _, _) => true ,
1365+ // parenthesize borrows of range literals (Issue #54505)
1366+ _ if is_range_literal ( expr) => true ,
1367+ _ => false ,
1368+ } ;
1369+
13531370 let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
1354- err. span_suggestion_verbose (
1355- span. shrink_to_lo ( ) ,
1356- & format ! (
1357- "consider{} borrowing here" ,
1358- if is_mut { " mutably" } else { "" }
1359- ) ,
1360- format ! ( "&{}" , if is_mut { "mut " } else { "" } ) ,
1371+ let span = if needs_parens { span } else { span. shrink_to_lo ( ) } ;
1372+ let sugg_prefix = format ! ( "&{}" , if is_mut { "mut " } else { "" } ) ;
1373+ let sugg_msg = & format ! (
1374+ "consider{} borrowing here" ,
1375+ if is_mut { " mutably" } else { "" }
1376+ ) ;
1377+
1378+ let suggestions = if !needs_parens {
1379+ vec ! [ ( span. shrink_to_lo( ) , format!( "{}" , sugg_prefix) ) ]
1380+ } else {
1381+ vec ! [
1382+ ( span. shrink_to_lo( ) , format!( "{}(" , sugg_prefix) ) ,
1383+ ( span. shrink_to_hi( ) , ")" . to_string( ) ) ,
1384+ ]
1385+ } ;
1386+ err. multipart_suggestion_verbose (
1387+ sugg_msg,
1388+ suggestions,
13611389 Applicability :: MaybeIncorrect ,
13621390 ) ;
13631391 }
0 commit comments