@@ -1192,10 +1192,11 @@ impl CTLexer {
11921192/// `HashMap{"ID": 0, "INT": 1}` the generated module will look roughly as follows:
11931193///
11941194/// ```rust,ignore
1195+ /// #[allow(dead_code)]
11951196/// mod x {
11961197/// pub const T_ID: u8 = 0;
11971198/// pub const T_INT: u8 = 1;
1198- /// pub const TOK_IDS: &[u8] = &[T_ID, T_INT ];
1199+ /// pub const TOK_IDS: &[u8] = &[0, 1 ];
11991200/// }
12001201/// ```
12011202///
@@ -1205,16 +1206,34 @@ impl CTLexer {
12051206/// module will look roughly as follows:
12061207///
12071208/// ```rust,ignore
1209+ /// #[allow(dead_code)]
12081210/// mod x {
12091211/// pub const T_PLUS: u8 = 0;
12101212/// pub const T_ID: u8 = 1;
1211- /// pub const TOK_IDS: &[u8] = &[T_PLUS, T_ID ];
1213+ /// pub const TOK_IDS: &[u8] = &[0, 1 ];
12121214/// }
12131215/// ```
1216+ ///
1217+ /// You can also use [`ct_token_map_require_usage`] to disable the `#[allow(dead_code)]` annotation.
1218+ /// This will help you to ensure that a custom lexer can produce every token used in a parser.
12141219pub fn ct_token_map < StorageT : Display + ToTokens > (
12151220 mod_name : & str ,
12161221 token_map : impl Borrow < HashMap < String , StorageT > > ,
12171222 rename_map : Option < & HashMap < & str , & str > > ,
1223+ ) -> Result < ( ) , Box < dyn Error > > {
1224+ ct_token_map_require_usage ( mod_name, token_map, rename_map, false )
1225+ }
1226+
1227+ /// Same as [`ct_token_map`], but allows disabling `#[allow(dead_code)]` annotation
1228+ /// for generated constants.
1229+ ///
1230+ /// This function can help you to ensure that a custom lexer can produce
1231+ /// every token used in a parser.
1232+ pub fn ct_token_map_require_usage < StorageT : Display + ToTokens > (
1233+ mod_name : & str ,
1234+ token_map : impl Borrow < HashMap < String , StorageT > > ,
1235+ rename_map : Option < & HashMap < & str , & str > > ,
1236+ require_usage : bool ,
12181237) -> Result < ( ) , Box < dyn Error > > {
12191238 // Record the time that this version of lrlex was built. If the source code changes and rustc
12201239 // forces a recompile, this will change this value, causing anything which depends on this
@@ -1237,21 +1256,30 @@ pub fn ct_token_map<StorageT: Display + ToTokens>(
12371256 } ;
12381257 let tok_ident = format_ident ! ( "T_{}" , name. to_ascii_uppercase( ) ) ;
12391258 (
1259+ // Note: the array of all tokens can't use `tok_ident` because
1260+ // it will confuse the dead code checker. For this reason,
1261+ // we use `id` here.
12401262 quote ! {
1241- #tok_ident ,
1263+ #id ,
12421264 } ,
12431265 quote ! {
12441266 pub const #tok_ident: #storaget = #id;
12451267 } ,
12461268 )
12471269 } )
12481270 . unzip ( ) ;
1271+ let unused_annotation = if require_usage {
1272+ quote ! { }
1273+ } else {
1274+ quote ! { #[ allow( dead_code) ] }
1275+ } ;
12491276 // Since the formatter doesn't preserve comments and we don't want to lose build time,
12501277 // just format the module contents.
12511278 let unformatted = quote ! {
1279+ #unused_annotation
12521280 mod #mod_ident {
1253- #![ allow( dead_code) ]
12541281 #tokens
1282+ #[ allow( dead_code) ]
12551283 pub const TOK_IDS : & [ #storaget] = & [ #token_array] ;
12561284 }
12571285 }
0 commit comments