Skip to content

Commit 0ecaa67

Browse files
committed
rustc: Refactor attribute checking to operate on HIR
This'll enable running queries that could be cached and overall be more amenable to the query infastructure.
1 parent 5f006ce commit 0ecaa67

File tree

5 files changed

+56
-44
lines changed

5 files changed

+56
-44
lines changed

src/librustc/hir/check_attr.rs

+38-28
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@
1414
//! conflicts between multiple such attributes attached to the same
1515
//! item.
1616
17-
use session::Session;
17+
use ty::TyCtxt;
1818

19-
use syntax::ast;
20-
use syntax::visit;
21-
use syntax::visit::Visitor;
19+
use hir;
20+
use hir::intravisit::{self, Visitor, NestedVisitorMap};
2221

2322
#[derive(Copy, Clone, PartialEq)]
2423
enum Target {
@@ -30,45 +29,51 @@ enum Target {
3029
}
3130

3231
impl Target {
33-
fn from_item(item: &ast::Item) -> Target {
32+
fn from_item(item: &hir::Item) -> Target {
3433
match item.node {
35-
ast::ItemKind::Fn(..) => Target::Fn,
36-
ast::ItemKind::Struct(..) => Target::Struct,
37-
ast::ItemKind::Union(..) => Target::Union,
38-
ast::ItemKind::Enum(..) => Target::Enum,
34+
hir::ItemFn(..) => Target::Fn,
35+
hir::ItemStruct(..) => Target::Struct,
36+
hir::ItemUnion(..) => Target::Union,
37+
hir::ItemEnum(..) => Target::Enum,
3938
_ => Target::Other,
4039
}
4140
}
4241
}
4342

44-
struct CheckAttrVisitor<'a> {
45-
sess: &'a Session,
43+
struct CheckAttrVisitor<'a, 'tcx: 'a> {
44+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
4645
}
4746

48-
impl<'a> CheckAttrVisitor<'a> {
47+
impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
4948
/// Check any attribute.
50-
fn check_attributes(&self, item: &ast::Item, target: Target) {
49+
fn check_attributes(&self, item: &hir::Item, target: Target) {
50+
self.tcx.target_features_enabled(self.tcx.hir.local_def_id(item.id));
51+
5152
for attr in &item.attrs {
5253
if let Some(name) = attr.name() {
5354
if name == "inline" {
5455
self.check_inline(attr, item, target)
5556
}
5657
}
5758
}
59+
5860
self.check_repr(item, target);
5961
}
6062

6163
/// Check if an `#[inline]` is applied to a function.
62-
fn check_inline(&self, attr: &ast::Attribute, item: &ast::Item, target: Target) {
64+
fn check_inline(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) {
6365
if target != Target::Fn {
64-
struct_span_err!(self.sess, attr.span, E0518, "attribute should be applied to function")
66+
struct_span_err!(self.tcx.sess,
67+
attr.span,
68+
E0518,
69+
"attribute should be applied to function")
6570
.span_label(item.span, "not a function")
6671
.emit();
6772
}
6873
}
6974

7075
/// Check if the `#[repr]` attributes on `item` are valid.
71-
fn check_repr(&self, item: &ast::Item, target: Target) {
76+
fn check_repr(&self, item: &hir::Item, target: Target) {
7277
// Extract the names of all repr hints, e.g., [foo, bar, align] for:
7378
// ```
7479
// #[repr(foo)]
@@ -144,7 +149,7 @@ impl<'a> CheckAttrVisitor<'a> {
144149
}
145150
_ => continue,
146151
};
147-
struct_span_err!(self.sess, hint.span, E0517,
152+
struct_span_err!(self.tcx.sess, hint.span, E0517,
148153
"attribute should be applied to {}", allowed_targets)
149154
.span_label(item.span, format!("not {} {}", article, allowed_targets))
150155
.emit();
@@ -154,32 +159,37 @@ impl<'a> CheckAttrVisitor<'a> {
154159
if (int_reprs > 1)
155160
|| (is_simd && is_c)
156161
|| (int_reprs == 1 && is_c && is_c_like_enum(item)) {
157-
// Just point at all repr hints. This is not ideal, but tracking precisely which ones
158-
// are at fault is a huge hassle.
162+
// Just point at all repr hints. This is not ideal, but tracking
163+
// precisely which ones are at fault is a huge hassle.
159164
let spans: Vec<_> = hints.iter().map(|hint| hint.span).collect();
160-
span_warn!(self.sess, spans, E0566,
165+
span_warn!(self.tcx.sess, spans, E0566,
161166
"conflicting representation hints");
162167
}
163168
}
164169
}
165170

166-
impl<'a> Visitor<'a> for CheckAttrVisitor<'a> {
167-
fn visit_item(&mut self, item: &'a ast::Item) {
171+
impl<'a, 'tcx> Visitor<'tcx> for CheckAttrVisitor<'a, 'tcx> {
172+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
173+
NestedVisitorMap::None
174+
}
175+
176+
fn visit_item(&mut self, item: &'tcx hir::Item) {
168177
let target = Target::from_item(item);
169178
self.check_attributes(item, target);
170-
visit::walk_item(self, item);
179+
intravisit::walk_item(self, item);
171180
}
172181
}
173182

174-
pub fn check_crate(sess: &Session, krate: &ast::Crate) {
175-
visit::walk_crate(&mut CheckAttrVisitor { sess: sess }, krate);
183+
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
184+
let mut checker = CheckAttrVisitor { tcx };
185+
tcx.hir.krate().visit_all_item_likes(&mut checker.as_deep_visitor());
176186
}
177187

178-
fn is_c_like_enum(item: &ast::Item) -> bool {
179-
if let ast::ItemKind::Enum(ref def, _) = item.node {
188+
fn is_c_like_enum(item: &hir::Item) -> bool {
189+
if let hir::ItemEnum(ref def, _) = item.node {
180190
for variant in &def.variants {
181191
match variant.node.data {
182-
ast::VariantData::Unit(_) => { /* continue */ }
192+
hir::VariantData::Unit(_) => { /* continue */ }
183193
_ => { return false; }
184194
}
185195
}

src/librustc_driver/driver.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,6 @@ pub fn compile_input(sess: &Session,
210210
Ok(()));
211211
}
212212

213-
time(sess.time_passes(), "attribute checking", || {
214-
hir::check_attr::check_crate(sess, &expanded_crate);
215-
});
216-
217213
let opt_crate = if control.keep_ast {
218214
Some(&expanded_crate)
219215
} else {
@@ -1038,6 +1034,10 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(control: &CompileController,
10381034
// tcx available.
10391035
rustc_incremental::dep_graph_tcx_init(tcx);
10401036

1037+
time(sess.time_passes(), "attribute checking", || {
1038+
hir::check_attr::check_crate(tcx)
1039+
});
1040+
10411041
time(time_passes,
10421042
"stability checking",
10431043
|| stability::check_unstable_api_usage(tcx));

src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
error[E0601]: main function not found
2+
13
error[E0518]: attribute should be applied to function
24
--> $DIR/issue-43106-gating-of-inline.rs:21:1
35
|
@@ -37,7 +39,5 @@ error[E0518]: attribute should be applied to function
3739
35 | #[inline = "2100"] impl S { }
3840
| ^^^^^^^^^^^^^^^^^^ ---------- not a function
3941

40-
error[E0601]: main function not found
41-
4242
error: aborting due to 6 previous errors
4343

src/test/ui/target-feature-wrong.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
// ignore-arm
1212
// ignore-aarch64
13+
// ignore-wasm
14+
// ignore-emscripten
1315

1416
#![feature(target_feature)]
1517

src/test/ui/target-feature-wrong.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
warning: #[target_feature = ".."] is deprecated and will eventually be removed, use #[target_feature(enable = "..")] instead
2-
--> $DIR/target-feature-wrong.rs:16:1
2+
--> $DIR/target-feature-wrong.rs:18:1
33
|
4-
16 | #[target_feature = "+sse2"]
4+
18 | #[target_feature = "+sse2"]
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
66

77
error: the feature named `foo` is not valid for this target
8-
--> $DIR/target-feature-wrong.rs:18:18
8+
--> $DIR/target-feature-wrong.rs:20:18
99
|
10-
18 | #[target_feature(enable = "foo")]
10+
20 | #[target_feature(enable = "foo")]
1111
| ^^^^^^^^^^^^^^
1212

1313
error: #[target_feature(..)] only accepts sub-keys of `enable` currently
14-
--> $DIR/target-feature-wrong.rs:20:18
14+
--> $DIR/target-feature-wrong.rs:22:18
1515
|
16-
20 | #[target_feature(bar)]
16+
22 | #[target_feature(bar)]
1717
| ^^^
1818

1919
error: #[target_feature(..)] only accepts sub-keys of `enable` currently
20-
--> $DIR/target-feature-wrong.rs:22:18
20+
--> $DIR/target-feature-wrong.rs:24:18
2121
|
22-
22 | #[target_feature(disable = "baz")]
22+
24 | #[target_feature(disable = "baz")]
2323
| ^^^^^^^^^^^^^^^
2424

2525
error: #[target_feature(..)] can only be applied to `unsafe` function
26-
--> $DIR/target-feature-wrong.rs:26:1
26+
--> $DIR/target-feature-wrong.rs:28:1
2727
|
28-
26 | #[target_feature(enable = "sse2")]
28+
28 | #[target_feature(enable = "sse2")]
2929
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3030

3131
error: aborting due to 4 previous errors

0 commit comments

Comments
 (0)