@@ -390,10 +390,25 @@ impl CheckAttrVisitor<'tcx> {
390390 . emit ( ) ;
391391 }
392392
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 {
395401 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 ( ) ;
397412 return false ;
398413 }
399414 if let Some ( c) =
@@ -403,7 +418,11 @@ impl CheckAttrVisitor<'tcx> {
403418 . sess
404419 . struct_span_err (
405420 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+ ) ,
407426 )
408427 . emit ( ) ;
409428 return false ;
@@ -413,7 +432,10 @@ impl CheckAttrVisitor<'tcx> {
413432 . sess
414433 . struct_span_err (
415434 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+ ) ,
417439 )
418440 . emit ( ) ;
419441 return false ;
@@ -446,7 +468,11 @@ impl CheckAttrVisitor<'tcx> {
446468 . sess
447469 . struct_span_err (
448470 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+ ) ,
450476 )
451477 . emit ( ) ;
452478 return false ;
@@ -457,14 +483,67 @@ impl CheckAttrVisitor<'tcx> {
457483 . sess
458484 . struct_span_err (
459485 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+ ) ,
461490 )
462491 . emit ( ) ;
463492 return false ;
464493 }
465494 true
466495 }
467496
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+
468547 fn check_doc_keyword ( & self , meta : & NestedMetaItem , hir_id : HirId ) -> bool {
469548 let doc_keyword = meta. value_str ( ) . map ( |s| s. to_string ( ) ) . unwrap_or_else ( String :: new) ;
470549 if doc_keyword. is_empty ( ) {
0 commit comments