@@ -16,6 +16,7 @@ use rustc_session::lint::{
16
16
Lint ,
17
17
} ;
18
18
use rustc_span:: hygiene:: MacroKind ;
19
+ use rustc_span:: symbol:: sym;
19
20
use rustc_span:: symbol:: Ident ;
20
21
use rustc_span:: symbol:: Symbol ;
21
22
use rustc_span:: DUMMY_SP ;
@@ -234,6 +235,52 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
234
235
}
235
236
}
236
237
238
+ fn resolve_primitive_associated_item (
239
+ & self ,
240
+ prim_ty : hir:: PrimTy ,
241
+ prim : Res ,
242
+ ns : Namespace ,
243
+ module_id : DefId ,
244
+ item_name : Symbol ,
245
+ item_str : & ' path str ,
246
+ ) -> Result < ( Res , Option < String > ) , ErrorKind < ' path > > {
247
+ let cx = self . cx ;
248
+
249
+ PrimitiveType :: from_hir ( prim_ty)
250
+ . impls ( cx. tcx )
251
+ . into_iter ( )
252
+ . find_map ( |& impl_| {
253
+ cx. tcx
254
+ . associated_items ( impl_)
255
+ . find_by_name_and_namespace (
256
+ cx. tcx ,
257
+ Ident :: with_dummy_span ( item_name) ,
258
+ ns,
259
+ impl_,
260
+ )
261
+ . map ( |item| match item. kind {
262
+ ty:: AssocKind :: Fn => "method" ,
263
+ ty:: AssocKind :: Const => "associatedconstant" ,
264
+ ty:: AssocKind :: Type => "associatedtype" ,
265
+ } )
266
+ . map ( |out| ( prim, Some ( format ! ( "{}#{}.{}" , prim_ty. name( ) , out, item_str) ) ) )
267
+ } )
268
+ . ok_or_else ( || {
269
+ debug ! (
270
+ "returning primitive error for {}::{} in {} namespace" ,
271
+ prim_ty. name( ) ,
272
+ item_name,
273
+ ns. descr( )
274
+ ) ;
275
+ ResolutionFailure :: NotResolved {
276
+ module_id,
277
+ partial_res : Some ( prim) ,
278
+ unresolved : item_str. into ( ) ,
279
+ }
280
+ . into ( )
281
+ } )
282
+ }
283
+
237
284
/// Resolves a string as a macro.
238
285
fn macro_resolve (
239
286
& self ,
@@ -275,6 +322,20 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
275
322
} )
276
323
}
277
324
325
+ fn resolve_path ( & self , path_str : & str , ns : Namespace , module_id : DefId ) -> Option < Res > {
326
+ let result = self . cx . enter_resolver ( |resolver| {
327
+ resolver. resolve_str_path_error ( DUMMY_SP , & path_str, ns, module_id)
328
+ } ) ;
329
+ debug ! ( "{} resolved to {:?} in namespace {:?}" , path_str, result, ns) ;
330
+ match result. map ( |( _, res) | res) {
331
+ Ok ( Res :: Err ) | Err ( ( ) ) => is_bool_value ( path_str, ns) . map ( |( _, res) | res) ,
332
+
333
+ // resolver doesn't know about true and false so we'll have to resolve them
334
+ // manually as bool
335
+ Ok ( res) => Some ( res. map_id ( |_| panic ! ( "unexpected node_id" ) ) ) ,
336
+ }
337
+ }
338
+
278
339
/// Resolves a string as a path within a particular namespace. Also returns an optional
279
340
/// URL fragment in the case of variants and methods.
280
341
fn resolve < ' path > (
@@ -287,32 +348,15 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
287
348
) -> Result < ( Res , Option < String > ) , ErrorKind < ' path > > {
288
349
let cx = self . cx ;
289
350
290
- let result = cx. enter_resolver ( |resolver| {
291
- resolver. resolve_str_path_error ( DUMMY_SP , & path_str, ns, module_id)
292
- } ) ;
293
- debug ! ( "{} resolved to {:?} in namespace {:?}" , path_str, result, ns) ;
294
- let result = match result. map ( |( _, res) | res) {
295
- Ok ( Res :: Err ) | Err ( ( ) ) => {
296
- // resolver doesn't know about true and false so we'll have to resolve them
297
- // manually as bool
298
- if let Some ( ( _, res) ) = is_bool_value ( path_str, ns) { Ok ( res) } else { Err ( ( ) ) }
299
- }
300
- Ok ( res) => Ok ( res. map_id ( |_| panic ! ( "unexpected node_id" ) ) ) ,
301
- } ;
302
-
303
- if let Ok ( res) = result {
351
+ if let Some ( res) = self . resolve_path ( path_str, ns, module_id) {
304
352
match res {
305
353
Res :: Def ( DefKind :: AssocFn | DefKind :: AssocConst , _) => {
306
- if ns != ValueNS {
307
- return Err ( ResolutionFailure :: WrongNamespace ( res, ns) . into ( ) ) ;
308
- }
354
+ assert_eq ! ( ns, ValueNS ) ;
309
355
// Fall through: In case this is a trait item, skip the
310
356
// early return and try looking for the trait.
311
357
}
312
358
Res :: Def ( DefKind :: AssocTy , _) => {
313
- if ns != TypeNS {
314
- return Err ( ResolutionFailure :: WrongNamespace ( res, ns) . into ( ) ) ;
315
- }
359
+ assert_eq ! ( ns, TypeNS ) ;
316
360
// Fall through: In case this is a trait item, skip the
317
361
// early return and try looking for the trait.
318
362
}
@@ -362,70 +406,29 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
362
406
}
363
407
} ) ?;
364
408
365
- if let Some ( ( path, prim) ) = is_primitive ( & path_root, TypeNS ) {
366
- let impls =
367
- primitive_impl ( cx, & path) . ok_or_else ( || ResolutionFailure :: NotResolved {
409
+ let ty_res = if let Some ( ty_res) = is_primitive ( & path_root, TypeNS )
410
+ . map ( |( _, res) | res)
411
+ . or_else ( || self . resolve_path ( & path_root, TypeNS , module_id) )
412
+ {
413
+ ty_res
414
+ } else {
415
+ // FIXME: this is duplicated on the end of this function.
416
+ return if ns == Namespace :: ValueNS {
417
+ self . variant_field ( path_str, current_item, module_id)
418
+ } else {
419
+ Err ( ResolutionFailure :: NotResolved {
368
420
module_id,
369
- partial_res : Some ( prim) ,
370
- unresolved : item_str. into ( ) ,
371
- } ) ?;
372
- for & impl_ in impls {
373
- let link = cx
374
- . tcx
375
- . associated_items ( impl_)
376
- . find_by_name_and_namespace (
377
- cx. tcx ,
378
- Ident :: with_dummy_span ( item_name) ,
379
- ns,
380
- impl_,
381
- )
382
- . map ( |item| match item. kind {
383
- ty:: AssocKind :: Fn => "method" ,
384
- ty:: AssocKind :: Const => "associatedconstant" ,
385
- ty:: AssocKind :: Type => "associatedtype" ,
386
- } )
387
- . map ( |out| ( prim, Some ( format ! ( "{}#{}.{}" , path, out, item_str) ) ) ) ;
388
- if let Some ( link) = link {
389
- return Ok ( link) ;
421
+ partial_res : None ,
422
+ unresolved : path_root. into ( ) ,
390
423
}
391
- }
392
- debug ! (
393
- "returning primitive error for {}::{} in {} namespace" ,
394
- path,
395
- item_name,
396
- ns. descr( )
397
- ) ;
398
- return Err ( ResolutionFailure :: NotResolved {
399
- module_id,
400
- partial_res : Some ( prim) ,
401
- unresolved : item_str. into ( ) ,
402
- }
403
- . into ( ) ) ;
404
- }
405
-
406
- let ty_res = cx
407
- . enter_resolver ( |resolver| {
408
- // only types can have associated items
409
- resolver. resolve_str_path_error ( DUMMY_SP , & path_root, TypeNS , module_id)
410
- } )
411
- . map ( |( _, res) | res) ;
412
- let ty_res = match ty_res {
413
- Err ( ( ) ) | Ok ( Res :: Err ) => {
414
- return if ns == Namespace :: ValueNS {
415
- self . variant_field ( path_str, current_item, module_id)
416
- } else {
417
- Err ( ResolutionFailure :: NotResolved {
418
- module_id,
419
- partial_res : None ,
420
- unresolved : path_root. into ( ) ,
421
- }
422
- . into ( ) )
423
- } ;
424
- }
425
- Ok ( res) => res,
424
+ . into ( ) )
425
+ } ;
426
426
} ;
427
- let ty_res = ty_res . map_id ( |_| panic ! ( "unexpected node_id" ) ) ;
427
+
428
428
let res = match ty_res {
429
+ Res :: PrimTy ( prim) => Some ( self . resolve_primitive_associated_item (
430
+ prim, ty_res, ns, module_id, item_name, item_str,
431
+ ) ) ,
429
432
Res :: Def ( DefKind :: Struct | DefKind :: Union | DefKind :: Enum | DefKind :: TyAlias , did) => {
430
433
debug ! ( "looking for associated item named {} for item {:?}" , item_name, did) ;
431
434
// Checks if item_name belongs to `impl SomeItem`
@@ -465,7 +468,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
465
468
Some ( if extra_fragment. is_some ( ) {
466
469
Err ( ErrorKind :: AnchorFailure ( AnchorFailure :: RustdocAnchorConflict ( ty_res) ) )
467
470
} else {
468
- // HACK(jynelson): `clean` expects the type, not the associated item.
471
+ // HACK(jynelson): `clean` expects the type, not the associated item
469
472
// but the disambiguator logic expects the associated item.
470
473
// Store the kind in a side channel so that only the disambiguator logic looks at it.
471
474
self . kind_side_channel . set ( Some ( ( kind. as_def_kind ( ) , id) ) ) ;
@@ -511,13 +514,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
511
514
_ => None ,
512
515
}
513
516
} else {
514
- // We already know this isn't in ValueNS, so no need to check variant_field
515
- return Err ( ResolutionFailure :: NotResolved {
516
- module_id,
517
- partial_res : Some ( ty_res) ,
518
- unresolved : item_str. into ( ) ,
519
- }
520
- . into ( ) ) ;
517
+ None
521
518
}
522
519
}
523
520
Res :: Def ( DefKind :: Trait , did) => cx
@@ -1089,7 +1086,7 @@ impl LinkCollector<'_, '_> {
1089
1086
return None ;
1090
1087
}
1091
1088
res = prim;
1092
- fragment = Some ( path. to_owned ( ) ) ;
1089
+ fragment = Some ( ( * path. as_str ( ) ) . to_owned ( ) ) ;
1093
1090
} else {
1094
1091
// `[char]` when a `char` module is in scope
1095
1092
let candidates = vec ! [ res, prim] ;
@@ -1956,44 +1953,45 @@ fn handle_variant(
1956
1953
)
1957
1954
}
1958
1955
1959
- const PRIMITIVES : & [ ( & str , Res ) ] = & [
1960
- ( "u8" , Res :: PrimTy ( hir:: PrimTy :: Uint ( rustc_ast:: UintTy :: U8 ) ) ) ,
1961
- ( "u16" , Res :: PrimTy ( hir:: PrimTy :: Uint ( rustc_ast:: UintTy :: U16 ) ) ) ,
1962
- ( "u32" , Res :: PrimTy ( hir:: PrimTy :: Uint ( rustc_ast:: UintTy :: U32 ) ) ) ,
1963
- ( "u64" , Res :: PrimTy ( hir:: PrimTy :: Uint ( rustc_ast:: UintTy :: U64 ) ) ) ,
1964
- ( "u128" , Res :: PrimTy ( hir:: PrimTy :: Uint ( rustc_ast:: UintTy :: U128 ) ) ) ,
1965
- ( "usize" , Res :: PrimTy ( hir:: PrimTy :: Uint ( rustc_ast:: UintTy :: Usize ) ) ) ,
1966
- ( "i8" , Res :: PrimTy ( hir:: PrimTy :: Int ( rustc_ast:: IntTy :: I8 ) ) ) ,
1967
- ( "i16" , Res :: PrimTy ( hir:: PrimTy :: Int ( rustc_ast:: IntTy :: I16 ) ) ) ,
1968
- ( "i32" , Res :: PrimTy ( hir:: PrimTy :: Int ( rustc_ast:: IntTy :: I32 ) ) ) ,
1969
- ( "i64" , Res :: PrimTy ( hir:: PrimTy :: Int ( rustc_ast:: IntTy :: I64 ) ) ) ,
1970
- ( "i128" , Res :: PrimTy ( hir:: PrimTy :: Int ( rustc_ast:: IntTy :: I128 ) ) ) ,
1971
- ( "isize" , Res :: PrimTy ( hir:: PrimTy :: Int ( rustc_ast:: IntTy :: Isize ) ) ) ,
1972
- ( "f32" , Res :: PrimTy ( hir:: PrimTy :: Float ( rustc_ast:: FloatTy :: F32 ) ) ) ,
1973
- ( "f64" , Res :: PrimTy ( hir:: PrimTy :: Float ( rustc_ast:: FloatTy :: F64 ) ) ) ,
1974
- ( "str" , Res :: PrimTy ( hir:: PrimTy :: Str ) ) ,
1975
- ( "bool" , Res :: PrimTy ( hir:: PrimTy :: Bool ) ) ,
1976
- ( "char" , Res :: PrimTy ( hir:: PrimTy :: Char ) ) ,
1956
+ // FIXME: At this point, this is basically a copy of the PrimitiveTypeTable
1957
+ const PRIMITIVES : & [ ( Symbol , Res ) ] = & [
1958
+ ( sym:: u8, Res :: PrimTy ( hir:: PrimTy :: Uint ( rustc_ast:: UintTy :: U8 ) ) ) ,
1959
+ ( sym:: u16, Res :: PrimTy ( hir:: PrimTy :: Uint ( rustc_ast:: UintTy :: U16 ) ) ) ,
1960
+ ( sym:: u32, Res :: PrimTy ( hir:: PrimTy :: Uint ( rustc_ast:: UintTy :: U32 ) ) ) ,
1961
+ ( sym:: u64, Res :: PrimTy ( hir:: PrimTy :: Uint ( rustc_ast:: UintTy :: U64 ) ) ) ,
1962
+ ( sym:: u128, Res :: PrimTy ( hir:: PrimTy :: Uint ( rustc_ast:: UintTy :: U128 ) ) ) ,
1963
+ ( sym:: usize, Res :: PrimTy ( hir:: PrimTy :: Uint ( rustc_ast:: UintTy :: Usize ) ) ) ,
1964
+ ( sym:: i8, Res :: PrimTy ( hir:: PrimTy :: Int ( rustc_ast:: IntTy :: I8 ) ) ) ,
1965
+ ( sym:: i16, Res :: PrimTy ( hir:: PrimTy :: Int ( rustc_ast:: IntTy :: I16 ) ) ) ,
1966
+ ( sym:: i32, Res :: PrimTy ( hir:: PrimTy :: Int ( rustc_ast:: IntTy :: I32 ) ) ) ,
1967
+ ( sym:: i64, Res :: PrimTy ( hir:: PrimTy :: Int ( rustc_ast:: IntTy :: I64 ) ) ) ,
1968
+ ( sym:: i128, Res :: PrimTy ( hir:: PrimTy :: Int ( rustc_ast:: IntTy :: I128 ) ) ) ,
1969
+ ( sym:: isize, Res :: PrimTy ( hir:: PrimTy :: Int ( rustc_ast:: IntTy :: Isize ) ) ) ,
1970
+ ( sym:: f32, Res :: PrimTy ( hir:: PrimTy :: Float ( rustc_ast:: FloatTy :: F32 ) ) ) ,
1971
+ ( sym:: f64, Res :: PrimTy ( hir:: PrimTy :: Float ( rustc_ast:: FloatTy :: F64 ) ) ) ,
1972
+ ( sym:: str, Res :: PrimTy ( hir:: PrimTy :: Str ) ) ,
1973
+ ( sym:: bool, Res :: PrimTy ( hir:: PrimTy :: Bool ) ) ,
1974
+ ( sym:: char, Res :: PrimTy ( hir:: PrimTy :: Char ) ) ,
1977
1975
] ;
1978
1976
1979
- fn is_primitive ( path_str : & str , ns : Namespace ) -> Option < ( & ' static str , Res ) > {
1977
+ fn is_primitive ( path_str : & str , ns : Namespace ) -> Option < ( Symbol , Res ) > {
1980
1978
is_bool_value ( path_str, ns) . or_else ( || {
1981
- if ns == TypeNS { PRIMITIVES . iter ( ) . find ( |x| x. 0 == path_str) . copied ( ) } else { None }
1979
+ if ns == TypeNS {
1980
+ PRIMITIVES . iter ( ) . find ( |x| x. 0 . as_str ( ) == path_str) . copied ( )
1981
+ } else {
1982
+ None
1983
+ }
1982
1984
} )
1983
1985
}
1984
1986
1985
- fn is_bool_value ( path_str : & str , ns : Namespace ) -> Option < ( & ' static str , Res ) > {
1987
+ fn is_bool_value ( path_str : & str , ns : Namespace ) -> Option < ( Symbol , Res ) > {
1986
1988
if ns == TypeNS && ( path_str == "true" || path_str == "false" ) {
1987
- Some ( ( " bool" , Res :: PrimTy ( hir:: PrimTy :: Bool ) ) )
1989
+ Some ( ( sym :: bool, Res :: PrimTy ( hir:: PrimTy :: Bool ) ) )
1988
1990
} else {
1989
1991
None
1990
1992
}
1991
1993
}
1992
1994
1993
- fn primitive_impl ( cx : & DocContext < ' _ > , path_str : & str ) -> Option < & ' static SmallVec < [ DefId ; 4 ] > > {
1994
- Some ( PrimitiveType :: from_symbol ( Symbol :: intern ( path_str) ) ?. impls ( cx. tcx ) )
1995
- }
1996
-
1997
1995
fn strip_generics_from_path ( path_str : & str ) -> Result < String , ResolutionFailure < ' static > > {
1998
1996
let mut stripped_segments = vec ! [ ] ;
1999
1997
let mut path = path_str. chars ( ) . peekable ( ) ;
0 commit comments