@@ -176,10 +176,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
176
176
err. emit ( ) ;
177
177
}
178
178
179
- MethodError :: IllegalSizedBound ( candidates, needs_mut, bound_span) => {
180
- let msg = format ! ( "the `{}` method cannot be invoked on a trait object" , item_name) ;
179
+ MethodError :: IllegalSizedBound { candidates, needs_mut, bound_span, self_expr } => {
180
+ let msg = if needs_mut {
181
+ with_forced_trimmed_paths ! ( format!(
182
+ "the `{item_name}` method cannot be invoked on `{rcvr_ty}`"
183
+ ) )
184
+ } else {
185
+ format ! ( "the `{item_name}` method cannot be invoked on a trait object" )
186
+ } ;
181
187
let mut err = self . sess ( ) . struct_span_err ( span, & msg) ;
182
- err. span_label ( bound_span, "this has a `Sized` requirement" ) ;
188
+ if !needs_mut {
189
+ err. span_label ( bound_span, "this has a `Sized` requirement" ) ;
190
+ }
183
191
if !candidates. is_empty ( ) {
184
192
let help = format ! (
185
193
"{an}other candidate{s} {were} found in the following trait{s}, perhaps \
@@ -197,7 +205,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
197
205
* region,
198
206
ty:: TypeAndMut { ty : * t_type, mutbl : mutability. invert ( ) } ,
199
207
) ;
200
- err. note ( & format ! ( "you need `{}` instead of `{}`" , trait_type, rcvr_ty) ) ;
208
+ let msg = format ! ( "you need `{}` instead of `{}`" , trait_type, rcvr_ty) ;
209
+ let mut kind = & self_expr. kind ;
210
+ while let hir:: ExprKind :: AddrOf ( _, _, expr)
211
+ | hir:: ExprKind :: Unary ( hir:: UnOp :: Deref , expr) = kind
212
+ {
213
+ kind = & expr. kind ;
214
+ }
215
+ if let hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None , path) ) = kind
216
+ && let hir:: def:: Res :: Local ( hir_id) = path. res
217
+ && let Some ( hir:: Node :: Pat ( b) ) = self . tcx . hir ( ) . find ( hir_id)
218
+ && let Some ( hir:: Node :: Param ( p) ) = self . tcx . hir ( ) . find_parent ( b. hir_id )
219
+ && let Some ( node) = self . tcx . hir ( ) . find_parent ( p. hir_id )
220
+ && let Some ( decl) = node. fn_decl ( )
221
+ && let Some ( ty) = decl. inputs . iter ( ) . find ( |ty| ty. span == p. ty_span )
222
+ && let hir:: TyKind :: Ref ( _, mut_ty) = & ty. kind
223
+ && let hir:: Mutability :: Not = mut_ty. mutbl
224
+ {
225
+ err. span_suggestion_verbose (
226
+ mut_ty. ty . span . shrink_to_lo ( ) ,
227
+ & msg,
228
+ "mut " ,
229
+ Applicability :: MachineApplicable ,
230
+ ) ;
231
+ } else {
232
+ err. help ( & msg) ;
233
+ }
201
234
}
202
235
}
203
236
err. emit ( ) ;
0 commit comments