@@ -56,6 +56,59 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
56
56
}
57
57
}
58
58
59
+ fn variant_field (
60
+ & self ,
61
+ path_str : & str ,
62
+ current_item : & Option < String > ,
63
+ module_id : syntax:: ast:: NodeId ,
64
+ ) -> Result < ( Res , Option < String > ) , ( ) > {
65
+ let cx = self . cx ;
66
+
67
+ let mut split = path_str. rsplitn ( 3 , "::" ) ;
68
+ let variant_field_name = split. next ( ) . map ( |f| Symbol :: intern ( f) ) . ok_or ( ( ) ) ?;
69
+ let variant_name = split. next ( ) . map ( |f| Symbol :: intern ( f) ) . ok_or ( ( ) ) ?;
70
+ let path = split. next ( ) . map ( |f| {
71
+ if f == "self" || f == "Self" {
72
+ if let Some ( name) = current_item. as_ref ( ) {
73
+ return name. clone ( ) ;
74
+ }
75
+ }
76
+ f. to_owned ( )
77
+ } ) . ok_or ( ( ) ) ?;
78
+ let ( _, ty_res) = cx. enter_resolver ( |resolver| {
79
+ resolver. resolve_str_path_error ( DUMMY_SP , & path, TypeNS , module_id)
80
+ } ) ?;
81
+ if let Res :: Err = ty_res {
82
+ return Err ( ( ) ) ;
83
+ }
84
+ let ty_res = ty_res. map_id ( |_| panic ! ( "unexpected node_id" ) ) ;
85
+ match ty_res {
86
+ Res :: Def ( DefKind :: Enum , did) => {
87
+ let item = cx. tcx . inherent_impls ( did)
88
+ . iter ( )
89
+ . flat_map ( |imp| cx. tcx . associated_items ( * imp) )
90
+ . find ( |item| item. ident . name == variant_name) ;
91
+ if item. is_some ( ) {
92
+ return Err ( ( ) ) ;
93
+ }
94
+ match cx. tcx . type_of ( did) . kind {
95
+ ty:: Adt ( def, _) if def. is_enum ( ) => {
96
+ if def. all_fields ( )
97
+ . find ( |item| item. ident . name == variant_field_name) . is_some ( ) {
98
+ Ok ( ( ty_res,
99
+ Some ( format ! ( "variant.{}.field.{}" ,
100
+ variant_name, variant_field_name) ) ) )
101
+ } else {
102
+ Err ( ( ) )
103
+ }
104
+ }
105
+ _ => Err ( ( ) ) ,
106
+ }
107
+ }
108
+ _ => Err ( ( ) )
109
+ }
110
+ }
111
+
59
112
/// Resolves a string as a path within a particular namespace. Also returns an optional
60
113
/// URL fragment in the case of variants and methods.
61
114
fn resolve (
@@ -149,7 +202,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
149
202
resolver. resolve_str_path_error ( DUMMY_SP , & path, TypeNS , module_id)
150
203
} ) . map_err ( |_| ErrorKind :: ResolutionFailure ) ?;
151
204
if let Res :: Err = ty_res {
152
- return Err ( ErrorKind :: ResolutionFailure ) ;
205
+ return self . variant_field ( path_str , current_item , module_id ) ;
153
206
}
154
207
let ty_res = ty_res. map_id ( |_| panic ! ( "unexpected node_id" ) ) ;
155
208
match ty_res {
@@ -165,7 +218,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
165
218
let out = match item. kind {
166
219
ty:: AssocKind :: Method if ns == ValueNS => "method" ,
167
220
ty:: AssocKind :: Const if ns == ValueNS => "associatedconstant" ,
168
- _ => return Err ( ErrorKind :: ResolutionFailure )
221
+ _ => return self . variant_field ( path_str , current_item , module_id ) ,
169
222
} ;
170
223
if extra_fragment. is_some ( ) {
171
224
Err ( ErrorKind :: AnchorFailure (
@@ -206,10 +259,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
206
259
item. ident) ) ) )
207
260
}
208
261
} else {
209
- Err ( ErrorKind :: ResolutionFailure )
262
+ self . variant_field ( path_str , current_item , module_id )
210
263
}
211
264
}
212
- _ => Err ( ErrorKind :: ResolutionFailure ) ,
265
+ _ => self . variant_field ( path_str , current_item , module_id ) ,
213
266
}
214
267
}
215
268
}
@@ -228,7 +281,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
228
281
"tymethod"
229
282
}
230
283
}
231
- _ => return Err ( ErrorKind :: ResolutionFailure )
284
+ _ => return self . variant_field ( path_str , current_item , module_id ) ,
232
285
} ;
233
286
234
287
if extra_fragment. is_some ( ) {
@@ -244,10 +297,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
244
297
Ok ( ( ty_res, Some ( format ! ( "{}.{}" , kind, item_name) ) ) )
245
298
}
246
299
} else {
247
- Err ( ErrorKind :: ResolutionFailure )
300
+ self . variant_field ( path_str , current_item , module_id )
248
301
}
249
302
}
250
- _ => Err ( ErrorKind :: ResolutionFailure )
303
+ _ => self . variant_field ( path_str , current_item , module_id ) ,
251
304
}
252
305
} else {
253
306
debug ! ( "attempting to resolve item without parent module: {}" , path_str) ;
0 commit comments