@@ -998,169 +998,19 @@ impl LinkCollector<'_, '_> {
998
998
}
999
999
}
1000
1000
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 ,
1164
1014
}
1165
1015
} ;
1166
1016
@@ -1274,6 +1124,183 @@ impl LinkCollector<'_, '_> {
1274
1124
item. attrs . links . push ( ItemLink { link : ori_link, link_text, did : Some ( id) , fragment } ) ;
1275
1125
}
1276
1126
}
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
+ }
1277
1304
}
1278
1305
1279
1306
#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
0 commit comments