@@ -7,6 +7,7 @@ use std::num::NonZeroU32;
7
7
use std:: rc:: Rc ;
8
8
use std:: sync:: Arc ;
9
9
use std:: { slice, vec} ;
10
+ use std:: lazy:: SyncOnceCell as OnceCell ;
10
11
11
12
use rustc_ast:: ast:: { self , AttrStyle } ;
12
13
use rustc_ast:: attr;
@@ -26,7 +27,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
26
27
use rustc_span:: { self , FileName } ;
27
28
use rustc_target:: abi:: VariantIdx ;
28
29
use rustc_target:: spec:: abi:: Abi ;
29
- use smallvec:: SmallVec ;
30
+ use smallvec:: { SmallVec , smallvec } ;
30
31
31
32
use crate :: clean:: cfg:: Cfg ;
32
33
use crate :: clean:: external_path;
@@ -1266,61 +1267,85 @@ impl PrimitiveType {
1266
1267
}
1267
1268
}
1268
1269
1269
- pub fn impls ( & self , tcx : TyCtxt < ' _ > ) -> SmallVec < [ DefId ; 4 ] > {
1270
- use self :: PrimitiveType :: * ;
1271
-
1272
- let both =
1273
- |a : Option < DefId > , b : Option < DefId > | -> SmallVec < _ > { a. into_iter ( ) . chain ( b) . collect ( ) } ;
1274
-
1275
- let lang_items = tcx. lang_items ( ) ;
1276
- let primary_impl = match self {
1277
- Isize => lang_items. isize_impl ( ) ,
1278
- I8 => lang_items. i8_impl ( ) ,
1279
- I16 => lang_items. i16_impl ( ) ,
1280
- I32 => lang_items. i32_impl ( ) ,
1281
- I64 => lang_items. i64_impl ( ) ,
1282
- I128 => lang_items. i128_impl ( ) ,
1283
- Usize => lang_items. usize_impl ( ) ,
1284
- U8 => lang_items. u8_impl ( ) ,
1285
- U16 => lang_items. u16_impl ( ) ,
1286
- U32 => lang_items. u32_impl ( ) ,
1287
- U64 => lang_items. u64_impl ( ) ,
1288
- U128 => lang_items. u128_impl ( ) ,
1289
- F32 => return both ( lang_items. f32_impl ( ) , lang_items. f32_runtime_impl ( ) ) ,
1290
- F64 => return both ( lang_items. f64_impl ( ) , lang_items. f64_runtime_impl ( ) ) ,
1291
- Char => lang_items. char_impl ( ) ,
1292
- Bool => lang_items. bool_impl ( ) ,
1293
- Str => return both ( lang_items. str_impl ( ) , lang_items. str_alloc_impl ( ) ) ,
1294
- Slice => {
1295
- return lang_items
1296
- . slice_impl ( )
1297
- . into_iter ( )
1298
- . chain ( lang_items. slice_u8_impl ( ) )
1299
- . chain ( lang_items. slice_alloc_impl ( ) )
1300
- . chain ( lang_items. slice_u8_alloc_impl ( ) )
1301
- . collect ( ) ;
1270
+ pub fn impls ( & self , tcx : TyCtxt < ' _ > ) -> & SmallVec < [ DefId ; 4 ] > {
1271
+ Self :: all_impls ( tcx) . get ( self ) . expect ( "missing impl for primitive type" )
1272
+ }
1273
+
1274
+ pub fn all_impls ( tcx : TyCtxt < ' _ > ) -> & ' static FxHashMap < PrimitiveType , SmallVec < [ DefId ; 4 ] > > {
1275
+ static CELL : OnceCell < FxHashMap < PrimitiveType , SmallVec < [ DefId ; 4 ] > > > = OnceCell :: new ( ) ;
1276
+
1277
+ CELL . get_or_init ( move || {
1278
+ use self :: PrimitiveType :: * ;
1279
+
1280
+ /// A macro to create a FxHashMap.
1281
+ ///
1282
+ /// Example:
1283
+ ///
1284
+ /// ```
1285
+ /// let letters = map!{"a" => "b", "c" => "d"};
1286
+ /// ```
1287
+ ///
1288
+ /// Trailing commas are allowed.
1289
+ /// Commas between elements are required (even if the expression is a block).
1290
+ macro_rules! map {
1291
+ ( $( $key: expr => $val: expr ) ,* $( , ) * ) => { {
1292
+ let mut map = :: rustc_data_structures:: fx:: FxHashMap :: default ( ) ;
1293
+ $( map. insert( $key, $val) ; ) *
1294
+ map
1295
+ } }
1302
1296
}
1303
- Array => lang_items. array_impl ( ) ,
1304
- Tuple => None ,
1305
- Unit => None ,
1306
- RawPointer => {
1307
- return lang_items
1308
- . const_ptr_impl ( )
1309
- . into_iter ( )
1310
- . chain ( lang_items. mut_ptr_impl ( ) )
1311
- . chain ( lang_items. const_slice_ptr_impl ( ) )
1312
- . chain ( lang_items. mut_slice_ptr_impl ( ) )
1313
- . collect ( ) ;
1314
- }
1315
- Reference => None ,
1316
- Fn => None ,
1317
- Never => None ,
1318
- } ;
1319
1297
1320
- primary_impl. into_iter ( ) . collect ( )
1298
+ let single = |a : Option < DefId > | a. into_iter ( ) . collect ( ) ;
1299
+ let both =
1300
+ |a : Option < DefId > , b : Option < DefId > | -> SmallVec < _ > { a. into_iter ( ) . chain ( b) . collect ( ) } ;
1301
+
1302
+ let lang_items = tcx. lang_items ( ) ;
1303
+ map ! {
1304
+ Isize => single( lang_items. isize_impl( ) ) ,
1305
+ I8 => single( lang_items. i8_impl( ) ) ,
1306
+ I16 => single( lang_items. i16_impl( ) ) ,
1307
+ I32 => single( lang_items. i32_impl( ) ) ,
1308
+ I64 => single( lang_items. i64_impl( ) ) ,
1309
+ I128 => single( lang_items. i128_impl( ) ) ,
1310
+ Usize => single( lang_items. usize_impl( ) ) ,
1311
+ U8 => single( lang_items. u8_impl( ) ) ,
1312
+ U16 => single( lang_items. u16_impl( ) ) ,
1313
+ U32 => single( lang_items. u32_impl( ) ) ,
1314
+ U64 => single( lang_items. u64_impl( ) ) ,
1315
+ U128 => single( lang_items. u128_impl( ) ) ,
1316
+ F32 => both( lang_items. f32_impl( ) , lang_items. f32_runtime_impl( ) ) ,
1317
+ F64 => both( lang_items. f64_impl( ) , lang_items. f64_runtime_impl( ) ) ,
1318
+ Char => single( lang_items. char_impl( ) ) ,
1319
+ Bool => single( lang_items. bool_impl( ) ) ,
1320
+ Str => both( lang_items. str_impl( ) , lang_items. str_alloc_impl( ) ) ,
1321
+ Slice => {
1322
+ lang_items
1323
+ . slice_impl( )
1324
+ . into_iter( )
1325
+ . chain( lang_items. slice_u8_impl( ) )
1326
+ . chain( lang_items. slice_alloc_impl( ) )
1327
+ . chain( lang_items. slice_u8_alloc_impl( ) )
1328
+ . collect( )
1329
+ } ,
1330
+ Array => single( lang_items. array_impl( ) ) ,
1331
+ Tuple => smallvec![ ] ,
1332
+ Unit => smallvec![ ] ,
1333
+ RawPointer => {
1334
+ lang_items
1335
+ . const_ptr_impl( )
1336
+ . into_iter( )
1337
+ . chain( lang_items. mut_ptr_impl( ) )
1338
+ . chain( lang_items. const_slice_ptr_impl( ) )
1339
+ . chain( lang_items. mut_slice_ptr_impl( ) )
1340
+ . collect( )
1341
+ } ,
1342
+ Reference => smallvec![ ] ,
1343
+ Fn => smallvec![ ] ,
1344
+ Never => smallvec![ ] ,
1345
+ }
1346
+ } )
1321
1347
}
1322
1348
1323
-
1324
1349
pub fn to_url_str ( & self ) -> & ' static str {
1325
1350
self . as_str ( )
1326
1351
}
0 commit comments