@@ -3412,19 +3412,37 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
34123412 "field `{}` of struct `{}` is private" ,
34133413 field, struct_path) ;
34143414 // Also check if an accessible method exists, which is often what is meant.
3415- if self . method_exists ( field, expr_t, expr. id , false ) {
3416- err. note ( & format ! ( "a method `{}` also exists, perhaps you wish to call it" , field) ) ;
3415+ if self . method_exists ( field, expr_t, expr. id , false ) && !self . expr_in_place ( expr. id ) {
3416+ self . suggest_method_call (
3417+ & mut err,
3418+ & format ! ( "a method `{}` also exists, call it with parentheses" , field) ,
3419+ field,
3420+ expr_t,
3421+ expr. id ,
3422+ ) ;
34173423 }
34183424 err. emit ( ) ;
34193425 field_ty
34203426 } else if field. name == keywords:: Invalid . name ( ) {
34213427 self . tcx ( ) . types . err
34223428 } else if self . method_exists ( field, expr_t, expr. id , true ) {
3423- type_error_struct ! ( self . tcx( ) . sess, field. span, expr_t, E0615 ,
3429+ let mut err = type_error_struct ! ( self . tcx( ) . sess, field. span, expr_t, E0615 ,
34243430 "attempted to take value of method `{}` on type `{}`" ,
3425- field, expr_t)
3426- . help ( "maybe a `()` to call it is missing?" )
3427- . emit ( ) ;
3431+ field, expr_t) ;
3432+
3433+ if !self . expr_in_place ( expr. id ) {
3434+ self . suggest_method_call (
3435+ & mut err,
3436+ "use parentheses to call the method" ,
3437+ field,
3438+ expr_t,
3439+ expr. id
3440+ ) ;
3441+ } else {
3442+ err. help ( "methods are immutable and cannot be assigned to" ) ;
3443+ }
3444+
3445+ err. emit ( ) ;
34283446 self . tcx ( ) . types . err
34293447 } else {
34303448 if !expr_t. is_primitive_ty ( ) {
@@ -5435,6 +5453,28 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
54355453 original_values,
54365454 query_result)
54375455 }
5456+
5457+ /// Returns whether an expression is contained inside the LHS of an assignment expression.
5458+ fn expr_in_place ( & self , mut expr_id : ast:: NodeId ) -> bool {
5459+ let mut contained_in_place = false ;
5460+
5461+ while let hir:: Node :: Expr ( parent_expr) =
5462+ self . tcx . hir ( ) . get ( self . tcx . hir ( ) . get_parent_node ( expr_id) )
5463+ {
5464+ match & parent_expr. node {
5465+ hir:: ExprKind :: Assign ( lhs, ..) | hir:: ExprKind :: AssignOp ( _, lhs, ..) => {
5466+ if lhs. id == expr_id {
5467+ contained_in_place = true ;
5468+ break ;
5469+ }
5470+ }
5471+ _ => ( ) ,
5472+ }
5473+ expr_id = parent_expr. id ;
5474+ }
5475+
5476+ contained_in_place
5477+ }
54385478}
54395479
54405480pub fn check_bounds_are_used < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
0 commit comments