@@ -54,7 +54,7 @@ fn parse_error(
5454impl < ' tcx > OnUnimplementedDirective {
5555 fn parse (
5656 tcx : TyCtxt < ' tcx > ,
57- trait_def_id : DefId ,
57+ item_def_id : DefId ,
5858 items : & [ NestedMetaItem ] ,
5959 span : Span ,
6060 is_root : bool ,
@@ -63,7 +63,7 @@ impl<'tcx> OnUnimplementedDirective {
6363 let mut item_iter = items. iter ( ) ;
6464
6565 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 )
6767 } ;
6868
6969 let condition = if is_root {
@@ -135,7 +135,7 @@ impl<'tcx> OnUnimplementedDirective {
135135 {
136136 if let Some ( items) = item. meta_item_list ( ) {
137137 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 )
139139 {
140140 subcommands. push ( subcommand) ;
141141 } else {
@@ -178,27 +178,23 @@ impl<'tcx> OnUnimplementedDirective {
178178 }
179179 }
180180
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) ;
187183
188184 let Some ( attr) = tcx. sess . find_by_name ( & attrs, sym:: rustc_on_unimplemented) else {
189185 return Ok ( None ) ;
190186 } ;
191187
192188 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 )
194190 } else if let Some ( value) = attr. value_str ( ) {
195191 Ok ( Some ( OnUnimplementedDirective {
196192 condition : None ,
197193 message : None ,
198194 subcommands : vec ! [ ] ,
199195 label : Some ( OnUnimplementedFormatString :: try_parse (
200196 tcx,
201- trait_def_id ,
197+ item_def_id ,
202198 value,
203199 attr. span ,
204200 ) ?) ,
@@ -209,7 +205,7 @@ impl<'tcx> OnUnimplementedDirective {
209205 } else {
210206 return Err ( ErrorGuaranteed ) ;
211207 } ;
212- debug ! ( "of_item({:?}/{:?} ) = {:?}" , trait_def_id , impl_def_id , result) ;
208+ debug ! ( "of_item({:?}) = {:?}" , item_def_id , result) ;
213209 result
214210 }
215211
@@ -280,23 +276,29 @@ impl<'tcx> OnUnimplementedDirective {
280276impl < ' tcx > OnUnimplementedFormatString {
281277 fn try_parse (
282278 tcx : TyCtxt < ' tcx > ,
283- trait_def_id : DefId ,
279+ item_def_id : DefId ,
284280 from : Symbol ,
285281 err_sp : Span ,
286282 ) -> Result < Self , ErrorGuaranteed > {
287283 let result = OnUnimplementedFormatString ( from) ;
288- result. verify ( tcx, trait_def_id , err_sp) ?;
284+ result. verify ( tcx, item_def_id , err_sp) ?;
289285 Ok ( result)
290286 }
291287
292288 fn verify (
293289 & self ,
294290 tcx : TyCtxt < ' tcx > ,
295- trait_def_id : DefId ,
291+ item_def_id : DefId ,
296292 span : Span ,
297293 ) -> 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) ;
300302 let s = self . 0 . as_str ( ) ;
301303 let parser = Parser :: new ( s, None , None , false , ParseMode :: Format ) ;
302304 let mut result = Ok ( ( ) ) ;
@@ -307,7 +309,7 @@ impl<'tcx> OnUnimplementedFormatString {
307309 // `{Self}` is allowed
308310 Position :: ArgumentNamed ( s, _) if s == kw:: SelfUpper => ( ) ,
309311 // `{ThisTraitsName}` is allowed
310- Position :: ArgumentNamed ( s, _) if s == name => ( ) ,
312+ Position :: ArgumentNamed ( s, _) if s == trait_name => ( ) ,
311313 // `{from_method}` is allowed
312314 Position :: ArgumentNamed ( s, _) if s == sym:: from_method => ( ) ,
313315 // `{from_desugaring}` is allowed
@@ -329,9 +331,13 @@ impl<'tcx> OnUnimplementedFormatString {
329331 tcx. sess,
330332 span,
331333 E0230 ,
332- "there is no parameter `{}` on trait `{}` " ,
334+ "there is no parameter `{}` on {} " ,
333335 s,
334- name
336+ if trait_def_id == item_def_id {
337+ format!( "trait `{}`" , trait_name)
338+ } else {
339+ "impl" . to_string( )
340+ }
335341 )
336342 . emit ( ) ;
337343 result = Err ( ErrorGuaranteed ) ;
0 commit comments