@@ -19,6 +19,7 @@ use rustc_span::symbol::Symbol;
19
19
use rustc_span:: DUMMY_SP ;
20
20
use smallvec:: { smallvec, SmallVec } ;
21
21
22
+ use std:: borrow:: Cow ;
22
23
use std:: cell:: Cell ;
23
24
use std:: ops:: Range ;
24
25
@@ -46,40 +47,40 @@ pub fn collect_intra_doc_links(krate: Crate, cx: &DocContext<'_>) -> Crate {
46
47
}
47
48
}
48
49
49
- enum ErrorKind {
50
- Resolve ( ResolutionFailure ) ,
50
+ enum ErrorKind < ' a > {
51
+ Resolve ( ResolutionFailure < ' a > ) ,
51
52
AnchorFailure ( AnchorFailure ) ,
52
53
}
53
54
54
55
#[ derive( Debug ) ]
55
- enum ResolutionFailure {
56
+ enum ResolutionFailure < ' a > {
56
57
/// This resolved, but with the wrong namespace.
57
58
/// `Namespace` is the expected namespace (as opposed to the actual).
58
59
WrongNamespace ( Res , Namespace ) ,
59
60
/// `String` is the base name of the path (not necessarily the whole link)
60
- NotInScope ( String ) ,
61
+ NotInScope ( Cow < ' a , str > ) ,
61
62
/// this is a primitive type without an impls (no associated methods)
62
63
/// when will this actually happen?
63
64
/// the `Res` is the primitive it resolved to
64
65
NoPrimitiveImpl ( Res , String ) ,
65
66
/// `[u8::not_found]`
66
67
/// 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 } ,
68
69
/// `[S::not_found]`
69
70
/// the `String` is the associated item that wasn't found
70
- NoAssocItem ( Res , String ) ,
71
+ NoAssocItem ( Res , Symbol ) ,
71
72
/// should not ever happen
72
73
NoParentItem ,
73
74
/// the root of this path resolved, but it was not an enum.
74
75
NotAnEnum ( Res ) ,
75
76
/// this could be an enum variant, but the last path fragment wasn't resolved.
76
77
/// the `String` is the variant that didn't exist
77
- NotAVariant ( Res , String ) ,
78
+ NotAVariant ( Res , Symbol ) ,
78
79
/// used to communicate that this should be ignored, but shouldn't be reported to the user
79
80
Dummy ,
80
81
}
81
82
82
- impl ResolutionFailure {
83
+ impl ResolutionFailure < ' a > {
83
84
fn res ( & self ) -> Option < Res > {
84
85
use ResolutionFailure :: * ;
85
86
match self {
@@ -121,10 +122,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
121
122
122
123
fn variant_field (
123
124
& self ,
124
- path_str : & str ,
125
+ path_str : & ' path str ,
125
126
current_item : & Option < String > ,
126
127
module_id : DefId ,
127
- ) -> Result < ( Res , Option < String > ) , ErrorKind > {
128
+ ) -> Result < ( Res , Option < String > ) , ErrorKind < ' path > > {
128
129
let cx = self . cx ;
129
130
130
131
let mut split = path_str. rsplitn ( 3 , "::" ) ;
@@ -134,7 +135,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
134
135
. expect ( "fold_item should ensure link is non-empty" ) ;
135
136
let variant_name =
136
137
// 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 ( ) ) ) ) ?;
138
139
// TODO: this looks very wrong, why are we requiring 3 fields?
139
140
let path = split
140
141
. next ( )
@@ -147,14 +148,18 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
147
148
f. to_owned ( )
148
149
} )
149
150
// 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
+ ) ) ) ?;
151
154
let ( _, ty_res) = cx
152
155
. enter_resolver ( |resolver| {
153
156
resolver. resolve_str_path_error ( DUMMY_SP , & path, TypeNS , module_id)
154
157
} )
155
- . map_err ( |_| ErrorKind :: Resolve ( ResolutionFailure :: NotInScope ( path. to_string ( ) ) ) ) ?;
158
+ . map_err ( |_| {
159
+ ErrorKind :: Resolve ( ResolutionFailure :: NotInScope ( path. to_string ( ) . into ( ) ) )
160
+ } ) ?;
156
161
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 ( ) ) ) ) ;
158
163
}
159
164
let ty_res = ty_res. map_id ( |_| panic ! ( "unexpected node_id" ) ) ;
160
165
match ty_res {
@@ -183,7 +188,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
183
188
} else {
184
189
Err ( ErrorKind :: Resolve ( ResolutionFailure :: NotAVariant (
185
190
ty_res,
186
- variant_field_name. to_string ( ) ,
191
+ variant_field_name,
187
192
) ) )
188
193
}
189
194
}
@@ -197,9 +202,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
197
202
/// Resolves a string as a macro.
198
203
fn macro_resolve (
199
204
& self ,
200
- path_str : & str ,
205
+ path_str : & ' a str ,
201
206
parent_id : Option < DefId > ,
202
- ) -> Result < Res , ResolutionFailure > {
207
+ ) -> Result < Res , ResolutionFailure < ' a > > {
203
208
let cx = self . cx ;
204
209
let path = ast:: Path :: from_ident ( Ident :: from_str ( path_str) ) ;
205
210
cx. enter_resolver ( |resolver| {
@@ -232,19 +237,19 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
232
237
debug ! ( "attempting to resolve item without parent module: {}" , path_str) ;
233
238
return Err ( ResolutionFailure :: NoParentItem ) ;
234
239
}
235
- return Err ( ResolutionFailure :: NotInScope ( path_str. to_string ( ) ) ) ;
240
+ return Err ( ResolutionFailure :: NotInScope ( path_str. into ( ) ) ) ;
236
241
} )
237
242
}
238
243
/// Resolves a string as a path within a particular namespace. Also returns an optional
239
244
/// URL fragment in the case of variants and methods.
240
- fn resolve (
245
+ fn resolve < ' path > (
241
246
& self ,
242
- path_str : & str ,
247
+ path_str : & ' path str ,
243
248
ns : Namespace ,
244
249
current_item : & Option < String > ,
245
250
parent_id : Option < DefId > ,
246
251
extra_fragment : & Option < String > ,
247
- ) -> Result < ( Res , Option < String > ) , ErrorKind > {
252
+ ) -> Result < ( Res , Option < String > ) , ErrorKind < ' path > > {
248
253
let cx = self . cx ;
249
254
250
255
// In case we're in a module, try to resolve the relative path.
@@ -309,11 +314,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
309
314
} )
310
315
// If there's no `::`, it's not an associated item.
311
316
// 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
+ ) ) ) ?;
313
320
314
321
if let Some ( ( path, prim) ) = is_primitive ( & path_root, ns) {
315
322
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 ( ) ) )
317
324
} ) ?;
318
325
for & impl_ in impls {
319
326
let link = cx
@@ -337,8 +344,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
337
344
}
338
345
return Err ( ErrorKind :: Resolve ( ResolutionFailure :: NoPrimitiveAssocItem {
339
346
res : prim,
340
- prim_name : path. to_string ( ) ,
341
- assoc_item : item_name. to_string ( ) ,
347
+ prim_name : path,
348
+ assoc_item : item_name,
342
349
} ) ) ;
343
350
}
344
351
@@ -347,13 +354,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
347
354
resolver. resolve_str_path_error ( DUMMY_SP , & path_root, TypeNS , module_id)
348
355
} )
349
356
. map_err ( |_| {
350
- ErrorKind :: Resolve ( ResolutionFailure :: NotInScope ( path_root. clone ( ) ) )
357
+ ErrorKind :: Resolve ( ResolutionFailure :: NotInScope ( path_root. clone ( ) . into ( ) ) )
351
358
} ) ?;
352
359
if let Res :: Err = ty_res {
353
360
return if ns == Namespace :: ValueNS {
354
361
self . variant_field ( path_str, current_item, module_id)
355
362
} else {
356
- Err ( ErrorKind :: Resolve ( ResolutionFailure :: NotInScope ( path_root) ) )
363
+ Err ( ErrorKind :: Resolve ( ResolutionFailure :: NotInScope ( path_root. into ( ) ) ) )
357
364
} ;
358
365
}
359
366
let ty_res = ty_res. map_id ( |_| panic ! ( "unexpected node_id" ) ) ;
@@ -450,8 +457,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
450
457
} else {
451
458
// We already know this isn't in ValueNS, so no need to check variant_field
452
459
return Err ( ErrorKind :: Resolve ( ResolutionFailure :: NoAssocItem (
453
- ty_res,
454
- item_name. to_string ( ) ,
460
+ ty_res, item_name,
455
461
) ) ) ;
456
462
}
457
463
}
@@ -491,10 +497,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
491
497
if ns == Namespace :: ValueNS {
492
498
self . variant_field ( path_str, current_item, module_id)
493
499
} 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) ) )
498
501
}
499
502
} )
500
503
} else {
@@ -638,7 +641,7 @@ fn traits_implemented_by(cx: &DocContext<'_>, type_: DefId, module: DefId) -> Fx
638
641
/// Check for resolve collisions between a trait and its derive
639
642
///
640
643
/// 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 {
642
645
if let PerNS {
643
646
type_ns : Ok ( ( Res :: Def ( DefKind :: Trait , _) , _) ) ,
644
647
macro_ns : Ok ( ( Res :: Def ( DefKind :: Macro ( MacroKind :: Derive ) , _) , _) ) ,
@@ -941,7 +944,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
941
944
drop ( candidates_iter) ;
942
945
if is_derive_trait_collision ( & candidates) {
943
946
candidates. macro_ns =
944
- Err ( ResolutionFailure :: NotInScope ( path_str. to_string ( ) ) ) ;
947
+ Err ( ResolutionFailure :: NotInScope ( path_str. into ( ) ) ) ;
945
948
}
946
949
// If we're reporting an ambiguity, don't mention the namespaces that failed
947
950
let candidates =
@@ -1348,7 +1351,7 @@ fn resolution_failure(
1348
1351
path_str : & str ,
1349
1352
dox : & str ,
1350
1353
link_range : Option < Range < usize > > ,
1351
- kinds : SmallVec < [ ResolutionFailure ; 3 ] > ,
1354
+ kinds : SmallVec < [ ResolutionFailure < ' _ > ; 3 ] > ,
1352
1355
) {
1353
1356
report_diagnostic (
1354
1357
cx,
@@ -1494,10 +1497,10 @@ fn anchor_failure(
1494
1497
} ) ;
1495
1498
}
1496
1499
1497
- fn ambiguity_error (
1500
+ fn ambiguity_error < ' a > (
1498
1501
cx : & DocContext < ' _ > ,
1499
1502
item : & Item ,
1500
- path_str : & str ,
1503
+ path_str : & ' a str ,
1501
1504
dox : & str ,
1502
1505
link_range : Option < Range < usize > > ,
1503
1506
candidates : Vec < Res > ,
@@ -1593,7 +1596,7 @@ fn handle_variant(
1593
1596
cx : & DocContext < ' _ > ,
1594
1597
res : Res ,
1595
1598
extra_fragment : & Option < String > ,
1596
- ) -> Result < ( Res , Option < String > ) , ErrorKind > {
1599
+ ) -> Result < ( Res , Option < String > ) , ErrorKind < ' static > > {
1597
1600
use rustc_middle:: ty:: DefIdTree ;
1598
1601
1599
1602
if extra_fragment. is_some ( ) {
0 commit comments