Skip to content

Commit 457a23f

Browse files
authored
Rollup merge of rust-lang#63468 - c410-f3r:attrs, r=petrochenkov
Resolve attributes in several places Resolve attributes for Arm, Field, FieldPat, GenericParam, Param, StructField and Variant. This PR is based on @petrochenkov work located at petrochenkov@83fdb8d.
2 parents 824383d + 63a5f39 commit 457a23f

37 files changed

+1097
-489
lines changed

src/librustc/hir/map/def_collector.rs

+57-1
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
155155
}
156156

157157
fn visit_variant(&mut self, v: &'a Variant) {
158+
if v.is_placeholder {
159+
return self.visit_macro_invoc(v.id);
160+
}
158161
let def = self.create_def(v.id,
159162
DefPathData::TypeNs(v.ident.as_interned_str()),
160163
v.span);
@@ -168,16 +171,24 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
168171

169172
fn visit_variant_data(&mut self, data: &'a VariantData) {
170173
for (index, field) in data.fields().iter().enumerate() {
174+
if field.is_placeholder {
175+
self.visit_macro_invoc(field.id);
176+
continue;
177+
}
171178
let name = field.ident.map(|ident| ident.name)
172179
.unwrap_or_else(|| sym::integer(index));
173180
let def = self.create_def(field.id,
174181
DefPathData::ValueNs(name.as_interned_str()),
175182
field.span);
176-
self.with_parent(def, |this| this.visit_struct_field(field));
183+
self.with_parent(def, |this| visit::walk_struct_field(this, field));
177184
}
178185
}
179186

180187
fn visit_generic_param(&mut self, param: &'a GenericParam) {
188+
if param.is_placeholder {
189+
self.visit_macro_invoc(param.id);
190+
return;
191+
}
181192
let name = param.ident.as_interned_str();
182193
let def_path_data = match param.kind {
183194
GenericParamKind::Lifetime { .. } => DefPathData::LifetimeNs(name),
@@ -294,4 +305,49 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
294305
}
295306
}
296307
}
308+
309+
fn visit_arm(&mut self, arm: &'a Arm) {
310+
if arm.is_placeholder {
311+
self.visit_macro_invoc(arm.id)
312+
} else {
313+
visit::walk_arm(self, arm)
314+
}
315+
}
316+
317+
fn visit_field(&mut self, f: &'a Field) {
318+
if f.is_placeholder {
319+
self.visit_macro_invoc(f.id)
320+
} else {
321+
visit::walk_field(self, f)
322+
}
323+
}
324+
325+
fn visit_field_pattern(&mut self, fp: &'a FieldPat) {
326+
if fp.is_placeholder {
327+
self.visit_macro_invoc(fp.id)
328+
} else {
329+
visit::walk_field_pattern(self, fp)
330+
}
331+
}
332+
333+
fn visit_param(&mut self, p: &'a Param) {
334+
if p.is_placeholder {
335+
self.visit_macro_invoc(p.id)
336+
} else {
337+
visit::walk_param(self, p)
338+
}
339+
}
340+
341+
fn visit_struct_field(&mut self, sf: &'a StructField) {
342+
if sf.is_placeholder {
343+
self.visit_macro_invoc(sf.id)
344+
} else {
345+
let name = sf.ident.map(|ident| ident.name)
346+
.unwrap_or_else(|| panic!("don't know the field number in this context"));
347+
let def = self.create_def(sf.id,
348+
DefPathData::ValueNs(name.as_interned_str()),
349+
sf.span);
350+
self.with_parent(def, |this| visit::walk_struct_field(this, sf));
351+
}
352+
}
297353
}

src/librustc_resolve/build_reduced_graph.rs

+94-45
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use syntax::ast::{Name, Ident};
3131
use syntax::attr;
3232

3333
use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId};
34-
use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind, Variant};
34+
use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind};
3535
use syntax::ext::base::{MacroKind, SyntaxExtension};
3636
use syntax::ext::expand::AstFragment;
3737
use syntax::ext::hygiene::ExpnId;
@@ -580,7 +580,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
580580
}
581581

