Auto merge of #138515 - petrochenkov:cfgtrace, r= · rust-lang/rust@c78b933 (original) (raw)

1

1

`//! Conditional compilation stripping.

`

2

2

``

``

3

`+

use std::iter;

`

``

4

+

3

5

`use rustc_ast::ptr::P;

`

4

6

`use rustc_ast::token::{Delimiter, Token, TokenKind};

`

5

7

`use rustc_ast::tokenstream::{

`

6

8

`AttrTokenStream, AttrTokenTree, LazyAttrTokenStream, Spacing, TokenTree,

`

7

9

`};

`

8

10

`use rustc_ast::{

`

9

``

`-

self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem, MetaItemInner, NodeId,

`

``

11

`+

self as ast, AttrKind, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem, MetaItemInner,

`

``

12

`+

NodeId, NormalAttr,

`

10

13

`};

`

11

14

`use rustc_attr_parsing as attr;

`

12

15

`use rustc_data_structures::flat_map_in_place::FlatMapInPlace;

`

`@@ -275,10 +278,23 @@ impl<'a> StripUnconfigured<'a> {

`

275

278

`pub(crate) fn expand_cfg_attr(&self, cfg_attr: &Attribute, recursive: bool) -> Vec {

`

276

279

` validate_attr::check_attribute_safety(&self.sess.psess, AttributeSafety::Normal, &cfg_attr);

`

277

280

``

``

281

`` +

// A trace attribute left in AST in place of the original cfg_attr attribute.

``

``

282

`+

// It can later be used by lints or other diagnostics.

`

``

283

`+

let mut trace_attr = cfg_attr.clone();

`

``

284

`+

match &mut trace_attr.kind {

`

``

285

`+

AttrKind::Normal(normal) => {

`

``

286

`+

let NormalAttr { item, tokens } = &mut **normal;

`

``

287

`+

item.path.segments[0].ident.name = sym::cfg_attr_trace;

`

``

288

`+

// This makes the trace attributes unobservable to token-based proc macros.

`

``

289

`+

*tokens = Some(LazyAttrTokenStream::new(AttrTokenStream::default()));

`

``

290

`+

}

`

``

291

`+

AttrKind::DocComment(..) => unreachable!(),

`

``

292

`+

}

`

``

293

+

278

294

`let Some((cfg_predicate, expanded_attrs)) =

`

279

295

` rustc_parse::parse_cfg_attr(cfg_attr, &self.sess.psess)

`

280

296

`else {

`

281

``

`-

return vec![];

`

``

297

`+

return vec![trace_attr];

`

282

298

`};

`

283

299

``

284

300

`// Lint on zero attributes in source.

`

`@@ -292,22 +308,21 @@ impl<'a> StripUnconfigured<'a> {

`

292

308

`}

`

293

309

``

294

310

`if !attr::cfg_matches(&cfg_predicate, &self.sess, self.lint_node_id, self.features) {

`

295

``

`-

return vec![];

`

``

311

`+

return vec![trace_attr];

`

296

312

`}

`

297

313

``

298

314

`if recursive {

`

299

315

`` // We call process_cfg_attr recursively in case there's a

``

300

316

`` // cfg_attr inside of another cfg_attr. E.g.

``

301

317

`` // #[cfg_attr(false, cfg_attr(true, some_attr))].

``

302

``

`-

expanded_attrs

`

``

318

`+

let expanded_attrs = expanded_attrs

`

303

319

`.into_iter()

`

304

``

`-

.flat_map(|item| self.process_cfg_attr(&self.expand_cfg_attr_item(cfg_attr, item)))

`

305

``

`-

.collect()

`

``

320

`+

.flat_map(|item| self.process_cfg_attr(&self.expand_cfg_attr_item(cfg_attr, item)));

`

``

321

`+

iter::once(trace_attr).chain(expanded_attrs).collect()

`

306

322

`} else {

`

307

``

`-

expanded_attrs

`

308

``

`-

.into_iter()

`

309

``

`-

.map(|item| self.expand_cfg_attr_item(cfg_attr, item))

`

310

``

`-

.collect()

`

``

323

`+

let expanded_attrs =

`

``

324

`+

expanded_attrs.into_iter().map(|item| self.expand_cfg_attr_item(cfg_attr, item));

`

``

325

`+

iter::once(trace_attr).chain(expanded_attrs).collect()

`

311

326

`}

`

312

327

`}

`

313

328

``