@@ -24,6 +24,7 @@ use crate::parser::{ArgParser, MetaItemListParser, MetaItemOrLitParser, MetaItem
2424pub ( crate ) mod do_not_recommend;
2525pub ( crate ) mod on_const;
2626pub ( crate ) mod on_move;
27+ pub ( crate ) mod on_type_error;
2728pub ( crate ) mod on_unimplemented;
2829pub ( crate ) mod on_unknown;
2930pub ( crate ) mod on_unmatch_args;
@@ -42,6 +43,8 @@ pub(crate) enum Mode {
4243 DiagnosticOnUnknown ,
4344 /// `#[diagnostic::on_unmatch_args]`
4445 DiagnosticOnUnmatchArgs ,
46+ /// `#[diagnostic::on_type_error]`
47+ DiagnosticOnTypeError ,
4548}
4649
4750impl Mode {
@@ -53,12 +56,15 @@ impl Mode {
5356 Self :: DiagnosticOnMove => "diagnostic::on_move" ,
5457 Self :: DiagnosticOnUnknown => "diagnostic::on_unknown" ,
5558 Self :: DiagnosticOnUnmatchArgs => "diagnostic::on_unmatch_args" ,
59+ Self :: DiagnosticOnTypeError => "diagnostic::on_type_error" ,
5660 }
5761 }
5862
5963 fn expected_options ( & self ) -> & ' static str {
6064 const DEFAULT : & str =
6165 "at least one of the `message`, `note` and `label` options are expected" ;
66+ const DIAGNOSTIC_ON_TYPE_ERROR_EXPECTED_OPTIONS : & str =
67+ "at least a single `note` option is expected" ;
6268 match self {
6369 Self :: RustcOnUnimplemented => {
6470 "see <https://rustc-dev-guide.rust-lang.org/diagnostics.html#rustc_on_unimplemented>"
@@ -68,11 +74,14 @@ impl Mode {
6874 Self :: DiagnosticOnMove => DEFAULT ,
6975 Self :: DiagnosticOnUnknown => DEFAULT ,
7076 Self :: DiagnosticOnUnmatchArgs => DEFAULT ,
77+ Self :: DiagnosticOnTypeError => DIAGNOSTIC_ON_TYPE_ERROR_EXPECTED_OPTIONS ,
7178 }
7279 }
7380
7481 fn allowed_options ( & self ) -> & ' static str {
7582 const DEFAULT : & str = "only `message`, `note` and `label` are allowed as options" ;
83+ const DIAGNOSTIC_ON_TYPE_ERROR_ALLOWED_OPTIONS : & str =
84+ "only `note` is allowed as option for `diagnostic::on_type_error`" ;
7685 match self {
7786 Self :: RustcOnUnimplemented => {
7887 "see <https://rustc-dev-guide.rust-lang.org/diagnostics.html#rustc_on_unimplemented>"
@@ -82,6 +91,7 @@ impl Mode {
8291 Self :: DiagnosticOnMove => DEFAULT ,
8392 Self :: DiagnosticOnUnknown => DEFAULT ,
8493 Self :: DiagnosticOnUnmatchArgs => DEFAULT ,
94+ Self :: DiagnosticOnTypeError => DIAGNOSTIC_ON_TYPE_ERROR_ALLOWED_OPTIONS ,
8595 }
8696 }
8797
@@ -105,6 +115,9 @@ impl Mode {
105115 Self :: DiagnosticOnUnmatchArgs => {
106116 "only `This` is allowed as a format argument, referring to the macro's name"
107117 }
118+ Self :: DiagnosticOnTypeError => {
119+ "only `note` is allowed as option for `diagnostic::on_type_error`"
120+ }
108121 }
109122 }
110123}
@@ -294,15 +307,31 @@ fn parse_directive_items<'p>(
294307 }
295308 } ;
296309 match ( mode, name) {
297- ( _, sym:: message) => {
310+ (
311+ Mode :: RustcOnUnimplemented
312+ | Mode :: DiagnosticOnUnimplemented
313+ | Mode :: DiagnosticOnConst
314+ | Mode :: DiagnosticOnMove
315+ | Mode :: DiagnosticOnUnknown
316+ | Mode :: DiagnosticOnUnmatchArgs ,
317+ sym:: message,
318+ ) => {
298319 let value = or_malformed ! ( value?) ;
299320 if let Some ( message) = & message {
300321 duplicate ! ( name, message. 0 )
301322 } else {
302323 message = Some ( ( item. span ( ) , parse_format ( value) ) ) ;
303324 }
304325 }
305- ( _, sym:: label) => {
326+ (
327+ Mode :: RustcOnUnimplemented
328+ | Mode :: DiagnosticOnUnimplemented
329+ | Mode :: DiagnosticOnConst
330+ | Mode :: DiagnosticOnMove
331+ | Mode :: DiagnosticOnUnknown
332+ | Mode :: DiagnosticOnUnmatchArgs ,
333+ sym:: label,
334+ ) => {
306335 let value = or_malformed ! ( value?) ;
307336 if let Some ( label) = & label {
308337 duplicate ! ( name, label. 0 )
@@ -356,7 +385,6 @@ fn parse_directive_items<'p>(
356385 malformed ! ( ) ;
357386 }
358387 }
359-
360388 _other => {
361389 malformed ! ( ) ;
362390 }
@@ -430,13 +458,19 @@ fn parse_arg(
430458 _ => FormatArg :: This ,
431459 } ,
432460
461+ ( Mode :: DiagnosticOnTypeError , sym:: Found ) => FormatArg :: Found ,
462+ ( Mode :: DiagnosticOnTypeError , sym:: Expected ) => FormatArg :: Expected ,
463+
433464 // Some diagnostic attributes can use `{This}` to refer to the annotated item.
434465 // For those that don't, we continue and maybe use it as a generic parameter.
435466 //
436467 // FIXME(mejrs) `DiagnosticOnUnimplemented` is intentionally not here;
437468 // that requires lang approval which is best kept for a standalone PR.
438469 (
439- Mode :: DiagnosticOnUnknown | Mode :: DiagnosticOnMove | Mode :: DiagnosticOnUnmatchArgs ,
470+ Mode :: DiagnosticOnUnknown
471+ | Mode :: DiagnosticOnMove
472+ | Mode :: DiagnosticOnUnmatchArgs
473+ | Mode :: DiagnosticOnTypeError ,
440474 sym:: This ,
441475 ) => FormatArg :: This ,
442476
@@ -462,7 +496,8 @@ fn parse_arg(
462496 Mode :: RustcOnUnimplemented
463497 | Mode :: DiagnosticOnUnimplemented
464498 | Mode :: DiagnosticOnMove
465- | Mode :: DiagnosticOnConst ,
499+ | Mode :: DiagnosticOnConst
500+ | Mode :: DiagnosticOnTypeError ,
466501 generic_param,
467502 ) => FormatArg :: GenericParam { generic_param, span } ,
468503
0 commit comments