1
+ #![ deny( rustc:: untranslatable_diagnostic) ]
2
+
3
+ use crate :: errors:: {
4
+ ArgumentNotAttributes , AttrNoArguments , AttributeMetaItem , AttributeSingleWord ,
5
+ AttributesWrongForm , CannotBeNameOfMacro , ExpectedCommaInList , HelperAttributeNameInvalid ,
6
+ MacroBodyStability , MacroConstStability , NotAMetaItem , OnlyOneArgument , OnlyOneWord ,
7
+ ResolveRelativePath , TakesNoArguments ,
8
+ } ;
1
9
use crate :: expand:: { self , AstFragment , Invocation } ;
2
10
use crate :: module:: DirOwnership ;
3
11
@@ -789,26 +797,16 @@ impl SyntaxExtension {
789
797
. unwrap_or_else ( || ( None , helper_attrs) ) ;
790
798
let ( stability, const_stability, body_stability) = attr:: find_stability ( & sess, attrs, span) ;
791
799
if let Some ( ( _, sp) ) = const_stability {
792
- sess. parse_sess
793
- . span_diagnostic
794
- . struct_span_err ( sp, "macros cannot have const stability attributes" )
795
- . span_label ( sp, "invalid const stability attribute" )
796
- . span_label (
797
- sess. source_map ( ) . guess_head_span ( span) ,
798
- "const stability attribute affects this macro" ,
799
- )
800
- . emit ( ) ;
800
+ sess. emit_err ( MacroConstStability {
801
+ span : sp,
802
+ head_span : sess. source_map ( ) . guess_head_span ( span) ,
803
+ } ) ;
801
804
}
802
805
if let Some ( ( _, sp) ) = body_stability {
803
- sess. parse_sess
804
- . span_diagnostic
805
- . struct_span_err ( sp, "macros cannot have body stability attributes" )
806
- . span_label ( sp, "invalid body stability attribute" )
807
- . span_label (
808
- sess. source_map ( ) . guess_head_span ( span) ,
809
- "body stability attribute affects this macro" ,
810
- )
811
- . emit ( ) ;
806
+ sess. emit_err ( MacroBodyStability {
807
+ span : sp,
808
+ head_span : sess. source_map ( ) . guess_head_span ( span) ,
809
+ } ) ;
812
810
}
813
811
814
812
SyntaxExtension {
@@ -1200,13 +1198,11 @@ pub fn resolve_path(
1200
1198
. expect ( "attempting to resolve a file path in an external file" ) ,
1201
1199
FileName :: DocTest ( path, _) => path,
1202
1200
other => {
1203
- return Err ( parse_sess . span_diagnostic . struct_span_err (
1201
+ return Err ( ResolveRelativePath {
1204
1202
span,
1205
- & format ! (
1206
- "cannot resolve relative path in non-file source `{}`" ,
1207
- parse_sess. source_map( ) . filename_for_diagnostics( & other)
1208
- ) ,
1209
- ) ) ;
1203
+ path : parse_sess. source_map ( ) . filename_for_diagnostics ( & other) . to_string ( ) ,
1204
+ }
1205
+ . into_diagnostic ( & parse_sess. span_diagnostic ) ) ;
1210
1206
}
1211
1207
} ;
1212
1208
result. pop ( ) ;
@@ -1222,6 +1218,8 @@ pub fn resolve_path(
1222
1218
/// The returned bool indicates whether an applicable suggestion has already been
1223
1219
/// added to the diagnostic to avoid emitting multiple suggestions. `Err(None)`
1224
1220
/// indicates that an ast error was encountered.
1221
+ // FIXME(Nilstrieb) Make this function setup translatable
1222
+ #[ allow( rustc:: untranslatable_diagnostic) ]
1225
1223
pub fn expr_to_spanned_string < ' a > (
1226
1224
cx : & ' a mut ExtCtxt < ' _ > ,
1227
1225
expr : P < ast:: Expr > ,
@@ -1280,9 +1278,9 @@ pub fn expr_to_string(
1280
1278
/// compilation should call
1281
1279
/// `cx.parse_sess.span_diagnostic.abort_if_errors()` (this should be
1282
1280
/// done as rarely as possible).
1283
- pub fn check_zero_tts ( cx : & ExtCtxt < ' _ > , sp : Span , tts : TokenStream , name : & str ) {
1281
+ pub fn check_zero_tts ( cx : & ExtCtxt < ' _ > , span : Span , tts : TokenStream , name : & str ) {
1284
1282
if !tts. is_empty ( ) {
1285
- cx. span_err ( sp , & format ! ( "{} takes no arguments" , name) ) ;
1283
+ cx. emit_err ( TakesNoArguments { span , name } ) ;
1286
1284
}
1287
1285
}
1288
1286
@@ -1304,31 +1302,27 @@ pub fn parse_expr(p: &mut parser::Parser<'_>) -> Option<P<ast::Expr>> {
1304
1302
/// expect exactly one string literal, or emit an error and return `None`.
1305
1303
pub fn get_single_str_from_tts (
1306
1304
cx : & mut ExtCtxt < ' _ > ,
1307
- sp : Span ,
1305
+ span : Span ,
1308
1306
tts : TokenStream ,
1309
1307
name : & str ,
1310
1308
) -> Option < Symbol > {
1311
1309
let mut p = cx. new_parser_from_tts ( tts) ;
1312
1310
if p. token == token:: Eof {
1313
- cx. span_err ( sp , & format ! ( "{} takes 1 argument" , name) ) ;
1311
+ cx. emit_err ( OnlyOneArgument { span , name } ) ;
1314
1312
return None ;
1315
1313
}
1316
1314
let ret = parse_expr ( & mut p) ?;
1317
1315
let _ = p. eat ( & token:: Comma ) ;
1318
1316
1319
1317
if p. token != token:: Eof {
1320
- cx. span_err ( sp , & format ! ( "{} takes 1 argument" , name) ) ;
1318
+ cx. emit_err ( OnlyOneArgument { span , name } ) ;
1321
1319
}
1322
1320
expr_to_string ( cx, ret, "argument must be a string literal" ) . map ( |( s, _) | s)
1323
1321
}
1324
1322
1325
1323
/// Extracts comma-separated expressions from `tts`.
1326
1324
/// On error, emit it, and return `None`.
1327
- pub fn get_exprs_from_tts (
1328
- cx : & mut ExtCtxt < ' _ > ,
1329
- sp : Span ,
1330
- tts : TokenStream ,
1331
- ) -> Option < Vec < P < ast:: Expr > > > {
1325
+ pub fn get_exprs_from_tts ( cx : & mut ExtCtxt < ' _ > , tts : TokenStream ) -> Option < Vec < P < ast:: Expr > > > {
1332
1326
let mut p = cx. new_parser_from_tts ( tts) ;
1333
1327
let mut es = Vec :: new ( ) ;
1334
1328
while p. token != token:: Eof {
@@ -1343,7 +1337,7 @@ pub fn get_exprs_from_tts(
1343
1337
continue ;
1344
1338
}
1345
1339
if p. token != token:: Eof {
1346
- cx. span_err ( sp , "expected token: `,`" ) ;
1340
+ cx. emit_err ( ExpectedCommaInList { span : p . token . span } ) ;
1347
1341
return None ;
1348
1342
}
1349
1343
}
@@ -1353,64 +1347,58 @@ pub fn get_exprs_from_tts(
1353
1347
pub fn parse_macro_name_and_helper_attrs (
1354
1348
diag : & rustc_errors:: Handler ,
1355
1349
attr : & Attribute ,
1356
- descr : & str ,
1350
+ macro_type : & str ,
1357
1351
) -> Option < ( Symbol , Vec < Symbol > ) > {
1358
1352
// Once we've located the `#[proc_macro_derive]` attribute, verify
1359
1353
// that it's of the form `#[proc_macro_derive(Foo)]` or
1360
1354
// `#[proc_macro_derive(Foo, attributes(A, ..))]`
1361
1355
let list = attr. meta_item_list ( ) ?;
1362
1356
if list. len ( ) != 1 && list. len ( ) != 2 {
1363
- diag. span_err ( attr. span , "attribute must have either one or two arguments" ) ;
1357
+ diag. emit_err ( AttrNoArguments { span : attr. span } ) ;
1364
1358
return None ;
1365
1359
}
1366
1360
let Some ( trait_attr) = list[ 0 ] . meta_item ( ) else {
1367
- diag. span_err ( list[ 0 ] . span ( ) , "not a meta item" ) ;
1361
+ diag. emit_err ( NotAMetaItem { span : list[ 0 ] . span ( ) } ) ;
1368
1362
return None ;
1369
1363
} ;
1370
1364
let trait_ident = match trait_attr. ident ( ) {
1371
1365
Some ( trait_ident) if trait_attr. is_word ( ) => trait_ident,
1372
1366
_ => {
1373
- diag. span_err ( trait_attr. span , "must only be one word" ) ;
1367
+ diag. emit_err ( OnlyOneWord { span : trait_attr. span } ) ;
1374
1368
return None ;
1375
1369
}
1376
1370
} ;
1377
1371
1378
1372
if !trait_ident. name . can_be_raw ( ) {
1379
- diag. span_err (
1380
- trait_attr. span ,
1381
- & format ! ( "`{}` cannot be a name of {} macro" , trait_ident, descr) ,
1382
- ) ;
1373
+ diag. emit_err ( CannotBeNameOfMacro { span : trait_attr. span , trait_ident, macro_type } ) ;
1383
1374
}
1384
1375
1385
1376
let attributes_attr = list. get ( 1 ) ;
1386
1377
let proc_attrs: Vec < _ > = if let Some ( attr) = attributes_attr {
1387
1378
if !attr. has_name ( sym:: attributes) {
1388
- diag. span_err ( attr. span ( ) , "second argument must be `attributes`" ) ;
1379
+ diag. emit_err ( ArgumentNotAttributes { span : attr. span ( ) } ) ;
1389
1380
}
1390
1381
attr. meta_item_list ( )
1391
1382
. unwrap_or_else ( || {
1392
- diag. span_err ( attr . span ( ) , "attribute must be of form: `attributes(foo, bar)`" ) ;
1383
+ diag. emit_err ( AttributesWrongForm { span : attr . span ( ) } ) ;
1393
1384
& [ ]
1394
1385
} )
1395
1386
. iter ( )
1396
1387
. filter_map ( |attr| {
1397
1388
let Some ( attr) = attr. meta_item ( ) else {
1398
- diag. span_err ( attr. span ( ) , "not a meta item" ) ;
1389
+ diag. emit_err ( AttributeMetaItem { span : attr. span ( ) } ) ;
1399
1390
return None ;
1400
1391
} ;
1401
1392
1402
1393
let ident = match attr. ident ( ) {
1403
1394
Some ( ident) if attr. is_word ( ) => ident,
1404
1395
_ => {
1405
- diag. span_err ( attr. span , "must only be one word" ) ;
1396
+ diag. emit_err ( AttributeSingleWord { span : attr. span } ) ;
1406
1397
return None ;
1407
1398
}
1408
1399
} ;
1409
1400
if !ident. name . can_be_raw ( ) {
1410
- diag. span_err (
1411
- attr. span ,
1412
- & format ! ( "`{}` cannot be a name of derive helper attribute" , ident) ,
1413
- ) ;
1401
+ diag. emit_err ( HelperAttributeNameInvalid { span : attr. span , name : ident } ) ;
1414
1402
}
1415
1403
1416
1404
Some ( ident. name )
0 commit comments