Skip to content

Commit 4ace4e7

Browse files
committed
Use fewer .to_string()s
1 parent f45e7b5 commit 4ace4e7

File tree

1 file changed

+42
-39
lines changed

1 file changed

+42
-39
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use rustc_span::symbol::Symbol;
1919
use rustc_span::DUMMY_SP;
2020
use smallvec::{smallvec, SmallVec};
2121

22+
use std::borrow::Cow;
2223
use std::cell::Cell;
2324
use std::ops::Range;
2425

@@ -46,40 +47,40 @@ pub fn collect_intra_doc_links(krate: Crate, cx: &DocContext<'_>) -> Crate {
4647
}
4748
}
4849

49-
enum ErrorKind {
50-
Resolve(ResolutionFailure),
50+
enum ErrorKind<'a> {
51+
Resolve(ResolutionFailure<'a>),
5152
AnchorFailure(AnchorFailure),
5253
}
5354

5455
#[derive(Debug)]
55-
enum ResolutionFailure {
56+
enum ResolutionFailure<'a> {
5657
/// This resolved, but with the wrong namespace.
5758
/// `Namespace` is the expected namespace (as opposed to the actual).
5859
WrongNamespace(Res, Namespace),
5960
/// `String` is the base name of the path (not necessarily the whole link)
60-
NotInScope(String),
61+
NotInScope(Cow<'a, str>),
6162
/// this is a primitive type without an impls (no associated methods)
6263
/// when will this actually happen?
6364
/// the `Res` is the primitive it resolved to
6465
NoPrimitiveImpl(Res, String),
6566
/// `[u8::not_found]`
6667
/// the `Res` is the primitive it resolved to
67-
NoPrimitiveAssocItem { res: Res, prim_name: String, assoc_item: String },
68+
NoPrimitiveAssocItem { res: Res, prim_name: &'a str, assoc_item: Symbol },
6869
/// `[S::not_found]`
6970
/// the `String` is the associated item that wasn't found
70-
NoAssocItem(Res, String),
71+
NoAssocItem(Res, Symbol),
7172
/// should not ever happen
7273
NoParentItem,
7374
/// the root of this path resolved, but it was not an enum.
7475
NotAnEnum(Res),
7576
/// this could be an enum variant, but the last path fragment wasn't resolved.
7677
/// the `String` is the variant that didn't exist
77-
NotAVariant(Res, String),
78+
NotAVariant(Res, Symbol),
7879
/// used to communicate that this should be ignored, but shouldn't be reported to the user
7980
Dummy,
8081
}
8182

82-
impl ResolutionFailure {
83+
impl ResolutionFailure<'a> {
8384
fn res(&self) -> Option<Res> {
8485
use ResolutionFailure::*;
8586
match self {
@@ -121,10 +122,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
121122

122123
fn variant_field(
123124
&self,
124-
path_str: &str,
125+
path_str: &'path str,
125126
current_item: &Option<String>,
126127
module_id: DefId,
127-
) -> Result<(Res, Option<String>), ErrorKind> {
128+
) -> Result<(Res, Option<String>), ErrorKind<'path>> {
128129
let cx = self.cx;
129130

130131
let mut split = path_str.rsplitn(3, "::");
@@ -134,7 +135,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
134135
.expect("fold_item should ensure link is non-empty");
135136
let variant_name =
136137
// we're not sure this is a variant at all, so use the full string
137-
split.next().map(|f| Symbol::intern(f)).ok_or(ErrorKind::Resolve(ResolutionFailure::NotInScope(path_str.to_string())))?;
138+
split.next().map(|f| Symbol::intern(f)).ok_or(ErrorKind::Resolve(ResolutionFailure::NotInScope(path_str.into())))?;
138139
// TODO: this looks very wrong, why are we requiring 3 fields?
139140
let path = split
140141
.next()
@@ -147,14 +148,18 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
147148
f.to_owned()
148149
})
149150
// TODO: is this right?
150-
.ok_or(ErrorKind::Resolve(ResolutionFailure::NotInScope(variant_name.to_string())))?;
151+
.ok_or(ErrorKind::Resolve(ResolutionFailure::NotInScope(
152+
variant_name.to_string().into(),
153+
)))?;
151154
let (_, ty_res) = cx
152155
.enter_resolver(|resolver| {
153156
resolver.resolve_str_path_error(DUMMY_SP, &path, TypeNS, module_id)
154157
})
155-
.map_err(|_| ErrorKind::Resolve(ResolutionFailure::NotInScope(path.to_string())))?;
158+
.map_err(|_| {
159+
ErrorKind::Resolve(ResolutionFailure::NotInScope(path.to_string().into()))
160+
})?;
156161
if let Res::Err = ty_res {
157-
return Err(ErrorKind::Resolve(ResolutionFailure::NotInScope(path.to_string())));
162+
return Err(ErrorKind::Resolve(ResolutionFailure::NotInScope(path.to_string().into())));
158163
}
159164
let ty_res = ty_res.map_id(|_| panic!("unexpected node_id"));
160165
match ty_res {
@@ -183,7 +188,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
183188
} else {
184189
Err(ErrorKind::Resolve(ResolutionFailure::NotAVariant(
185190
ty_res,
186-
variant_field_name.to_string(),
191+
variant_field_name,
187192
)))
188193
}
189194
}
@@ -197,9 +202,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
197202
/// Resolves a string as a macro.
198203
fn macro_resolve(
199204
&self,
200-
path_str: &str,
205+
path_str: &'a str,
201206
parent_id: Option<DefId>,
202-
) -> Result<Res, ResolutionFailure> {
207+
) -> Result<Res, ResolutionFailure<'a>> {
203208
let cx = self.cx;
204209
let path = ast::Path::from_ident(Ident::from_str(path_str));
205210
cx.enter_resolver(|resolver| {
@@ -232,19 +237,19 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
232237
debug!("attempting to resolve item without parent module: {}", path_str);
233238
return Err(ResolutionFailure::NoParentItem);
234239
}
235-
return Err(ResolutionFailure::NotInScope(path_str.to_string()));
240+
return Err(ResolutionFailure::NotInScope(path_str.into()));
236241
})
237242
}
238243
/// Resolves a string as a path within a particular namespace. Also returns an optional
239244
/// URL fragment in the case of variants and methods.
240-
fn resolve(
245+
fn resolve<'path>(
241246
&self,
242-
path_str: &str,
247+
path_str: &'path str,
243248
ns: Namespace,
244249
current_item: &Option<String>,
245250
parent_id: Option<DefId>,
246251
extra_fragment: &Option<String>,
247-
) -> Result<(Res, Option<String>), ErrorKind> {
252+
) -> Result<(Res, Option<String>), ErrorKind<'path>> {
248253
let cx = self.cx;
249254

250255
// In case we're in a module, try to resolve the relative path.
@@ -309,11 +314,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
309314
})
310315
// If there's no `::`, it's not an associated item.
311316
// So we can be sure that `rustc_resolve` was accurate when it said it wasn't resolved.
312-
.ok_or(ErrorKind::Resolve(ResolutionFailure::NotInScope(item_name.to_string())))?;
317+
.ok_or(ErrorKind::Resolve(ResolutionFailure::NotInScope(
318+
item_name.to_string().into(),
319+
)))?;
313320

