@@ -19,6 +19,7 @@ use rustc_hir as hir;
19
19
use rustc_hir:: def:: DefKind ;
20
20
use rustc_hir:: def_id:: DefId ;
21
21
use rustc_hir:: intravisit:: Visitor ;
22
+ use rustc_hir:: is_range_literal;
22
23
use rustc_hir:: lang_items:: LangItem ;
23
24
use rustc_hir:: { AsyncGeneratorKind , GeneratorKind , Node } ;
24
25
use rustc_hir:: { Expr , HirId } ;
@@ -1349,14 +1350,41 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1349
1350
Applicability :: MaybeIncorrect ,
1350
1351
) ;
1351
1352
} 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
+
1352
1369
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,
1360
1388
Applicability :: MaybeIncorrect ,
1361
1389
) ;
1362
1390
}
0 commit comments