Skip to content

Commit 553a64f

Browse files
authored
Rollup merge of rust-lang#128223 - nnethercote:refactor-collect_tokens, r=petrochenkov
Refactor complex conditions in `collect_tokens_trailing_token` More readability improvements for this complicated function. r? ````@petrochenkov````
2 parents 7195b80 + e631b1e commit 553a64f

File tree

2 files changed

+43
-45
lines changed

2 files changed

+43
-45
lines changed

compiler/rustc_parse/src/parser/attr.rs

-11
Original file line numberDiff line numberDiff line change
@@ -457,14 +457,3 @@ impl<'a> Parser<'a> {
457457
Err(self.dcx().create_err(err))
458458
}
459459
}
460-
461-
/// The attributes are complete if all attributes are either a doc comment or a
462-
/// builtin attribute other than `cfg_attr`.
463-
pub fn is_complete(attrs: &[ast::Attribute]) -> bool {
464-
attrs.iter().all(|attr| {
465-
attr.is_doc_comment()
466-
|| attr.ident().is_some_and(|ident| {
467-
ident.name != sym::cfg_attr && rustc_feature::is_builtin_attr_name(ident.name)
468-
})
469-
})
470-
}

compiler/rustc_parse/src/parser/attr_wrapper.rs

+43-34
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,6 @@ impl AttrWrapper {
6060
pub fn is_empty(&self) -> bool {
6161
self.attrs.is_empty()
6262
}
63-
64-
pub fn is_complete(&self) -> bool {
65-
crate::parser::attr::is_complete(&self.attrs)
66-
}
6763
}
6864

6965
/// Returns `true` if `attrs` contains a `cfg` or `cfg_attr` attribute
@@ -199,20 +195,20 @@ impl<'a> Parser<'a> {
199195
force_collect: ForceCollect,
200196
f: impl FnOnce(&mut Self, ast::AttrVec) -> PResult<'a, (R, bool)>,
201197
) -> PResult<'a, R> {
202-
// Skip collection when nothing could observe the collected tokens, i.e.
203-
// all of the following conditions hold.
204-
// - We are not force collecting tokens (because force collection
205-
// requires tokens by definition).
206-
if matches!(force_collect, ForceCollect::No)
207-
// - None of our outer attributes require tokens.
208-
&& attrs.is_complete()
209-
// - Our target doesn't support custom inner attributes (custom
198+
// We must collect if anything could observe the collected tokens, i.e.
199+
// if any of the following conditions hold.
200+
// - We are force collecting tokens (because force collection requires
201+
// tokens by definition).
202+
let needs_collection = matches!(force_collect, ForceCollect::Yes)
203+
// - Any of our outer attributes require tokens.
204+
|| needs_tokens(&attrs.attrs)
205+
// - Our target supports custom inner attributes (custom
210206
// inner attribute invocation might require token capturing).
211-
&& !R::SUPPORTS_CUSTOM_INNER_ATTRS
212-
// - We are not in `capture_cfg` mode (which requires tokens if
207+
|| R::SUPPORTS_CUSTOM_INNER_ATTRS
208+
// - We are in `capture_cfg` mode (which requires tokens if
213209
// the parsed node has `#[cfg]` or `#[cfg_attr]` attributes).
214-
&& !self.capture_cfg
215-
{
210+
|| self.capture_cfg;
211+
if !needs_collection {
216212
return Ok(f(self, attrs.attrs)?.0);
217213
}
218214

@@ -250,28 +246,28 @@ impl<'a> Parser<'a> {
250246
return Ok(ret);
251247
}
252248

253-
// This is similar to the "skip collection" check at the start of this
254-
// function, but now that we've parsed an AST node we have more
249+
// This is similar to the `needs_collection` check at the start of this
250+
// function, but now that we've parsed an AST node we have complete
255251
// information available. (If we return early here that means the
256252
// setup, such as cloning the token cursor, was unnecessary. That's
257253
// hard to avoid.)
258254
//
259-
// Skip collection when nothing could observe the collected tokens, i.e.
260-
// all of the following conditions hold.
261-
// - We are not force collecting tokens.
262-
if matches!(force_collect, ForceCollect::No)
263-
// - None of our outer *or* inner attributes require tokens.
264-
// (`attrs` was just outer attributes, but `ret.attrs()` is outer
265-
// and inner attributes. That makes this check more precise than
266-
// `attrs.is_complete()` at the start of the function, and we can
267-
// skip the subsequent check on `R::SUPPORTS_CUSTOM_INNER_ATTRS`.
268-
&& crate::parser::attr::is_complete(ret.attrs())
269-
// - We are not in `capture_cfg` mode, or we are but there are no
270-
// `#[cfg]` or `#[cfg_attr]` attributes. (During normal
271-
// non-`capture_cfg` parsing, we don't need any special capturing
272-
// for those attributes, because they're builtin.)
273-
&& (!self.capture_cfg || !has_cfg_or_cfg_attr(ret.attrs()))
274-
{
255+
// We must collect if anything could observe the collected tokens, i.e.
256+
// if any of the following conditions hold.
257+
// - We are force collecting tokens.
258+
let needs_collection = matches!(force_collect, ForceCollect::Yes)
259+
// - Any of our outer *or* inner attributes require tokens.
260+
// (`attr.attrs` was just outer attributes, but `ret.attrs()` is
261+
// outer and inner attributes. So this check is more precise than
262+
// the earlier `needs_tokens` check, and we don't need to
263+
// check `R::SUPPORTS_CUSTOM_INNER_ATTRS`.)
264+
|| needs_tokens(ret.attrs())
265+
// - We are in `capture_cfg` mode and there are `#[cfg]` or
266+
// `#[cfg_attr]` attributes. (During normal non-`capture_cfg`
267+
// parsing, we don't need any special capturing for those
268+
// attributes, because they're builtin.)
269+
|| (self.capture_cfg && has_cfg_or_cfg_attr(ret.attrs()));
270+
if !needs_collection {
275271
return Ok(ret);
276272
}
277273

@@ -461,6 +457,19 @@ fn make_attr_token_stream(
461457
AttrTokenStream::new(stack_top.inner)
462458
}
463459

460+
/// Tokens are needed if:
461+
/// - any non-single-segment attributes (other than doc comments) are present; or
462+
/// - any `cfg_attr` attributes are present;
463+
/// - any single-segment, non-builtin attributes are present.
464+
fn needs_tokens(attrs: &[ast::Attribute]) -> bool {
465+
attrs.iter().any(|attr| match attr.ident() {
466+
None => !attr.is_doc_comment(),
467+
Some(ident) => {
468+
ident.name == sym::cfg_attr || !rustc_feature::is_builtin_attr_name(ident.name)
469+
}
470+
})
471+
}
472+
464473
// Some types are used a lot. Make sure they don't unintentionally get bigger.
465474
#[cfg(target_pointer_width = "64")]
466475
mod size_asserts {

0 commit comments

Comments
 (0)