@@ -131,7 +131,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
131131 parse_error ( tcx, item. span ,
132132 "this attribute must have a valid value" ,
133133 "expected value here" ,
134- Some ( r#"eg `#[rustc_on_unimplemented = "foo"]`"# ) ) ;
134+ Some ( r#"eg `#[rustc_on_unimplemented(message= "foo") ]`"# ) ) ;
135135 }
136136
137137 if errored {
@@ -170,7 +170,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
170170 return Err ( parse_error ( tcx, attr. span ,
171171 "`#[rustc_on_unimplemented]` requires a value" ,
172172 "value required here" ,
173- Some ( r#"eg `#[rustc_on_unimplemented = "foo"]`"# ) ) ) ;
173+ Some ( r#"eg `#[rustc_on_unimplemented(message= "foo") ]`"# ) ) ) ;
174174 } ;
175175 debug ! ( "of_item({:?}/{:?}) = {:?}" , trait_def_id, impl_def_id, result) ;
176176 result
@@ -213,10 +213,13 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
213213 }
214214 }
215215
216+ let options: FxHashMap < String , String > = options. into_iter ( )
217+ . filter_map ( |( k, v) | v. as_ref ( ) . map ( |v| ( k. to_owned ( ) , v. to_owned ( ) ) ) )
218+ . collect ( ) ;
216219 OnUnimplementedNote {
217- label : label. map ( |l| l. format ( tcx, trait_ref) ) ,
218- message : message. map ( |m| m. format ( tcx, trait_ref) ) ,
219- note : note. map ( |n| n. format ( tcx, trait_ref) ) ,
220+ label : label. map ( |l| l. format ( tcx, trait_ref, & options ) ) ,
221+ message : message. map ( |m| m. format ( tcx, trait_ref, & options ) ) ,
222+ note : note. map ( |n| n. format ( tcx, trait_ref, & options ) ) ,
220223 }
221224 }
222225}
@@ -251,24 +254,25 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
251254 Position :: ArgumentNamed ( s) if s == "Self" => ( ) ,
252255 // `{ThisTraitsName}` is allowed
253256 Position :: ArgumentNamed ( s) if s == name => ( ) ,
257+ // `{from_method}` is allowed
258+ Position :: ArgumentNamed ( s) if s == "from_method" => ( ) ,
259+ // `{from_desugaring}` is allowed
260+ Position :: ArgumentNamed ( s) if s == "from_desugaring" => ( ) ,
254261 // So is `{A}` if A is a type parameter
255262 Position :: ArgumentNamed ( s) => match generics. params . iter ( ) . find ( |param| {
256263 param. name == s
257264 } ) {
258265 Some ( _) => ( ) ,
259266 None => {
260267 span_err ! ( tcx. sess, span, E0230 ,
261- "there is no parameter \
262- {} on trait {}",
263- s, name) ;
268+ "there is no parameter `{}` on trait `{}`" , s, name) ;
264269 result = Err ( ErrorReported ) ;
265270 }
266271 } ,
267272 // `{:1}` and `{}` are not to be used
268273 Position :: ArgumentIs ( _) | Position :: ArgumentImplicitlyIs ( _) => {
269274 span_err ! ( tcx. sess, span, E0231 ,
270- "only named substitution \
271- parameters are allowed") ;
275+ "only named substitution parameters are allowed" ) ;
272276 result = Err ( ErrorReported ) ;
273277 }
274278 }
@@ -280,7 +284,8 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
280284
281285 pub fn format ( & self ,
282286 tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
283- trait_ref : ty:: TraitRef < ' tcx > )
287+ trait_ref : ty:: TraitRef < ' tcx > ,
288+ options : & FxHashMap < String , String > )
284289 -> String
285290 {
286291 let name = tcx. item_name ( trait_ref. def_id ) ;
@@ -296,6 +301,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
296301 let name = param. name . to_string ( ) ;
297302 Some ( ( name, value) )
298303 } ) . collect :: < FxHashMap < String , String > > ( ) ;
304+ let empty_string = String :: new ( ) ;
299305
300306 let parser = Parser :: new ( & self . 0 , None ) ;
301307 parser. map ( |p| {
@@ -308,14 +314,20 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
308314 & trait_str
309315 }
310316 None => {
311- bug ! ( "broken on_unimplemented {:?} for {:?}: \
312- no argument matching {:?}",
313- self . 0 , trait_ref, s)
317+ if let Some ( val) = options. get ( s) {
318+ val
319+ } else if s == "from_desugaring" || s == "from_method" {
320+ // don't break messages using these two arguments incorrectly
321+ & empty_string
322+ } else {
323+ bug ! ( "broken on_unimplemented {:?} for {:?}: \
324+ no argument matching {:?}",
325+ self . 0 , trait_ref, s)
326+ }
314327 }
315328 } ,
316329 _ => {
317- bug ! ( "broken on_unimplemented {:?} - bad \
318- format arg", self . 0 )
330+ bug ! ( "broken on_unimplemented {:?} - bad format arg" , self . 0 )
319331 }
320332 }
321333 }
0 commit comments