@@ -54,7 +54,7 @@ fn parse_error(
54
54
impl < ' tcx > OnUnimplementedDirective {
55
55
fn parse (
56
56
tcx : TyCtxt < ' tcx > ,
57
- trait_def_id : DefId ,
57
+ item_def_id : DefId ,
58
58
items : & [ NestedMetaItem ] ,
59
59
span : Span ,
60
60
is_root : bool ,
@@ -63,7 +63,7 @@ impl<'tcx> OnUnimplementedDirective {
63
63
let mut item_iter = items. iter ( ) ;
64
64
65
65
let parse_value = |value_str| {
66
- OnUnimplementedFormatString :: try_parse ( tcx, trait_def_id , value_str, span) . map ( Some )
66
+ OnUnimplementedFormatString :: try_parse ( tcx, item_def_id , value_str, span) . map ( Some )
67
67
} ;
68
68
69
69
let condition = if is_root {
@@ -135,7 +135,7 @@ impl<'tcx> OnUnimplementedDirective {
135
135
{
136
136
if let Some ( items) = item. meta_item_list ( ) {
137
137
if let Ok ( subcommand) =
138
- Self :: parse ( tcx, trait_def_id , & items, item. span ( ) , false )
138
+ Self :: parse ( tcx, item_def_id , & items, item. span ( ) , false )
139
139
{
140
140
subcommands. push ( subcommand) ;
141
141
} else {
@@ -178,27 +178,23 @@ impl<'tcx> OnUnimplementedDirective {
178
178
}
179
179
}
180
180
181
- pub fn of_item (
182
- tcx : TyCtxt < ' tcx > ,
183
- trait_def_id : DefId ,
184
- impl_def_id : DefId ,
185
- ) -> Result < Option < Self > , ErrorGuaranteed > {
186
- let attrs = tcx. get_attrs ( impl_def_id) ;
181
+ pub fn of_item ( tcx : TyCtxt < ' tcx > , item_def_id : DefId ) -> Result < Option < Self > , ErrorGuaranteed > {
182
+ let attrs = tcx. get_attrs ( item_def_id) ;
187
183
188
184
let Some ( attr) = tcx. sess . find_by_name ( & attrs, sym:: rustc_on_unimplemented) else {
189
185
return Ok ( None ) ;
190
186
} ;
191
187
192
188
let result = if let Some ( items) = attr. meta_item_list ( ) {
193
- Self :: parse ( tcx, trait_def_id , & items, attr. span , true ) . map ( Some )
189
+ Self :: parse ( tcx, item_def_id , & items, attr. span , true ) . map ( Some )
194
190
} else if let Some ( value) = attr. value_str ( ) {
195
191
Ok ( Some ( OnUnimplementedDirective {
196
192
condition : None ,
197
193
message : None ,
198
194
subcommands : vec ! [ ] ,
199
195
label : Some ( OnUnimplementedFormatString :: try_parse (
200
196
tcx,
201
- trait_def_id ,
197
+ item_def_id ,
202
198
value,
203
199
attr. span ,
204
200
) ?) ,
@@ -209,7 +205,7 @@ impl<'tcx> OnUnimplementedDirective {
209
205
} else {
210
206
return Err ( ErrorGuaranteed ) ;
211
207
} ;
212
- debug ! ( "of_item({:?}/{:?} ) = {:?}" , trait_def_id , impl_def_id , result) ;
208
+ debug ! ( "of_item({:?}) = {:?}" , item_def_id , result) ;
213
209
result
214
210
}
215
211
@@ -280,23 +276,29 @@ impl<'tcx> OnUnimplementedDirective {
280
276
impl < ' tcx > OnUnimplementedFormatString {
281
277
fn try_parse (
282
278
tcx : TyCtxt < ' tcx > ,
283
- trait_def_id : DefId ,
279
+ item_def_id : DefId ,
284
280
from : Symbol ,
285
281
err_sp : Span ,
286
282
) -> Result < Self , ErrorGuaranteed > {
287
283
let result = OnUnimplementedFormatString ( from) ;
288
- result. verify ( tcx, trait_def_id , err_sp) ?;
284
+ result. verify ( tcx, item_def_id , err_sp) ?;
289
285
Ok ( result)
290
286
}
291
287
292
288
fn verify (
293
289
& self ,
294
290
tcx : TyCtxt < ' tcx > ,
295
- trait_def_id : DefId ,
291
+ item_def_id : DefId ,
296
292
span : Span ,
297
293
) -> Result < ( ) , ErrorGuaranteed > {
298
- let name = tcx. item_name ( trait_def_id) ;
299
- let generics = tcx. generics_of ( trait_def_id) ;
294
+ let trait_def_id = if tcx. is_trait ( item_def_id) {
295
+ item_def_id
296
+ } else {
297
+ tcx. trait_id_of_impl ( item_def_id)
298
+ . expect ( "expected `on_unimplemented` to correspond to a trait" )
299
+ } ;
300
+ let trait_name = tcx. item_name ( trait_def_id) ;
301
+ let generics = tcx. generics_of ( item_def_id) ;
300
302
let s = self . 0 . as_str ( ) ;
301
303
let parser = Parser :: new ( s, None , None , false , ParseMode :: Format ) ;
302
304
let mut result = Ok ( ( ) ) ;
@@ -307,7 +309,7 @@ impl<'tcx> OnUnimplementedFormatString {
307
309
// `{Self}` is allowed
308
310
Position :: ArgumentNamed ( s, _) if s == kw:: SelfUpper => ( ) ,
309
311
// `{ThisTraitsName}` is allowed
310
- Position :: ArgumentNamed ( s, _) if s == name => ( ) ,
312
+ Position :: ArgumentNamed ( s, _) if s == trait_name => ( ) ,
311
313
// `{from_method}` is allowed
312
314
Position :: ArgumentNamed ( s, _) if s == sym:: from_method => ( ) ,
313
315
// `{from_desugaring}` is allowed
@@ -329,9 +331,13 @@ impl<'tcx> OnUnimplementedFormatString {
329
331
tcx. sess,
330
332
span,
331
333
E0230 ,
332
- "there is no parameter `{}` on trait `{}` " ,
334
+ "there is no parameter `{}` on {} " ,
333
335
s,
334
- name
336
+ if trait_def_id == item_def_id {
337
+ format!( "trait `{}`" , trait_name)
338
+ } else {
339
+ "impl" . to_string( )
340
+ }
335
341
)
336
342
. emit ( ) ;
337
343
result = Err ( ErrorGuaranteed ) ;
0 commit comments