Skip to content

Commit 952c5ba

Browse files
committed
Fix ICE from cfg_attr_trace by storing span
1 parent 2972b5e commit 952c5ba

8 files changed

Lines changed: 37 additions & 10 deletions

File tree

compiler/rustc_attr_parsing/src/early_parsed.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ pub(crate) struct EarlyParsedState {
1818
cfg_trace: ThinVec<(CfgEntry, Span)>,
1919

2020
/// Attribute state for `#[cfg_attr]` trace attributes
21-
/// The arguments of these attributes is no longer relevant for any later passes, only their presence.
22-
/// So we discard the arguments here.
23-
cfg_attr_trace: bool,
21+
/// The arguments of these attributes are no longer relevant for later passes,
22+
/// but we still keep a source span so downstream diagnostics can tell that the
23+
/// original expression had a prefix attribute.
24+
cfg_attr_trace: Option<Span>,
2425
}
2526

2627
impl EarlyParsedState {
@@ -37,7 +38,7 @@ impl EarlyParsedState {
3738
self.cfg_trace.push((cfg, attr_span));
3839
}
3940
EarlyParsedAttribute::CfgAttrTrace => {
40-
self.cfg_attr_trace = true;
41+
self.cfg_attr_trace.get_or_insert(attr_span);
4142
}
4243
}
4344
}
@@ -46,8 +47,8 @@ impl EarlyParsedState {
4647
if !self.cfg_trace.is_empty() {
4748
attributes.push(Attribute::Parsed(AttributeKind::CfgTrace(self.cfg_trace)));
4849
}
49-
if self.cfg_attr_trace {
50-
attributes.push(Attribute::Parsed(AttributeKind::CfgAttrTrace));
50+
if let Some(span) = self.cfg_attr_trace {
51+
attributes.push(Attribute::Parsed(AttributeKind::CfgAttrTrace(span)));
5152
}
5253
}
5354
}

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,7 @@ pub enum AttributeKind {
10951095
AutomaticallyDerived(Span),
10961096

10971097
/// Represents the trace attribute of `#[cfg_attr]`
1098-
CfgAttrTrace,
1098+
CfgAttrTrace(Span),
10991099

11001100
/// Represents the trace attribute of `#[cfg]`
11011101
CfgTrace(ThinVec<(CfgEntry, Span)>),

compiler/rustc_hir/src/attrs/encode_cross_crate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ impl AttributeKind {
2121
AllowInternalUnsafe(..) => Yes,
2222
AllowInternalUnstable(..) => Yes,
2323
AutomaticallyDerived(..) => Yes,
24-
CfgAttrTrace => Yes,
24+
CfgAttrTrace(..) => Yes,
2525
CfgTrace(..) => Yes,
2626
CfiEncoding { .. } => Yes,
2727
Cold(..) => No,

compiler/rustc_hir/src/hir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,6 +1308,7 @@ impl Attribute {
13081308
pub fn has_span_without_desugaring_kind(&self) -> bool {
13091309
let span = match self {
13101310
Attribute::Unparsed(attr) => attr.span,
1311+
Attribute::Parsed(AttributeKind::CfgAttrTrace(span)) => *span,
13111312
Attribute::Parsed(AttributeKind::Deprecated { span, .. }) => *span,
13121313
Attribute::Parsed(AttributeKind::LintAttributes(sub_attrs)) => {
13131314
return sub_attrs.iter().any(|attr| attr.attr_span.desugaring_kind().is_none());

compiler/rustc_passes/src/check_attr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
226226
// tidy-alphabetical-start
227227
AttributeKind::RustcAllowIncoherentImpl(..)
228228
| AttributeKind::AutomaticallyDerived(..)
229-
| AttributeKind::CfgAttrTrace
229+
| AttributeKind::CfgAttrTrace(..)
230230
| AttributeKind::CfgTrace(..)
231231
| AttributeKind::CfiEncoding { .. }
232232
| AttributeKind::Cold(..)

src/tools/clippy/clippy_lints/src/incompatible_msrv.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,5 +269,5 @@ impl<'tcx> LateLintPass<'tcx> for IncompatibleMsrv {
269269
fn is_under_cfg_attribute(cx: &LateContext<'_>, hir_id: HirId) -> bool {
270270
cx.tcx
271271
.hir_parent_id_iter(hir_id)
272-
.any(|id| find_attr!(cx.tcx, id, CfgTrace(..) | CfgAttrTrace))
272+
.any(|id| find_attr!(cx.tcx, id, CfgTrace(..) | CfgAttrTrace(..)))
273273
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fn main() {
2+
let _x = 30;
3+
#[cfg_attr(, (cc))] //~ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `,`
4+
_x //~ ERROR mismatched types
5+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `,`
2+
--> $DIR/cfg-attr-parsed-span-issue-154801.rs:3:16
3+
|
4+
LL | #[cfg_attr(, (cc))]
5+
| -----------^------- help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]`
6+
|
7+
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
8+
9+
error[E0308]: mismatched types
10+
--> $DIR/cfg-attr-parsed-span-issue-154801.rs:4:5
11+
|
12+
LL | fn main() {
13+
| - expected `()` because of default return type
14+
...
15+
LL | _x
16+
| ^^ expected `()`, found integer
17+
18+
error: aborting due to 2 previous errors
19+
20+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)