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