582582
/// Constructs the reduced graph for one item.
583-
fn build_reduced_graph_for_item(&mut self, item: &Item) {
583+
fn build_reduced_graph_for_item(&mut self, item: &'b Item) {
584584
let parent_scope = &self.parent_scope;
585585
let parent = parent_scope.module;
586586
let expansion = parent_scope.expansion;
@@ -716,23 +716,17 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
716716
self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
717717
}
718718

719-
ItemKind::Enum(ref enum_definition, _) => {
720-
let module_kind = ModuleKind::Def(
721-
DefKind::Enum,
722-
self.r.definitions.local_def_id(item.id),
723-
ident.name,
724-
);
719+
ItemKind::Enum(_, _) => {
720+
let def_id = self.r.definitions.local_def_id(item.id);
721+
self.r.variant_vis.insert(def_id, vis);
722+
let module_kind = ModuleKind::Def(DefKind::Enum, def_id, ident.name);
725723
let module = self.r.new_module(parent,
726724
module_kind,
727725
parent.normal_ancestor_id,
728726
expansion,
729727
item.span);
730728
self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
731729
self.parent_scope.module = module;
732-
733-
for variant in &(*enum_definition).variants {
734-
self.build_reduced_graph_for_variant(variant, vis);
735-
}
736730
}
737731

738732
ItemKind::TraitAlias(..) => {
@@ -817,38 +811,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
817811
}
818812
}
819813

820-
// Constructs the reduced graph for one variant. Variants exist in the
821-
// type and value namespaces.
822-
fn build_reduced_graph_for_variant(&mut self, variant: &Variant, vis: ty::Visibility) {
823-
let parent = self.parent_scope.module;
824-
let expn_id = self.parent_scope.expansion;
825-
let ident = variant.ident;
826-
827-
// Define a name in the type namespace.
828-
let def_id = self.r.definitions.local_def_id(variant.id);
829-
let res = Res::Def(DefKind::Variant, def_id);
830-
self.r.define(parent, ident, TypeNS, (res, vis, variant.span, expn_id));
831-
832-
// If the variant is marked as non_exhaustive then lower the visibility to within the
833-
// crate.
834-
let mut ctor_vis = vis;
835-
let has_non_exhaustive = attr::contains_name(&variant.attrs, sym::non_exhaustive);
836-
if has_non_exhaustive && vis == ty::Visibility::Public {
837-
ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
838-
}
839-
840-
// Define a constructor name in the value namespace.
841-
// Braced variants, unlike structs, generate unusable names in
842-
// value namespace, they are reserved for possible future use.
843-
// It's ok to use the variant's id as a ctor id since an
844-
// error will be reported on any use of such resolution anyway.
845-
let ctor_node_id = variant.data.ctor_id().unwrap_or(variant.id);
846-
let ctor_def_id = self.r.definitions.local_def_id(ctor_node_id);
847-
let ctor_kind = CtorKind::from_ast(&variant.data);
848-
let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id);
849-
self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id));
850-
}
851-
852814
/// Constructs the reduced graph for one foreign item.
853815
fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem) {
854816
let (res, ns) = match item.node {
@@ -1188,7 +1150,6 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
11881150
ItemKind::Mod(..) => self.contains_macro_use(&item.attrs),
11891151
_ => false,
11901152
};
1191-
11921153
let orig_current_module = self.parent_scope.module;
11931154
let orig_current_legacy_scope = self.parent_scope.legacy;
11941155
self.build_reduced_graph_for_item(item);
@@ -1271,4 +1232,92 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
12711232
}
12721233
visit::walk_attribute(self, attr);
12731234
}
1235+
1236+
fn visit_arm(&mut self, arm: &'b ast::Arm) {
1237+
if arm.is_placeholder {
1238+
self.visit_invoc(arm.id);
1239+
} else {
1240+
visit::walk_arm(self, arm);
1241+
}
1242+
}
1243+
1244+
fn visit_field(&mut self, f: &'b ast::Field) {
1245+
if f.is_placeholder {
1246+
self.visit_invoc(f.id);
1247+
} else {
1248+
visit::walk_field(self, f);
1249+
}
1250+
}
1251+
1252+
fn visit_field_pattern(&mut self, fp: &'b ast::FieldPat) {
1253+
if fp.is_placeholder {
1254+
self.visit_invoc(fp.id);
1255+
} else {
1256+
visit::walk_field_pattern(self, fp);
1257+
}
1258+
}
1259+
1260+
fn visit_generic_param(&mut self, param: &'b ast::GenericParam) {
1261+
if param.is_placeholder {
1262+
self.visit_invoc(param.id);
1263+
} else {
1264+
visit::walk_generic_param(self, param);
1265+
}
1266+
}
1267+
1268+
fn visit_param(&mut self, p: &'b ast::Param) {
1269+
if p.is_placeholder {
1270+
self.visit_invoc(p.id);
1271+
} else {
1272+
visit::walk_param(self, p);
1273+
}
1274+
}
1275+
1276+
fn visit_struct_field(&mut self, sf: &'b ast::StructField) {
1277+
if sf.is_placeholder {
1278+
self.visit_invoc(sf.id);
1279+
} else {
1280+
visit::walk_struct_field(self, sf);
1281+
}
1282+
}
1283+
1284+
// Constructs the reduced graph for one variant. Variants exist in the
1285+
// type and value namespaces.
1286+
fn visit_variant(&mut self, variant: &'b ast::Variant) {
1287+
if variant.is_placeholder {
1288+
self.visit_invoc(variant.id);
1289+
return;
1290+
}
1291+
1292+
let parent = self.parent_scope.module;
1293+
let vis = self.r.variant_vis[&parent.def_id().expect("enum without def-id")];
1294+
let expn_id = self.parent_scope.expansion;
1295+
let ident = variant.ident;
1296+
1297+
// Define a name in the type namespace.
1298+
let def_id = self.r.definitions.local_def_id(variant.id);
1299+
let res = Res::Def(DefKind::Variant, def_id);
1300+
self.r.define(parent, ident, TypeNS, (res, vis, variant.span, expn_id));
1301+
1302+
// If the variant is marked as non_exhaustive then lower the visibility to within the
1303+
// crate.
1304+
let mut ctor_vis = vis;
1305+
let has_non_exhaustive = attr::contains_name(&variant.attrs, sym::non_exhaustive);
1306+
if has_non_exhaustive && vis == ty::Visibility::Public {
1307+
ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
1308+
}
1309+
1310+
// Define a constructor name in the value namespace.
1311+
// Braced variants, unlike structs, generate unusable names in
1312+
// value namespace, they are reserved for possible future use.
1313+
// It's ok to use the variant's id as a ctor id since an
1314+
// error will be reported on any use of such resolution anyway.
1315+
let ctor_node_id = variant.data.ctor_id().unwrap_or(variant.id);
1316+
let ctor_def_id = self.r.definitions.local_def_id(ctor_node_id);
1317+
let ctor_kind = CtorKind::from_ast(&variant.data);
1318+
let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id);
1319+
self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id));
1320+
1321+
visit::walk_variant(self, variant);
1322+
}
12741323
}

