@@ -677,6 +677,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
677677 }
678678 }
679679
680+ #[ expect( dead_code) ] // FIXME: remove fn etc. entirely
680681 fn doc_attr_str_error ( & self , meta : & MetaItemInner , attr_name : & str ) {
681682 self . dcx ( ) . emit_err ( errors:: DocExpectStr { attr_span : meta. span ( ) , attr_name } ) ;
682683 }
@@ -821,17 +822,60 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
821822 }
822823
823824 fn check_doc_keyword ( & self , meta : & MetaItemInner , hir_id : HirId ) {
825+
824826 fn is_doc_keyword ( s : Symbol ) -> bool {
825- // FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we
826- // can remove the `SelfTy` case here, remove `sym::SelfTy`, and update the
827- // `#[doc(keyword = "SelfTy")` attribute in `library/std/src/keyword_docs.rs`.
828- s. is_reserved ( || edition:: LATEST_STABLE_EDITION ) || s. is_weak ( ) || s == sym:: SelfTy
827+ s. is_reserved ( || edition:: LATEST_STABLE_EDITION ) || s. is_weak ( )
829828 }
830829
831- let doc_keyword = match meta. value_str ( ) {
832- Some ( value) if value != sym:: empty => value,
833- _ => return self . doc_attr_str_error ( meta, "keyword" ) ,
834- } ;
830+ // FIXME: Reject unsafe in various places.
831+ if let Some ( values) = meta. meta_item_list ( ) {
832+ let mut keyword = None ;
833+ // XXX XXX XXX docs
834+ let mut xx_url_name_override_xx = None ;
835+ for value in values {
836+ match value {
837+ MetaItemInner :: MetaItem ( meta) => {
838+ if meta. has_name ( sym:: encode)
839+ && let Some ( x) = meta. value_str ( )
840+ {
841+ if xx_url_name_override_xx. is_some ( ) {
842+ self . dcx ( )
843+ . span_err ( meta. span , "[[ encoding provided more than once ]]" ) ;
844+ }
845+ xx_url_name_override_xx = Some ( x) ;
846+ } else {
847+ self . dcx ( ) . span_err ( meta. span , "[[ invalid format ]]" ) ;
848+ }
849+ }
850+ MetaItemInner :: Lit ( lit) => {
851+ if let Some ( kw) = lit. value_str ( ) {
852+ if keyword. is_some ( ) {
853+ self . dcx ( )
854+ . span_err ( meta. span ( ) , "[[ keyword provided more than once ]]" ) ;
855+ }
856+ keyword = Some ( kw) ;
857+ } else {
858+ self . dcx ( ) . span_err ( meta. span ( ) , "[[ invalid format ]]" ) ;
859+ }
860+ }
861+ }
862+ }
863+
864+ _ = xx_url_name_override_xx;
865+
866+ if let Some ( keyword) = keyword {
867+ if !is_doc_keyword ( keyword) {
868+ self . dcx ( ) . emit_err ( errors:: DocKeywordNotKeyword {
869+ span : meta. name_value_literal_span ( ) . unwrap_or_else ( || meta. span ( ) ) ,
870+ keyword,
871+ } ) ;
872+ }
873+ } else {
874+ self . dcx ( ) . span_err ( meta. span ( ) , "[[ no keyword provided ]]" ) ;
875+ }
876+ } else {
877+ self . dcx ( ) . span_err ( meta. span ( ) , "[[ invalid format ]]" ) ;
878+ }
835879
836880 let item_kind = match self . tcx . hir_node ( hir_id) {
837881 hir:: Node :: Item ( item) => Some ( & item. kind ) ,
@@ -849,12 +893,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
849893 return ;
850894 }
851895 }
852- if !is_doc_keyword ( doc_keyword) {
853- self . dcx ( ) . emit_err ( errors:: DocKeywordNotKeyword {
854- span : meta. name_value_literal_span ( ) . unwrap_or_else ( || meta. span ( ) ) ,
855- keyword : doc_keyword,
856- } ) ;
857- }
858896 }
859897
860898 fn check_doc_fake_variadic ( & self , meta : & MetaItemInner , hir_id : HirId ) {
0 commit comments