@@ -390,10 +390,25 @@ impl CheckAttrVisitor<'tcx> {
390
390
. emit ( ) ;
391
391
}
392
392
393
- fn check_doc_alias ( & self , meta : & NestedMetaItem , hir_id : HirId , target : Target ) -> bool {
394
- let doc_alias = meta. value_str ( ) . map ( |s| s. to_string ( ) ) . unwrap_or_else ( String :: new) ;
393
+ fn check_doc_alias_value (
394
+ & self ,
395
+ meta : & NestedMetaItem ,
396
+ doc_alias : & str ,
397
+ hir_id : HirId ,
398
+ target : Target ,
399
+ is_list : bool ,
400
+ ) -> bool {
395
401
if doc_alias. is_empty ( ) {
396
- self . doc_attr_str_error ( meta, "alias" ) ;
402
+ self . tcx
403
+ . sess
404
+ . struct_span_err (
405
+ meta. name_value_literal_span ( ) . unwrap_or_else ( || meta. span ( ) ) ,
406
+ & format ! (
407
+ "`#[doc(alias{})]` attribute cannot have empty value" ,
408
+ if is_list { "(\" ...\" )" } else { " = \" ...\" " } ,
409
+ ) ,
410
+ )
411
+ . emit ( ) ;
397
412
return false ;
398
413
}
399
414
if let Some ( c) =
@@ -403,7 +418,11 @@ impl CheckAttrVisitor<'tcx> {
403
418
. sess
404
419
. struct_span_err (
405
420
meta. name_value_literal_span ( ) . unwrap_or_else ( || meta. span ( ) ) ,
406
- & format ! ( "{:?} character isn't allowed in `#[doc(alias = \" ...\" )]`" , c) ,
421
+ & format ! (
422
+ "{:?} character isn't allowed in `#[doc(alias{})]`" ,
423
+ c,
424
+ if is_list { "(\" ...\" )" } else { " = \" ...\" " } ,
425
+ ) ,
407
426
)
408
427
. emit ( ) ;
409
428
return false ;
@@ -413,7 +432,10 @@ impl CheckAttrVisitor<'tcx> {
413
432
. sess
414
433
. struct_span_err (
415
434
meta. name_value_literal_span ( ) . unwrap_or_else ( || meta. span ( ) ) ,
416
- "`#[doc(alias = \" ...\" )]` cannot start or end with ' '" ,
435
+ & format ! (
436
+ "`#[doc(alias{})]` cannot start or end with ' '" ,
437
+ if is_list { "(\" ...\" )" } else { " = \" ...\" " } ,
438
+ ) ,
417
439
)
418
440
. emit ( ) ;
419
441
return false ;
@@ -446,7 +468,11 @@ impl CheckAttrVisitor<'tcx> {
446
468
. sess
447
469
. struct_span_err (
448
470
meta. span ( ) ,
449
- & format ! ( "`#[doc(alias = \" ...\" )]` isn't allowed on {}" , err) ,
471
+ & format ! (
472
+ "`#[doc(alias{})]` isn't allowed on {}" ,
473
+ if is_list { "(\" ...\" )" } else { " = \" ...\" " } ,
474
+ err,
475
+ ) ,
450
476
)
451
477
. emit ( ) ;
452
478
return false ;
@@ -457,14 +483,67 @@ impl CheckAttrVisitor<'tcx> {
457
483
. sess
458
484
. struct_span_err (
459
485
meta. span ( ) ,
460
- & format ! ( "`#[doc(alias = \" ...\" )]` is the same as the item's name" ) ,
486
+ & format ! (
487
+ "`#[doc(alias{})]` is the same as the item's name" ,
488
+ if is_list { "(\" ...\" )" } else { " = \" ...\" " } ,
489
+ ) ,
461
490
)
462
491
. emit ( ) ;
463
492
return false ;
464
493
}
465
494
true
466
495
}
467
496
497
+ fn check_doc_alias ( & self , meta : & NestedMetaItem , hir_id : HirId , target : Target ) -> bool {
498
+ if let Some ( values) = meta. meta_item_list ( ) {
499
+ let mut errors = 0 ;
500
+ for v in values {
501
+ match v. literal ( ) {
502
+ Some ( l) => match l. kind {
503
+ LitKind :: Str ( s, _) => {
504
+ if !self . check_doc_alias_value ( v, & s. as_str ( ) , hir_id, target, true ) {
505
+ errors += 1 ;
506
+ }
507
+ }
508
+ _ => {
509
+ self . tcx
510
+ . sess
511
+ . struct_span_err (
512
+ v. span ( ) ,
513
+ "`#[doc(alias(\" a\" )]` expects string literals" ,
514
+ )
515
+ . emit ( ) ;
516
+ errors += 1 ;
517
+ }
518
+ } ,
519
+ None => {
520
+ self . tcx
521
+ . sess
522
+ . struct_span_err (
523
+ v. span ( ) ,
524
+ "`#[doc(alias(\" a\" )]` expects string literals" ,
525
+ )
526
+ . emit ( ) ;
527
+ errors += 1 ;
528
+ }
529
+ }
530
+ }
531
+ errors == 0
532
+ } else if let Some ( doc_alias) = meta. value_str ( ) . map ( |s| s. to_string ( ) ) {
533
+ self . check_doc_alias_value ( meta, & doc_alias, hir_id, target, false )
534
+ } else {
535
+ self . tcx
536
+ . sess
537
+ . struct_span_err (
538
+ meta. span ( ) ,
539
+ "doc alias attribute expects a string `#[doc(alias = \" a\" )]` or a list of \
540
+ strings: `#[doc(alias(\" a\" , \" b\" )]`",
541
+ )
542
+ . emit ( ) ;
543
+ false
544
+ }
545
+ }
546
+
468
547
fn check_doc_keyword ( & self , meta : & NestedMetaItem , hir_id : HirId ) -> bool {
469
548
let doc_keyword = meta. value_str ( ) . map ( |s| s. to_string ( ) ) . unwrap_or_else ( String :: new) ;
470
549
if doc_keyword. is_empty ( ) {
0 commit comments