src/librustc_resolve/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,10 @@ pub struct Resolver<'a> {
952952

953953
/// Features enabled for this crate.
954954
active_features: FxHashSet<Symbol>,
955+
956+
/// Stores enum visibilities to properly build a reduced graph
957+
/// when visiting the correspondent variants.
958+
variant_vis: DefIdMap<ty::Visibility>,
955959
}
956960

957961
/// Nothing really interesting here; it just provides memory for the rest of the crate.
@@ -1214,6 +1218,7 @@ impl<'a> Resolver<'a> {
12141218
features.declared_lib_features.iter().map(|(feat, ..)| *feat)
12151219
.chain(features.declared_lang_features.iter().map(|(feat, ..)| *feat))
12161220
.collect(),
1221+
variant_vis: Default::default()
12171222
}
12181223
}
12191224

src/librustc_resolve/macros.rs

+21-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use syntax::attr::StabilityLevel;
1616
use syntax::edition::Edition;
1717
use syntax::ext::base::{self, InvocationRes, Indeterminate, SpecialDerives};
1818
use syntax::ext::base::{MacroKind, SyntaxExtension};
19-
use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
19+
use syntax::ext::expand::{AstFragment, AstFragmentKind, Invocation, InvocationKind};
2020
use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind};
2121
use syntax::ext::tt::macro_rules;
2222
use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name};
@@ -225,6 +225,26 @@ impl<'a> base::Resolver for Resolver<'a> {
225225
self.definitions.add_parent_module_of_macro_def(invoc_id, normal_module_def_id);
226226
}
227227

228+
match invoc.fragment_kind {
229+
AstFragmentKind::Arms
230+
| AstFragmentKind::Fields
231+
| AstFragmentKind::FieldPats
232+
| AstFragmentKind::GenericParams
233+
| AstFragmentKind::Params
234+
| AstFragmentKind::StructFields
235+
| AstFragmentKind::Variants =>
236+
{
237+
if let Res::Def(..) = res {
238+
self.session.span_err(
239+
span,
240+
"expected an inert attribute, found an attribute macro"
241+
);
242+
return Ok(InvocationRes::Single(self.dummy_ext(kind)));
243+
}
244+
},
245+
_ => {}
246+
}
247+
228248
Ok(InvocationRes::Single(ext))
229249
}
230250

src/librustc_typeck/collect.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -519,15 +519,15 @@ fn convert_variant_ctor(tcx: TyCtxt<'_>, ctor_id: hir::HirId) {
519519
tcx.predicates_of(def_id);
520520
}
521521

522-
fn convert_enum_variant_types<'tcx>(
523-
tcx: TyCtxt<'tcx>,
522+
fn convert_enum_variant_types(
523+
tcx: TyCtxt<'_>,
524524
def_id: DefId,
525525
variants: &[hir::Variant]
526526
) {
527527
let def = tcx.adt_def(def_id);
528528
let repr_type = def.repr.discr_type();
529529
let initial = repr_type.initial_discriminant(tcx);
530-
let mut prev_discr = None::<Discr<'tcx>>;
530+
let mut prev_discr = None::<Discr<'_>>;
531531

532532
// fill the discriminant values and field types
533533
for variant in variants {

0 commit comments

Comments
 (0)