@@ -394,33 +394,50 @@ impl CheckAttrVisitor<'tcx> {
394
394
. emit ( ) ;
395
395
}
396
396
397
- fn check_doc_alias ( & self , meta : & NestedMetaItem , hir_id : HirId , target : Target ) -> bool {
398
- let doc_alias = meta. value_str ( ) . map ( |s| s. to_string ( ) ) . unwrap_or_else ( String :: new) ;
397
+ fn check_doc_alias_value (
398
+ & self ,
399
+ meta : & NestedMetaItem ,
400
+ doc_alias : & str ,
401
+ hir_id : HirId ,
402
+ target : Target ,
403
+ is_list : bool ,
404
+ ) -> bool {
405
+ let tcx = self . tcx ;
406
+ let err_fn = move |span : Span , msg : & str | {
407
+ tcx. sess . span_err (
408
+ span,
409
+ & format ! (
410
+ "`#[doc(alias{})]` {}" ,
411
+ if is_list { "(\" ...\" )" } else { " = \" ...\" " } ,
412
+ msg,
413
+ ) ,
414
+ ) ;
415
+ false
416
+ } ;
399
417
if doc_alias. is_empty ( ) {
400
- self . doc_attr_str_error ( meta, "alias" ) ;
401
- return false ;
418
+ return err_fn (
419
+ meta. name_value_literal_span ( ) . unwrap_or_else ( || meta. span ( ) ) ,
420
+ "attribute cannot have empty value" ,
421
+ ) ;
402
422
}
403
423
if let Some ( c) =
404
424
doc_alias. chars ( ) . find ( |& c| c == '"' || c == '\'' || ( c. is_whitespace ( ) && c != ' ' ) )
405
425
{
406
- self . tcx
407
- . sess
408
- . struct_span_err (
409
- meta. name_value_literal_span ( ) . unwrap_or_else ( || meta. span ( ) ) ,
410
- & format ! ( "{:?} character isn't allowed in `#[doc(alias = \" ...\" )]`" , c) ,
411
- )
412
- . emit ( ) ;
426
+ self . tcx . sess . span_err (
427
+ meta. name_value_literal_span ( ) . unwrap_or_else ( || meta. span ( ) ) ,
428
+ & format ! (
429
+ "{:?} character isn't allowed in `#[doc(alias{})]`" ,
430
+ c,
431
+ if is_list { "(\" ...\" )" } else { " = \" ...\" " } ,
432
+ ) ,
433
+ ) ;
413
434
return false ;
414
435
}
415
436
if doc_alias. starts_with ( ' ' ) || doc_alias. ends_with ( ' ' ) {
416
- self . tcx
417
- . sess
418
- . struct_span_err (
419
- meta. name_value_literal_span ( ) . unwrap_or_else ( || meta. span ( ) ) ,
420
- "`#[doc(alias = \" ...\" )]` cannot start or end with ' '" ,
421
- )
422
- . emit ( ) ;
423
- return false ;
437
+ return err_fn (
438
+ meta. name_value_literal_span ( ) . unwrap_or_else ( || meta. span ( ) ) ,
439
+ "cannot start or end with ' '" ,
440
+ ) ;
424
441
}
425
442
if let Some ( err) = match target {
426
443
Target :: Impl => Some ( "implementation block" ) ,
@@ -446,27 +463,63 @@ impl CheckAttrVisitor<'tcx> {
446
463
}
447
464
_ => None ,
448
465
} {
449
- self . tcx
450
- . sess
451
- . struct_span_err (
452
- meta. span ( ) ,
453
- & format ! ( "`#[doc(alias = \" ...\" )]` isn't allowed on {}" , err) ,
454
- )
455
- . emit ( ) ;
456
- return false ;
466
+ return err_fn ( meta. span ( ) , & format ! ( "isn't allowed on {}" , err) ) ;
457
467
}
458
468
let item_name = self . tcx . hir ( ) . name ( hir_id) ;
459
469
if & * item_name. as_str ( ) == doc_alias {
470
+ return err_fn ( meta. span ( ) , "is the same as the item's name" ) ;
471
+ }
472
+ true
473
+ }
474
+
475
+ fn check_doc_alias ( & self , meta : & NestedMetaItem , hir_id : HirId , target : Target ) -> bool {
476
+ if let Some ( values) = meta. meta_item_list ( ) {
477
+ let mut errors = 0 ;
478
+ for v in values {
479
+ match v. literal ( ) {
480
+ Some ( l) => match l. kind {
481
+ LitKind :: Str ( s, _) => {
482
+ if !self . check_doc_alias_value ( v, & s. as_str ( ) , hir_id, target, true ) {
483
+ errors += 1 ;
484
+ }
485
+ }
486
+ _ => {
487
+ self . tcx
488
+ . sess
489
+ . struct_span_err (
490
+ v. span ( ) ,
491
+ "`#[doc(alias(\" a\" ))]` expects string literals" ,
492
+ )
493
+ . emit ( ) ;
494
+ errors += 1 ;
495
+ }
496
+ } ,
497
+ None => {
498
+ self . tcx
499
+ . sess
500
+ . struct_span_err (
501
+ v. span ( ) ,
502
+ "`#[doc(alias(\" a\" ))]` expects string literals" ,
503
+ )
504
+ . emit ( ) ;
505
+ errors += 1 ;
506
+ }
507
+ }
508
+ }
509
+ errors == 0
510
+ } else if let Some ( doc_alias) = meta. value_str ( ) . map ( |s| s. to_string ( ) ) {
511
+ self . check_doc_alias_value ( meta, & doc_alias, hir_id, target, false )
512
+ } else {
460
513
self . tcx
461
514
. sess
462
515
. struct_span_err (
463
516
meta. span ( ) ,
464
- & format ! ( "`#[doc(alias = \" ...\" )]` is the same as the item's name" ) ,
517
+ "doc alias attribute expects a string `#[doc(alias = \" a\" )]` or a list of \
518
+ strings `#[doc(alias(\" a\" , \" b\" ))]`",
465
519
)
466
520
. emit ( ) ;
467
- return false ;
521
+ false
468
522
}
469
- true
470
523
}
471
524
472
525
fn check_doc_keyword ( & self , meta : & NestedMetaItem , hir_id : HirId ) -> bool {
0 commit comments