Skip to content

Commit fc9f13e

Browse files
committed
def_collector: Do not ICE on attributes on unnamed fields
1 parent 4576668 commit fc9f13e

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

src/librustc/hir/map/def_collector.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,13 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
170170
}
171171

172172
fn visit_variant_data(&mut self, data: &'a VariantData) {
173+
// The assumption here is that non-`cfg` macro expansion cannot change field indices.
174+
// It currently holds because only inert attributes are accepted on fields,
175+
// and every such attribute expands into a single field after it's resolved.
173176
for (index, field) in data.fields().iter().enumerate() {
174177
if field.is_placeholder {
175178
self.visit_macro_invoc(field.id);
179+
self.definitions.placeholder_field_indices.insert(field.id, index);
176180
continue;
177181
}
178182
let name = field.ident.map(|ident| ident.name)
@@ -338,12 +342,19 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
338342
}
339343
}
340344

345+
// This method is called only when we are visiting an individual field
346+
// after expanding an attribute on it.
341347
fn visit_struct_field(&mut self, sf: &'a StructField) {
342348
if sf.is_placeholder {
343349
self.visit_macro_invoc(sf.id)
344350
} else {
345-
let name = sf.ident.map(|ident| ident.name)
346-
.unwrap_or_else(|| panic!("don't know the field number in this context"));
351+
let name = sf.ident.map_or_else(
352+
|| {
353+
let expn_id = NodeId::placeholder_from_expn_id(self.expansion);
354+
sym::integer(self.definitions.placeholder_field_indices[&expn_id])
355+
},
356+
|ident| ident.name,
357+
);
347358
let def = self.create_def(sf.id,
348359
DefPathData::ValueNs(name.as_interned_str()),
349360
sf.span);

src/librustc/hir/map/definitions.rs

+2
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ pub struct Definitions {
104104
/// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId`
105105
/// we know what parent node that fragment should be attached to thanks to this table.
106106
invocation_parents: FxHashMap<ExpnId, DefIndex>,
107+
/// Indices of unnamed struct or variant fields with unresolved attributes.
108+
pub(super) placeholder_field_indices: NodeMap<usize>,
107109
}
108110

109111
/// A unique identifier that we can use to lookup a definition
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// check-pass
2+
3+
struct S(
4+
#[rustfmt::skip] u8,
5+
u16,
6+
#[rustfmt::skip] u32,
7+
);
8+
9+
fn main() {}

0 commit comments

Comments
 (0)