@@ -7,6 +7,7 @@ use std::num::NonZeroU32;
77use std:: rc:: Rc ;
88use std:: sync:: Arc ;
99use std:: { slice, vec} ;
10+ use std:: lazy:: SyncOnceCell as OnceCell ;
1011
1112use rustc_ast:: attr;
1213use rustc_ast:: util:: comments:: beautify_doc_string;
@@ -26,7 +27,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
2627use rustc_span:: { self , FileName } ;
2728use rustc_target:: abi:: VariantIdx ;
2829use rustc_target:: spec:: abi:: Abi ;
29- use smallvec:: SmallVec ;
30+ use smallvec:: { SmallVec , smallvec } ;
3031
3132use crate :: clean:: cfg:: Cfg ;
3233use crate :: clean:: external_path;
@@ -1266,61 +1267,85 @@ impl PrimitiveType {
12661267 }
12671268 }
12681269
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+ } }
13021296 }
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- } ;
13191297
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+ } )
13211347 }
13221348
1323-
13241349 pub fn to_url_str ( & self ) -> & ' static str {
13251350 self . as_str ( )
13261351 }
0 commit comments