Skip to content

Commit b5c6ab2

Browse files
committed
Run feature-gating on the final AST passed to the compiler.
This ensures we catch everything; previously, an unknown attribute inserted by #[cfg_attr(...)] in a macro expansion would not be detected.
1 parent 10426f6 commit b5c6ab2

File tree

3 files changed

+50
-9
lines changed

3 files changed

+50
-9
lines changed

src/librustc_driver/driver.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -493,12 +493,16 @@ pub fn phase_2_configure_and_expand(sess: &Session,
493493
}
494494
);
495495

496-
// Needs to go *after* expansion to be able to check the results of macro expansion.
497-
time(time_passes, "complete gated feature checking", (), |_| {
496+
// Needs to go *after* expansion to be able to check the results
497+
// of macro expansion. This runs before #[cfg] to try to catch as
498+
// much as possible (e.g. help the programmer avoid platform
499+
// specific differences)
500+
time(time_passes, "complete gated feature checking 1", (), |_| {
498501
let features =
499502
syntax::feature_gate::check_crate(sess.codemap(),
500-
&sess.parse_sess.span_diagnostic,
501-
&krate);
503+
&sess.parse_sess.span_diagnostic,
504+
&krate,
505+
true);
502506
*sess.features.borrow_mut() = features;
503507
sess.abort_if_errors();
504508
});
@@ -521,6 +525,19 @@ pub fn phase_2_configure_and_expand(sess: &Session,
521525
time(time_passes, "checking that all macro invocations are gone", &krate, |krate|
522526
syntax::ext::expand::check_for_macros(&sess.parse_sess, krate));
523527

528+
// One final feature gating of the true AST that gets compiled
529+
// later, to make sure we've got everything (e.g. configuration
530+
// can insert new attributes via `cfg_attr`)
531+
time(time_passes, "complete gated feature checking 2", (), |_| {
532+
let features =
533+
syntax::feature_gate::check_crate(sess.codemap(),
534+
&sess.parse_sess.span_diagnostic,
535+
&krate,
536+
false);
537+
*sess.features.borrow_mut() = features;
538+
sess.abort_if_errors();
539+
});
540+
524541
Some(krate)
525542
}
526543

src/libsyntax/feature_gate.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ struct Context<'a> {
349349
features: Vec<&'static str>,
350350
span_handler: &'a SpanHandler,
351351
cm: &'a CodeMap,
352+
do_warnings: bool,
352353
}
353354

354355
impl<'a> Context<'a> {
@@ -361,7 +362,7 @@ impl<'a> Context<'a> {
361362
}
362363

363364
fn warn_feature(&self, feature: &str, span: Span, explain: &str) {
364-
if !self.has_feature(feature) {
365+
if !self.has_feature(feature) && self.do_warnings {
365366
emit_feature_warn(self.span_handler, feature, span, explain);
366367
}
367368
}
@@ -700,13 +701,15 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
700701
}
701702

702703
fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate,
704+
do_warnings: bool,
703705
check: F)
704706
-> Features
705707
where F: FnOnce(&mut Context, &ast::Crate)
706708
{
707709
let mut cx = Context {
708710
features: Vec::new(),
709711
span_handler: span_handler,
712+
do_warnings: do_warnings,
710713
cm: cm,
711714
};
712715

@@ -786,13 +789,14 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
786789

787790
pub fn check_crate_macros(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate)
788791
-> Features {
789-
check_crate_inner(cm, span_handler, krate,
792+
check_crate_inner(cm, span_handler, krate, true,
790793
|ctx, krate| visit::walk_crate(&mut MacroVisitor { context: ctx }, krate))
791794
}
792795

793-
pub fn check_crate(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate)
794-
-> Features {
795-
check_crate_inner(cm, span_handler, krate,
796+
pub fn check_crate(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate,
797+
do_warnings: bool) -> Features
798+
{
799+
check_crate_inner(cm, span_handler, krate, do_warnings,
796800
|ctx, krate| visit::walk_crate(&mut PostExpansionVisitor { context: ctx },
797801
krate))
798802
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
macro_rules! foo {
12+
() => {
13+
#[cfg_attr(all(), unknown)] //~ ERROR `unknown` is currently unknown
14+
fn foo() {}
15+
}
16+
}
17+
18+
foo!();
19+
20+
fn main() {}

0 commit comments

Comments
 (0)