@@ -10,7 +10,10 @@ use rustc_errors::PResult;
10
10
use rustc_session:: parse:: ParseSess ;
11
11
use rustc_span:: { sym, Span , DUMMY_SP } ;
12
12
13
- use super :: { Capturing , FlatToken , ForceCollect , Parser , ReplaceRange , TokenCursor } ;
13
+ use super :: {
14
+ Capturing , FlatToken , ForceCollect , NodeRange , NodeReplacement , Parser , ParserRange ,
15
+ TokenCursor ,
16
+ } ;
14
17
15
18
/// A wrapper type to ensure that the parser handles outer attributes correctly.
16
19
/// When we parse outer attributes, we need to ensure that we capture tokens
@@ -28,8 +31,8 @@ use super::{Capturing, FlatToken, ForceCollect, Parser, ReplaceRange, TokenCurso
28
31
#[ derive( Debug , Clone ) ]
29
32
pub struct AttrWrapper {
30
33
attrs : AttrVec ,
31
- // The start of the outer attributes in the token cursor .
32
- // This allows us to create a `ReplaceRange ` for the entire attribute
34
+ // The start of the outer attributes in the parser's token stream .
35
+ // This lets us create a `NodeReplacement ` for the entire attribute
33
36
// target, including outer attributes.
34
37
start_pos : u32 ,
35
38
}
@@ -88,7 +91,7 @@ struct LazyAttrTokenStreamImpl {
88
91
cursor_snapshot : TokenCursor ,
89
92
num_calls : u32 ,
90
93
break_last_token : bool ,
91
- replace_ranges : Box < [ ReplaceRange ] > ,
94
+ node_replacements : Box < [ NodeReplacement ] > ,
92
95
}
93
96
94
97
impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
@@ -103,21 +106,24 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
103
106
. chain ( iter:: repeat_with ( || FlatToken :: Token ( cursor_snapshot. next ( ) ) ) )
104
107
. take ( self . num_calls as usize ) ;
105
108
106
- if self . replace_ranges . is_empty ( ) {
109
+ if self . node_replacements . is_empty ( ) {
107
110
make_attr_token_stream ( tokens, self . break_last_token )
108
111
} else {
109
112
let mut tokens: Vec < _ > = tokens. collect ( ) ;
110
- let mut replace_ranges = self . replace_ranges . to_vec ( ) ;
111
- replace_ranges . sort_by_key ( |( range, _) | range. start ) ;
113
+ let mut node_replacements = self . node_replacements . to_vec ( ) ;
114
+ node_replacements . sort_by_key ( |( range, _) | range. 0 . start ) ;
112
115
113
116
#[ cfg( debug_assertions) ]
114
- for [ ( range, tokens) , ( next_range, next_tokens) ] in replace_ranges. array_windows ( ) {
117
+ for [ ( node_range, tokens) , ( next_node_range, next_tokens) ] in
118
+ node_replacements. array_windows ( )
119
+ {
115
120
assert ! (
116
- range. end <= next_range. start || range. end >= next_range. end,
117
- "Replace ranges should either be disjoint or nested: ({:?}, {:?}) ({:?}, {:?})" ,
118
- range,
121
+ node_range. 0 . end <= next_node_range. 0 . start
122
+ || node_range. 0 . end >= next_node_range. 0 . end,
123
+ "Node ranges should be disjoint or nested: ({:?}, {:?}) ({:?}, {:?})" ,
124
+ node_range,
119
125
tokens,
120
- next_range ,
126
+ next_node_range ,
121
127
next_tokens,
122
128
) ;
123
129
}
@@ -135,20 +141,23 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl {
135
141
// start position, we ensure that any (outer) replace range which
136
142
// encloses another (inner) replace range will fully overwrite the
137
143
// inner range's replacement.
138
- for ( range, target) in replace_ranges. into_iter ( ) . rev ( ) {
139
- assert ! ( !range. is_empty( ) , "Cannot replace an empty range: {range:?}" ) ;
144
+ for ( node_range, target) in node_replacements. into_iter ( ) . rev ( ) {
145
+ assert ! (
146
+ !node_range. 0 . is_empty( ) ,
147
+ "Cannot replace an empty node range: {:?}" ,
148
+ node_range. 0
149
+ ) ;
140
150
141
151
// Replace the tokens in range with zero or one `FlatToken::AttrsTarget`s, plus
142
152
// enough `FlatToken::Empty`s to fill up the rest of the range. This keeps the
143
153
// total length of `tokens` constant throughout the replacement process, allowing
144
- // us to use all of the `ReplaceRanges` entries without adjusting indices.
154
+ // us to do all replacements without adjusting indices.
145
155
let target_len = target. is_some ( ) as usize ;
146
156
tokens. splice (
147
- ( range. start as usize ) ..( range. end as usize ) ,
148
- target
149
- . into_iter ( )
150
- . map ( |target| FlatToken :: AttrsTarget ( target) )
151
- . chain ( iter:: repeat ( FlatToken :: Empty ) . take ( range. len ( ) - target_len) ) ,
157
+ ( node_range. 0 . start as usize ) ..( node_range. 0 . end as usize ) ,
158
+ target. into_iter ( ) . map ( |target| FlatToken :: AttrsTarget ( target) ) . chain (
159
+ iter:: repeat ( FlatToken :: Empty ) . take ( node_range. 0 . len ( ) - target_len) ,
160
+ ) ,
152
161
) ;
153
162
}
154
163
make_attr_token_stream ( tokens. into_iter ( ) , self . break_last_token )
@@ -215,7 +224,7 @@ impl<'a> Parser<'a> {
215
224
let cursor_snapshot = self . token_cursor . clone ( ) ;
216
225
let start_pos = self . num_bump_calls ;
217
226
let has_outer_attrs = !attrs. attrs . is_empty ( ) ;
218
- let replace_ranges_start = self . capture_state . replace_ranges . len ( ) ;
227
+ let parser_replacements_start = self . capture_state . parser_replacements . len ( ) ;
219
228
220
229
// We set and restore `Capturing::Yes` on either side of the call to
221
230
// `f`, so we can distinguish the outermost call to
@@ -270,7 +279,7 @@ impl<'a> Parser<'a> {
270
279
return Ok ( ret) ;
271
280
}
272
281
273
- let replace_ranges_end = self . capture_state . replace_ranges . len ( ) ;
282
+ let parser_replacements_end = self . capture_state . parser_replacements . len ( ) ;
274
283
275
284
assert ! (
276
285
!( self . break_last_token && capture_trailing) ,
@@ -287,15 +296,16 @@ impl<'a> Parser<'a> {
287
296
288
297
let num_calls = end_pos - start_pos;
289
298
290
- // Take the captured ranges for any inner attributes that we parsed in
291
- // `Parser::parse_inner_attributes`, and pair them in a `ReplaceRange`
292
- // with `None`, which means the relevant tokens will be removed. (More
293
- // details below.)
294
- let mut inner_attr_replace_ranges = Vec :: new ( ) ;
299
+ // Take the captured `ParserRange`s for any inner attributes that we parsed in
300
+ // `Parser::parse_inner_attributes`, and pair them in a `ParserReplacement` with `None`,
301
+ // which means the relevant tokens will be removed. (More details below.)
302
+ let mut inner_attr_parser_replacements = Vec :: new ( ) ;
295
303
for attr in ret. attrs ( ) {
296
304
if attr. style == ast:: AttrStyle :: Inner {
297
- if let Some ( attr_range) = self . capture_state . inner_attr_ranges . remove ( & attr. id ) {
298
- inner_attr_replace_ranges. push ( ( attr_range, None ) ) ;
305
+ if let Some ( inner_attr_parser_range) =
306
+ self . capture_state . inner_attr_parser_ranges . remove ( & attr. id )
307
+ {
308
+ inner_attr_parser_replacements. push ( ( inner_attr_parser_range, None ) ) ;
299
309
} else {
300
310
self . dcx ( ) . span_delayed_bug ( attr. span , "Missing token range for attribute" ) ;
301
311
}
@@ -304,37 +314,41 @@ impl<'a> Parser<'a> {
304
314
305
315
// This is hot enough for `deep-vector` that checking the conditions for an empty iterator
306
316
// is measurably faster than actually executing the iterator.
307
- let replace_ranges: Box < [ ReplaceRange ] > =
308
- if replace_ranges_start == replace_ranges_end && inner_attr_replace_ranges. is_empty ( ) {
309
- Box :: new ( [ ] )
310
- } else {
311
- // Grab any replace ranges that occur *inside* the current AST node. We will
312
- // perform the actual replacement only when we convert the `LazyAttrTokenStream` to
313
- // an `AttrTokenStream`.
314
- self . capture_state . replace_ranges [ replace_ranges_start..replace_ranges_end]
315
- . iter ( )
316
- . cloned ( )
317
- . chain ( inner_attr_replace_ranges. iter ( ) . cloned ( ) )
318
- . map ( |( range, data) | ( ( range. start - start_pos) ..( range. end - start_pos) , data) )
319
- . collect ( )
320
- } ;
317
+ let node_replacements: Box < [ _ ] > = if parser_replacements_start == parser_replacements_end
318
+ && inner_attr_parser_replacements. is_empty ( )
319
+ {
320
+ Box :: new ( [ ] )
321
+ } else {
322
+ // Grab any replace ranges that occur *inside* the current AST node. Convert them
323
+ // from `ParserRange` form to `NodeRange` form. We will perform the actual
324
+ // replacement only when we convert the `LazyAttrTokenStream` to an
325
+ // `AttrTokenStream`.
326
+ self . capture_state . parser_replacements
327
+ [ parser_replacements_start..parser_replacements_end]
328
+ . iter ( )
329
+ . cloned ( )
330
+ . chain ( inner_attr_parser_replacements. iter ( ) . cloned ( ) )
331
+ . map ( |( parser_range, data) | ( NodeRange :: new ( parser_range, start_pos) , data) )
332
+ . collect ( )
333
+ } ;
321
334
322
335
// What is the status here when parsing the example code at the top of this method?
323
336
//
324
337
// When parsing `g`:
325
338
// - `start_pos..end_pos` is `12..33` (`fn g { ... }`, excluding the outer attr).
326
- // - `inner_attr_replace_ranges ` has one entry (`5..15`, when counting from `fn `), to
339
+ // - `inner_attr_parser_replacements ` has one entry (`ParserRange(17..27) `), to
327
340
// delete the inner attr's tokens.
328
- // - This entry is put into the lazy tokens for `g`, i.e. deleting the inner attr from
329
- // those tokens (if they get evaluated).
341
+ // - This entry is converted to `NodeRange(5..15)` (relative to the `fn`) and put into
342
+ // the lazy tokens for `g`, i.e. deleting the inner attr from those tokens (if they get
343
+ // evaluated).
330
344
// - Those lazy tokens are also put into an `AttrsTarget` that is appended to `self`'s
331
345
// replace ranges at the bottom of this function, for processing when parsing `m`.
332
- // - `replace_ranges_start..replace_ranges_end ` is empty.
346
+ // - `parser_replacements_start..parser_replacements_end ` is empty.
333
347
//
334
348
// When parsing `m`:
335
349
// - `start_pos..end_pos` is `0..34` (`mod m`, excluding the `#[cfg_eval]` attribute).
336
- // - `inner_attr_replace_ranges ` is empty.
337
- // - `replace_range_start..replace_ranges_end ` has one entry.
350
+ // - `inner_attr_parser_replacements ` is empty.
351
+ // - `parser_replacements_start..parser_replacements_end ` has one entry.
338
352
// - One `AttrsTarget` (added below when parsing `g`) to replace all of `g` (`3..33`,
339
353
// including its outer attribute), with:
340
354
// - `attrs`: includes the outer and the inner attr.
@@ -345,7 +359,7 @@ impl<'a> Parser<'a> {
345
359
num_calls,
346
360
cursor_snapshot,
347
361
break_last_token : self . break_last_token ,
348
- replace_ranges ,
362
+ node_replacements ,
349
363
} ) ;
350
364
351
365
// If we support tokens and don't already have them, store the newly captured tokens.
@@ -366,7 +380,7 @@ impl<'a> Parser<'a> {
366
380
// What is the status here when parsing the example code at the top of this method?
367
381
//
368
382
// When parsing `g`, we add one entry:
369
- // - The `start_pos..end_pos` (` 3..33`) entry has a new `AttrsTarget` with:
383
+ // - The pushed entry (`ParserRange( 3..33)`) has a new `AttrsTarget` with:
370
384
// - `attrs`: includes the outer and the inner attr.
371
385
// - `tokens`: lazy tokens for `g` (with its inner attr deleted).
372
386
//
@@ -377,12 +391,14 @@ impl<'a> Parser<'a> {
377
391
// cfg-expand this AST node.
378
392
let start_pos = if has_outer_attrs { attrs. start_pos } else { start_pos } ;
379
393
let target = AttrsTarget { attrs : ret. attrs ( ) . iter ( ) . cloned ( ) . collect ( ) , tokens } ;
380
- self . capture_state . replace_ranges . push ( ( start_pos..end_pos, Some ( target) ) ) ;
394
+ self . capture_state
395
+ . parser_replacements
396
+ . push ( ( ParserRange ( start_pos..end_pos) , Some ( target) ) ) ;
381
397
} else if matches ! ( self . capture_state. capturing, Capturing :: No ) {
382
398
// Only clear the ranges once we've finished capturing entirely, i.e. we've finished
383
399
// the outermost call to this method.
384
- self . capture_state . replace_ranges . clear ( ) ;
385
- self . capture_state . inner_attr_ranges . clear ( ) ;
400
+ self . capture_state . parser_replacements . clear ( ) ;
401
+ self . capture_state . inner_attr_parser_ranges . clear ( ) ;
386
402
}
387
403
Ok ( ret)
388
404
}
0 commit comments