@@ -898,20 +898,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
898898 specified. article( ) ,
899899 specified. descr( )
900900 ) ;
901- let suggestion = resolved. display_for ( path_str) ;
902- let help_msg =
903- format ! ( "to link to the {}, use its disambiguator" , resolved. descr( ) ) ;
904901 diag. note ( & note) ;
905- if let Some ( sp) = sp {
906- diag. span_suggestion (
907- sp,
908- & help_msg,
909- suggestion,
910- Applicability :: MaybeIncorrect ,
911- ) ;
912- } else {
913- diag. help ( & format ! ( "{}: {}" , help_msg, suggestion) ) ;
914- }
902+ suggest_disambiguator ( resolved, diag, path_str, & dox, sp, & link_range) ;
915903 } ) ;
916904 } ;
917905 if let Res :: PrimTy ( _) = res {
@@ -1047,17 +1035,31 @@ impl Disambiguator {
10471035 }
10481036 }
10491037
1050- fn display_for ( self , path_str : & str ) -> String {
1038+ fn from_res ( res : Res ) -> Self {
1039+ match res {
1040+ Res :: Def ( kind, _) => Disambiguator :: Kind ( kind) ,
1041+ Res :: PrimTy ( _) => Disambiguator :: Primitive ,
1042+ _ => Disambiguator :: Namespace ( res. ns ( ) . expect ( "can't call `from_res` on Res::err" ) ) ,
1043+ }
1044+ }
1045+
1046+ /// Return (description of the change, suggestion)
1047+ fn display_for ( self , path_str : & str ) -> ( & ' static str , String ) {
1048+ const PREFIX : & str = "prefix with the item kind" ;
1049+ const FUNCTION : & str = "add parentheses" ;
1050+ const MACRO : & str = "add an exclamation mark" ;
1051+
10511052 let kind = match self {
1052- Disambiguator :: Primitive => return format ! ( "prim@{}" , path_str) ,
1053+ Disambiguator :: Primitive => return ( PREFIX , format ! ( "prim@{}" , path_str) ) ,
10531054 Disambiguator :: Kind ( kind) => kind,
10541055 Disambiguator :: Namespace ( _) => panic ! ( "display_for cannot be used on namespaces" ) ,
10551056 } ;
10561057 if kind == DefKind :: Macro ( MacroKind :: Bang ) {
1057- return format ! ( "{}!" , path_str) ;
1058+ return ( MACRO , format ! ( "{}!" , path_str) ) ;
10581059 } else if kind == DefKind :: Fn || kind == DefKind :: AssocFn {
1059- return format ! ( "{}()" , path_str) ;
1060+ return ( FUNCTION , format ! ( "{}()" , path_str) ) ;
10601061 }
1062+
10611063 let prefix = match kind {
10621064 DefKind :: Struct => "struct" ,
10631065 DefKind :: Enum => "enum" ,
@@ -1079,7 +1081,9 @@ impl Disambiguator {
10791081 Namespace :: MacroNS => "macro" ,
10801082 } ,
10811083 } ;
1082- format ! ( "{}@{}" , prefix, path_str)
1084+
1085+ // FIXME: if this is an implied shortcut link, it's bad style to suggest `@`
1086+ ( PREFIX , format ! ( "{}@{}" , prefix, path_str) )
10831087 }
10841088
10851089 fn ns ( self ) -> Namespace {
@@ -1276,52 +1280,39 @@ fn ambiguity_error(
12761280 report_diagnostic ( cx, & msg, item, dox, link_range. clone ( ) , |diag, sp| {
12771281 if let Some ( sp) = sp {
12781282 diag. span_label ( sp, "ambiguous link" ) ;
1283+ } else {
1284+ diag. note ( "ambiguous link" ) ;
1285+ }
12791286
1280- let link_range = link_range. expect ( "must have a link range if we have a span" ) ;
1281-
1282- for ( res, ns) in candidates {
1283- let ( action, mut suggestion) = match res {
1284- Res :: Def ( DefKind :: AssocFn | DefKind :: Fn , _) => {
1285- ( "add parentheses" , format ! ( "{}()" , path_str) )
1286- }
1287- Res :: Def ( DefKind :: Macro ( MacroKind :: Bang ) , _) => {
1288- ( "add an exclamation mark" , format ! ( "{}!" , path_str) )
1289- }
1290- _ => {
1291- let type_ = match ( res, ns) {
1292- ( Res :: PrimTy ( _) , _) => "prim" ,
1293- ( Res :: Def ( DefKind :: Const , _) , _) => "const" ,
1294- ( Res :: Def ( DefKind :: Static , _) , _) => "static" ,
1295- ( Res :: Def ( DefKind :: Struct , _) , _) => "struct" ,
1296- ( Res :: Def ( DefKind :: Enum , _) , _) => "enum" ,
1297- ( Res :: Def ( DefKind :: Union , _) , _) => "union" ,
1298- ( Res :: Def ( DefKind :: Trait , _) , _) => "trait" ,
1299- ( Res :: Def ( DefKind :: Mod , _) , _) => "module" ,
1300- ( _, TypeNS ) => "type" ,
1301- ( _, ValueNS ) => "value" ,
1302- ( Res :: Def ( DefKind :: Macro ( MacroKind :: Derive ) , _) , MacroNS ) => "derive" ,
1303- ( _, MacroNS ) => "macro" ,
1304- } ;
1305-
1306- // FIXME: if this is an implied shortcut link, it's bad style to suggest `@`
1307- ( "prefix with the item type" , format ! ( "{}@{}" , type_, path_str) )
1308- }
1309- } ;
1287+ for ( res, _ns) in candidates {
1288+ let disambiguator = Disambiguator :: from_res ( res) ;
1289+ suggest_disambiguator ( disambiguator, diag, path_str, dox, sp, & link_range) ;
1290+ }
1291+ } ) ;
1292+ }
13101293
1311- if dox. bytes ( ) . nth ( link_range. start ) == Some ( b'`' ) {
1312- suggestion = format ! ( "`{}`" , suggestion) ;
1313- }
1294+ fn suggest_disambiguator (
1295+ disambiguator : Disambiguator ,
1296+ diag : & mut DiagnosticBuilder < ' _ > ,
1297+ path_str : & str ,
1298+ dox : & str ,
1299+ sp : Option < rustc_span:: Span > ,
1300+ link_range : & Option < Range < usize > > ,
1301+ ) {
1302+ let ( action, mut suggestion) = disambiguator. display_for ( path_str) ;
1303+ let help = format ! ( "to link to the {}, {}" , disambiguator. descr( ) , action) ;
13141304
1315- // FIXME: Create a version of this suggestion for when we don't have the span.
1316- diag. span_suggestion (
1317- sp,
1318- & format ! ( "to link to the {}, {}" , res. descr( ) , action) ,
1319- suggestion,
1320- Applicability :: MaybeIncorrect ,
1321- ) ;
1322- }
1305+ if let Some ( sp) = sp {
1306+ let link_range = link_range. as_ref ( ) . expect ( "must have a link range if we have a span" ) ;
1307+ if dox. bytes ( ) . nth ( link_range. start ) == Some ( b'`' ) {
1308+ suggestion = format ! ( "`{}`" , suggestion) ;
13231309 }
1324- } ) ;
1310+
1311+ // FIXME: Create a version of this suggestion for when we don't have the span.
1312+ diag. span_suggestion ( sp, & help, suggestion, Applicability :: MaybeIncorrect ) ;
1313+ } else {
1314+ diag. help ( & format ! ( "{}: {}" , help, suggestion) ) ;
1315+ }
13251316}
13261317
13271318fn privacy_error (
0 commit comments