Skip to content

Commit 3b1d2e3

Browse files
committed
Allow reusing the code in collect_trait_impls
1 parent c6ac860 commit 3b1d2e3

File tree

4 files changed

+80
-87
lines changed

4 files changed

+80
-87
lines changed

src/librustdoc/clean/types.rs

+77-52
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::num::NonZeroU32;
77
use std::rc::Rc;
88
use std::sync::Arc;
99
use std::{slice, vec};
10+
use std::lazy::SyncOnceCell as OnceCell;
1011

1112
use rustc_ast::ast::{self, AttrStyle};
1213
use rustc_ast::attr;
@@ -26,7 +27,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
2627
use rustc_span::{self, FileName};
2728
use rustc_target::abi::VariantIdx;
2829
use rustc_target::spec::abi::Abi;
29-
use smallvec::SmallVec;
30+
use smallvec::{SmallVec, smallvec};
3031

3132
use crate::clean::cfg::Cfg;
3233
use 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
}

src/librustdoc/clean/utils.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut V
368368
None => continue,
369369
},
370370
};
371-
for did in primitive.impls(tcx) {
371+
for &did in primitive.impls(tcx) {
372372
if !did.is_local() {
373373
inline::build_impl(cx, did, None, ret);
374374
}

src/librustdoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#![feature(ptr_offset_from)]
1313
#![feature(crate_visibility_modifier)]
1414
#![feature(never_type)]
15+
#![feature(once_cell)]
1516
#![recursion_limit = "256"]
1617

1718
#[macro_use]

src/librustdoc/passes/collect_trait_impls.rs

+1-34
Original file line numberDiff line numberDiff line change
@@ -34,40 +34,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
3434
}
3535

3636
// Also try to inline primitive impls from other crates.
37-
let lang_items = cx.tcx.lang_items();
38-
let primitive_impls = [
39-
lang_items.isize_impl(),
40-
lang_items.i8_impl(),
41-
lang_items.i16_impl(),
42-
lang_items.i32_impl(),
43-
lang_items.i64_impl(),
44-
lang_items.i128_impl(),
45-
lang_items.usize_impl(),
46-
lang_items.u8_impl(),
47-
lang_items.u16_impl(),
48-
lang_items.u32_impl(),
49-
lang_items.u64_impl(),
50-
lang_items.u128_impl(),
51-
lang_items.f32_impl(),
52-
lang_items.f64_impl(),
53-
lang_items.f32_runtime_impl(),
54-
lang_items.f64_runtime_impl(),
55-
lang_items.bool_impl(),
56-
lang_items.char_impl(),
57-
lang_items.str_impl(),
58-
lang_items.array_impl(),
59-
lang_items.slice_impl(),
60-
lang_items.slice_u8_impl(),
61-
lang_items.str_alloc_impl(),
62-
lang_items.slice_alloc_impl(),
63-
lang_items.slice_u8_alloc_impl(),
64-
lang_items.const_ptr_impl(),
65-
lang_items.mut_ptr_impl(),
66-
lang_items.const_slice_ptr_impl(),
67-
lang_items.mut_slice_ptr_impl(),
68-
];
69-
70-
for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) {
37+
for &def_id in PrimitiveType::all_impls(cx.tcx).values().flatten() {
7138
if !def_id.is_local() {
7239
inline::build_impl(cx, def_id, None, &mut new_items);
7340

0 commit comments

Comments
 (0)