@@ -998,169 +998,19 @@ impl LinkCollector<'_, '_> {
998998 }
999999 }
10001000
1001- match disambiguator. map ( Disambiguator :: ns) {
1002- Some ( ns @ ( ValueNS | TypeNS ) ) => {
1003- match self . resolve ( path_str, ns, & current_item, base_node, & extra_fragment) {
1004- Ok ( res) => res,
1005- Err ( ErrorKind :: Resolve ( box mut kind) ) => {
1006- // We only looked in one namespace. Try to give a better error if possible.
1007- if kind. full_res ( ) . is_none ( ) {
1008- let other_ns = if ns == ValueNS { TypeNS } else { ValueNS } ;
1009- for & new_ns in & [ other_ns, MacroNS ] {
1010- if let Some ( res) = self . check_full_res (
1011- new_ns,
1012- path_str,
1013- base_node,
1014- & current_item,
1015- & extra_fragment,
1016- ) {
1017- kind = ResolutionFailure :: WrongNamespace ( res, ns) ;
1018- break ;
1019- }
1020- }
1021- }
1022- resolution_failure (
1023- self ,
1024- & item,
1025- path_str,
1026- disambiguator,
1027- dox,
1028- link_range,
1029- smallvec ! [ kind] ,
1030- ) ;
1031- // This could just be a normal link or a broken link
1032- // we could potentially check if something is
1033- // "intra-doc-link-like" and warn in that case.
1034- return ;
1035- }
1036- Err ( ErrorKind :: AnchorFailure ( msg) ) => {
1037- anchor_failure ( cx, & item, & ori_link, dox, link_range, msg) ;
1038- return ;
1039- }
1040- }
1041- }
1042- None => {
1043- // Try everything!
1044- let mut candidates = PerNS {
1045- macro_ns : self
1046- . macro_resolve ( path_str, base_node)
1047- . map ( |res| ( res, extra_fragment. clone ( ) ) ) ,
1048- type_ns : match self . resolve (
1049- path_str,
1050- TypeNS ,
1051- & current_item,
1052- base_node,
1053- & extra_fragment,
1054- ) {
1055- Ok ( res) => {
1056- debug ! ( "got res in TypeNS: {:?}" , res) ;
1057- Ok ( res)
1058- }
1059- Err ( ErrorKind :: AnchorFailure ( msg) ) => {
1060- anchor_failure ( cx, & item, & ori_link, dox, link_range, msg) ;
1061- return ;
1062- }
1063- Err ( ErrorKind :: Resolve ( box kind) ) => Err ( kind) ,
1064- } ,
1065- value_ns : match self . resolve (
1066- path_str,
1067- ValueNS ,
1068- & current_item,
1069- base_node,
1070- & extra_fragment,
1071- ) {
1072- Ok ( res) => Ok ( res) ,
1073- Err ( ErrorKind :: AnchorFailure ( msg) ) => {
1074- anchor_failure ( cx, & item, & ori_link, dox, link_range, msg) ;
1075- return ;
1076- }
1077- Err ( ErrorKind :: Resolve ( box kind) ) => Err ( kind) ,
1078- }
1079- . and_then ( |( res, fragment) | {
1080- // Constructors are picked up in the type namespace.
1081- match res {
1082- Res :: Def ( DefKind :: Ctor ( ..) , _) | Res :: SelfCtor ( ..) => {
1083- Err ( ResolutionFailure :: WrongNamespace ( res, TypeNS ) )
1084- }
1085- _ => match ( fragment, extra_fragment) {
1086- ( Some ( fragment) , Some ( _) ) => {
1087- // Shouldn't happen but who knows?
1088- Ok ( ( res, Some ( fragment) ) )
1089- }
1090- ( fragment, None ) | ( None , fragment) => Ok ( ( res, fragment) ) ,
1091- } ,
1092- }
1093- } ) ,
1094- } ;
1095-
1096- let len = candidates. iter ( ) . filter ( |res| res. is_ok ( ) ) . count ( ) ;
1097-
1098- if len == 0 {
1099- resolution_failure (
1100- self ,
1101- & item,
1102- path_str,
1103- disambiguator,
1104- dox,
1105- link_range,
1106- candidates. into_iter ( ) . filter_map ( |res| res. err ( ) ) . collect ( ) ,
1107- ) ;
1108- // this could just be a normal link
1109- return ;
1110- }
1111-
1112- if len == 1 {
1113- candidates. into_iter ( ) . filter_map ( |res| res. ok ( ) ) . next ( ) . unwrap ( )
1114- } else if len == 2 && is_derive_trait_collision ( & candidates) {
1115- candidates. type_ns . unwrap ( )
1116- } else {
1117- if is_derive_trait_collision ( & candidates) {
1118- candidates. macro_ns = Err ( ResolutionFailure :: Dummy ) ;
1119- }
1120- // If we're reporting an ambiguity, don't mention the namespaces that failed
1121- let candidates =
1122- candidates. map ( |candidate| candidate. ok ( ) . map ( |( res, _) | res) ) ;
1123- ambiguity_error (
1124- cx,
1125- & item,
1126- path_str,
1127- dox,
1128- link_range,
1129- candidates. present_items ( ) . collect ( ) ,
1130- ) ;
1131- return ;
1132- }
1133- }
1134- Some ( MacroNS ) => {
1135- match self . macro_resolve ( path_str, base_node) {
1136- Ok ( res) => ( res, extra_fragment) ,
1137- Err ( mut kind) => {
1138- // `macro_resolve` only looks in the macro namespace. Try to give a better error if possible.
1139- for & ns in & [ TypeNS , ValueNS ] {
1140- if let Some ( res) = self . check_full_res (
1141- ns,
1142- path_str,
1143- base_node,
1144- & current_item,
1145- & extra_fragment,
1146- ) {
1147- kind = ResolutionFailure :: WrongNamespace ( res, MacroNS ) ;
1148- break ;
1149- }
1150- }
1151- resolution_failure (
1152- self ,
1153- & item,
1154- path_str,
1155- disambiguator,
1156- dox,
1157- link_range,
1158- smallvec ! [ kind] ,
1159- ) ;
1160- return ;
1161- }
1162- }
1163- }
1001+ match self . resolve_with_disambiguator (
1002+ disambiguator,
1003+ item,
1004+ dox,
1005+ path_str,
1006+ current_item,
1007+ base_node,
1008+ extra_fragment,
1009+ & ori_link,
1010+ link_range. clone ( ) ,
1011+ ) {
1012+ Some ( x) => x,
1013+ None => return ,
11641014 }
11651015 } ;
11661016
@@ -1274,6 +1124,183 @@ impl LinkCollector<'_, '_> {
12741124 item. attrs . links . push ( ItemLink { link : ori_link, link_text, did : Some ( id) , fragment } ) ;
12751125 }
12761126 }
1127+
1128+ fn resolve_with_disambiguator (
1129+ & self ,
1130+ disambiguator : Option < Disambiguator > ,
1131+ item : & mut Item ,
1132+ dox : & str ,
1133+ path_str : & str ,
1134+ current_item : & Option < String > ,
1135+ base_node : Option < DefId > ,
1136+ extra_fragment : Option < String > ,
1137+ ori_link : & str ,
1138+ link_range : Option < Range < usize > > ,
1139+ ) -> Option < ( Res , Option < String > ) > {
1140+ match disambiguator. map ( Disambiguator :: ns) {
1141+ Some ( ns @ ( ValueNS | TypeNS ) ) => {
1142+ match self . resolve ( path_str, ns, & current_item, base_node, & extra_fragment) {
1143+ Ok ( res) => Some ( res) ,
1144+ Err ( ErrorKind :: Resolve ( box mut kind) ) => {
1145+ // We only looked in one namespace. Try to give a better error if possible.
1146+ if kind. full_res ( ) . is_none ( ) {
1147+ let other_ns = if ns == ValueNS { TypeNS } else { ValueNS } ;
1148+ for & new_ns in & [ other_ns, MacroNS ] {
1149+ if let Some ( res) = self . check_full_res (
1150+ new_ns,
1151+ path_str,
1152+ base_node,
1153+ & current_item,
1154+ & extra_fragment,
1155+ ) {
1156+ kind = ResolutionFailure :: WrongNamespace ( res, ns) ;
1157+ break ;
1158+ }
1159+ }
1160+ }
1161+ resolution_failure (
1162+ self ,
1163+ & item,
1164+ path_str,
1165+ disambiguator,
1166+ dox,
1167+ link_range,
1168+ smallvec ! [ kind] ,
1169+ ) ;
1170+ // This could just be a normal link or a broken link
1171+ // we could potentially check if something is
1172+ // "intra-doc-link-like" and warn in that case.
1173+ return None ;
1174+ }
1175+ Err ( ErrorKind :: AnchorFailure ( msg) ) => {
1176+ anchor_failure ( self . cx , & item, & ori_link, dox, link_range, msg) ;
1177+ return None ;
1178+ }
1179+ }
1180+ }
1181+ None => {
1182+ // Try everything!
1183+ let mut candidates = PerNS {
1184+ macro_ns : self
1185+ . macro_resolve ( path_str, base_node)
1186+ . map ( |res| ( res, extra_fragment. clone ( ) ) ) ,
1187+ type_ns : match self . resolve (
1188+ path_str,
1189+ TypeNS ,
1190+ & current_item,
1191+ base_node,
1192+ & extra_fragment,
1193+ ) {
1194+ Ok ( res) => {
1195+ debug ! ( "got res in TypeNS: {:?}" , res) ;
1196+ Ok ( res)
1197+ }
1198+ Err ( ErrorKind :: AnchorFailure ( msg) ) => {
1199+ anchor_failure ( self . cx , & item, ori_link, dox, link_range, msg) ;
1200+ return None ;
1201+ }
1202+ Err ( ErrorKind :: Resolve ( box kind) ) => Err ( kind) ,
1203+ } ,
1204+ value_ns : match self . resolve (
1205+ path_str,
1206+ ValueNS ,
1207+ & current_item,
1208+ base_node,
1209+ & extra_fragment,
1210+ ) {
1211+ Ok ( res) => Ok ( res) ,
1212+ Err ( ErrorKind :: AnchorFailure ( msg) ) => {
1213+ anchor_failure ( self . cx , & item, ori_link, dox, link_range, msg) ;
1214+ return None ;
1215+ }
1216+ Err ( ErrorKind :: Resolve ( box kind) ) => Err ( kind) ,
1217+ }
1218+ . and_then ( |( res, fragment) | {
1219+ // Constructors are picked up in the type namespace.
1220+ match res {
1221+ Res :: Def ( DefKind :: Ctor ( ..) , _) | Res :: SelfCtor ( ..) => {
1222+ Err ( ResolutionFailure :: WrongNamespace ( res, TypeNS ) )
1223+ }
1224+ _ => match ( fragment, extra_fragment) {
1225+ ( Some ( fragment) , Some ( _) ) => {
1226+ // Shouldn't happen but who knows?
1227+ Ok ( ( res, Some ( fragment) ) )
1228+ }
1229+ ( fragment, None ) | ( None , fragment) => Ok ( ( res, fragment) ) ,
1230+ } ,
1231+ }
1232+ } ) ,
1233+ } ;
1234+
1235+ let len = candidates. iter ( ) . filter ( |res| res. is_ok ( ) ) . count ( ) ;
1236+
1237+ if len == 0 {
1238+ resolution_failure (
1239+ self ,
1240+ & item,
1241+ path_str,
1242+ disambiguator,
1243+ dox,
1244+ link_range,
1245+ candidates. into_iter ( ) . filter_map ( |res| res. err ( ) ) . collect ( ) ,
1246+ ) ;
1247+ // this could just be a normal link
1248+ return None ;
1249+ }
1250+
1251+ if len == 1 {
1252+ Some ( candidates. into_iter ( ) . filter_map ( |res| res. ok ( ) ) . next ( ) . unwrap ( ) )
1253+ } else if len == 2 && is_derive_trait_collision ( & candidates) {
1254+ Some ( candidates. type_ns . unwrap ( ) )
1255+ } else {
1256+ if is_derive_trait_collision ( & candidates) {
1257+ candidates. macro_ns = Err ( ResolutionFailure :: Dummy ) ;
1258+ }
1259+ // If we're reporting an ambiguity, don't mention the namespaces that failed
1260+ let candidates = candidates. map ( |candidate| candidate. ok ( ) . map ( |( res, _) | res) ) ;
1261+ ambiguity_error (
1262+ self . cx ,
1263+ & item,
1264+ path_str,
1265+ dox,
1266+ link_range,
1267+ candidates. present_items ( ) . collect ( ) ,
1268+ ) ;
1269+ return None ;
1270+ }
1271+ }
1272+ Some ( MacroNS ) => {
1273+ match self . macro_resolve ( path_str, base_node) {
1274+ Ok ( res) => Some ( ( res, extra_fragment) ) ,
1275+ Err ( mut kind) => {
1276+ // `macro_resolve` only looks in the macro namespace. Try to give a better error if possible.
1277+ for & ns in & [ TypeNS , ValueNS ] {
1278+ if let Some ( res) = self . check_full_res (
1279+ ns,
1280+ path_str,
1281+ base_node,
1282+ & current_item,
1283+ & extra_fragment,
1284+ ) {
1285+ kind = ResolutionFailure :: WrongNamespace ( res, MacroNS ) ;
1286+ break ;
1287+ }
1288+ }
1289+ resolution_failure (
1290+ self ,
1291+ & item,
1292+ path_str,
1293+ disambiguator,
1294+ dox,
1295+ link_range,
1296+ smallvec ! [ kind] ,
1297+ ) ;
1298+ return None ;
1299+ }
1300+ }
1301+ }
1302+ }
1303+ }
12771304}
12781305
12791306#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
0 commit comments