314321
if let Some((path, prim)) = is_primitive(&path_root, ns) {
315322
let impls = primitive_impl(cx, &path).ok_or_else(|| {
316-
ErrorKind::Resolve(ResolutionFailure::NoPrimitiveImpl(prim, path_root))
323+
ErrorKind::Resolve(ResolutionFailure::NoPrimitiveImpl(prim, path_root.into()))
317324
})?;
318325
for &impl_ in impls {
319326
let link = cx
@@ -337,8 +344,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
337344
}
338345
return Err(ErrorKind::Resolve(ResolutionFailure::NoPrimitiveAssocItem {
339346
res: prim,
340-
prim_name: path.to_string(),
341-
assoc_item: item_name.to_string(),
347+
prim_name: path,
348+
assoc_item: item_name,
342349
}));
343350
}
344351

@@ -347,13 +354,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
347354
resolver.resolve_str_path_error(DUMMY_SP, &path_root, TypeNS, module_id)
348355
})
349356
.map_err(|_| {
350-
ErrorKind::Resolve(ResolutionFailure::NotInScope(path_root.clone()))
357+
ErrorKind::Resolve(ResolutionFailure::NotInScope(path_root.clone().into()))
351358
})?;
352359
if let Res::Err = ty_res {
353360
return if ns == Namespace::ValueNS {
354361
self.variant_field(path_str, current_item, module_id)
355362
} else {
356-
Err(ErrorKind::Resolve(ResolutionFailure::NotInScope(path_root)))
363+
Err(ErrorKind::Resolve(ResolutionFailure::NotInScope(path_root.into())))
357364
};
358365
}
359366
let ty_res = ty_res.map_id(|_| panic!("unexpected node_id"));
@@ -450,8 +457,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
450457
} else {
451458
// We already know this isn't in ValueNS, so no need to check variant_field
452459
return Err(ErrorKind::Resolve(ResolutionFailure::NoAssocItem(
453-
ty_res,
454-
item_name.to_string(),
460+
ty_res, item_name,
455461
)));
456462
}
457463
}
@@ -491,10 +497,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
491497
if ns == Namespace::ValueNS {
492498
self.variant_field(path_str, current_item, module_id)
493499
} else {
494-
Err(ErrorKind::Resolve(ResolutionFailure::NoAssocItem(
495-
ty_res,
496-
item_name.to_string(),
497-
)))
500+
Err(ErrorKind::Resolve(ResolutionFailure::NoAssocItem(ty_res, item_name)))
498501
}
499502
})
500503
} else {
@@ -638,7 +641,7 @@ fn traits_implemented_by(cx: &DocContext<'_>, type_: DefId, module: DefId) -> Fx
638641
/// Check for resolve collisions between a trait and its derive
639642
///
640643
/// These are common and we should just resolve to the trait in that case
641-
fn is_derive_trait_collision<T>(ns: &PerNS<Result<(Res, T), ResolutionFailure>>) -> bool {
644+
fn is_derive_trait_collision<T>(ns: &PerNS<Result<(Res, T), ResolutionFailure<'_>>>) -> bool {
642645
if let PerNS {
643646
type_ns: Ok((Res::Def(DefKind::Trait, _), _)),
644647
macro_ns: Ok((Res::Def(DefKind::Macro(MacroKind::Derive), _), _)),
@@ -941,7 +944,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
941944
drop(candidates_iter);
942945
if is_derive_trait_collision(&candidates) {
943946
candidates.macro_ns =
944-
Err(ResolutionFailure::NotInScope(path_str.to_string()));
947+
Err(ResolutionFailure::NotInScope(path_str.into()));
945948
}
946949
// If we're reporting an ambiguity, don't mention the namespaces that failed
947950
let candidates =
@@ -1348,7 +1351,7 @@ fn resolution_failure(
13481351
path_str: &str,
13491352
dox: &str,
13501353
link_range: Option<Range<usize>>,
1351-
kinds: SmallVec<[ResolutionFailure; 3]>,
1354+
kinds: SmallVec<[ResolutionFailure<'_>; 3]>,
13521355
) {
13531356
report_diagnostic(
13541357
cx,
@@ -1494,10 +1497,10 @@ fn anchor_failure(
14941497
});
14951498
}
14961499

1497-
fn ambiguity_error(
1500+
fn ambiguity_error<'a>(
14981501
cx: &DocContext<'_>,
14991502
item: &Item,
1500-
path_str: &str,
1503+
path_str: &'a str,
15011504
dox: &str,
15021505
link_range: Option<Range<usize>>,
15031506
candidates: Vec<Res>,
@@ -1593,7 +1596,7 @@ fn handle_variant(
15931596
cx: &DocContext<'_>,
15941597
res: Res,
15951598
extra_fragment: &Option<String>,
1596-
) -> Result<(Res, Option<String>), ErrorKind> {
1599+
) -> Result<(Res, Option<String>), ErrorKind<'static>> {
15971600
use rustc_middle::ty::DefIdTree;
15981601

15991602
if extra_fragment.is_some() {

0 commit comments

Comments
 (0)