Skip to content

Commit 8b012ed

Browse files
committedMay 28, 2016
Auto merge of #33706 - jseyfried:refactor_cfg, r=nrc
Perform `cfg` attribute processing during macro expansion and fix bugs This PR refactors `cfg` attribute processing and fixes bugs. More specifically: - It merges gated feature checking for stmt/expr attributes, `cfg_attr` processing, and `cfg` processing into a single fold. - This allows feature gated `cfg` variables to be used in `cfg_attr` on unconfigured items. All other feature gated attributes can already be used on unconfigured items. - It performs `cfg` attribute processing during macro expansion instead of after expansion so that macro-expanded items are configured the same as ordinary items. In particular, to match their non-expanded counterparts, - macro-expanded unconfigured macro invocations are no longer expanded, - macro-expanded unconfigured macro definitions are no longer usable, and - feature gated `cfg` variables on macro-expanded macro definitions/invocations are now errors. This is a [breaking-change]. For example, the following would break: ```rust macro_rules! m { () => { #[cfg(attr)] macro_rules! foo { () => {} } foo!(); // This will be an error macro_rules! bar { () => { fn f() {} } } #[cfg(attr)] bar!(); // This will no longer be expanded ... fn g() { f(); } // ... so that `f` will be unresolved. #[cfg(target_thread_local)] // This will be a gated feature error macro_rules! baz { () => {} } } } m!(); ``` r? @nrc
2 parents 7bddce6 + 53ab137 commit 8b012ed

File tree

8 files changed

+355
-613
lines changed

8 files changed

+355
-613
lines changed
 

‎src/librustc_driver/driver.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -720,16 +720,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
720720
ret
721721
});
722722

723-
// JBC: make CFG processing part of expansion to avoid this problem:
724-
725-
// strip again, in case expansion added anything with a #[cfg].
726723
krate = sess.track_errors(|| {
727-
let krate = time(time_passes, "configuration 2", || {
728-
syntax::config::strip_unconfigured_items(sess.diagnostic(),
729-
krate,
730-
&mut feature_gated_cfgs)
731-
});
732-
733724
time(time_passes, "gated configuration checking", || {
734725
let features = sess.features.borrow();
735726
feature_gated_cfgs.sort();

‎src/libsyntax/ast.rs

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub use self::UnsafeSource::*;
1515
pub use self::ViewPath_::*;
1616
pub use self::PathParameters::*;
1717

18-
use attr::ThinAttributes;
18+
use attr::{ThinAttributes, HasAttrs};
1919
use codemap::{mk_sp, respan, Span, Spanned, DUMMY_SP, ExpnId};
2020
use abi::Abi;
2121
use errors;
@@ -831,13 +831,7 @@ impl StmtKind {
831831
}
832832

833833
pub fn attrs(&self) -> &[Attribute] {
834-
match *self {
835-
StmtKind::Decl(ref d, _) => d.attrs(),
836-
StmtKind::Expr(ref e, _) |
837-
StmtKind::Semi(ref e, _) => e.attrs(),
838-
StmtKind::Mac(_, _, Some(ref b)) => b,
839-
StmtKind::Mac(_, _, None) => &[],
840-
}
834+
HasAttrs::attrs(self)
841835
}
842836
}
843837

@@ -870,10 +864,7 @@ pub struct Local {
870864

871865
impl Local {
872866
pub fn attrs(&self) -> &[Attribute] {
873-
match self.attrs {
874-
Some(ref b) => b,
875-
None => &[],
876-
}
867+
HasAttrs::attrs(self)
877868
}
878869
}
879870

@@ -889,10 +880,7 @@ pub enum DeclKind {
889880

890881
impl Decl {
891882
pub fn attrs(&self) -> &[Attribute] {
892-
match self.node {
893-
DeclKind::Local(ref l) => l.attrs(),
894-
DeclKind::Item(ref i) => i.attrs(),
895-
}
883+
HasAttrs::attrs(self)
896884
}
897885
}
898886

@@ -937,10 +925,7 @@ pub struct Expr {
937925

938926
impl Expr {
939927
pub fn attrs(&self) -> &[Attribute] {
940-
match self.attrs {
941-
Some(ref b) => b,
942-
None => &[],
943-
}
928+
HasAttrs::attrs(self)
944929
}
945930
}
946931

‎src/libsyntax/attr.rs

Lines changed: 84 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -884,82 +884,109 @@ impl AttributesExt for Vec<Attribute> {
884884
}
885885
}
886886

887+
pub trait HasAttrs: Sized {
888+
fn attrs(&self) -> &[ast::Attribute];
889+
fn map_attrs<F: FnOnce(Vec<ast::Attribute>) -> Vec<ast::Attribute>>(self, f: F) -> Self;
890+
}
891+
887892
/// A cheap way to add Attributes to an AST node.
888893
pub trait WithAttrs {
889894
// FIXME: Could be extended to anything IntoIter<Item=Attribute>
890895
fn with_attrs(self, attrs: ThinAttributes) -> Self;
891896
}
892897

893-
impl WithAttrs for P<Expr> {
898+
impl<T: HasAttrs> WithAttrs for T {
894899
fn with_attrs(self, attrs: ThinAttributes) -> Self {
895-
self.map(|mut e| {
896-
e.attrs.update(|a| a.append(attrs));
897-
e
900+
self.map_attrs(|mut orig_attrs| {
901+
orig_attrs.extend(attrs.into_attr_vec());
902+
orig_attrs
898903
})
899904
}
900905
}
901906

902-
impl WithAttrs for P<Item> {
903-
fn with_attrs(self, attrs: ThinAttributes) -> Self {
904-
self.map(|Item { ident, attrs: mut ats, id, node, vis, span }| {
905-
ats.extend(attrs.into_attr_vec());
906-
Item {
907-
ident: ident,
908-
attrs: ats,
909-
id: id,
910-
node: node,
911-
vis: vis,
912-
span: span,
913-
}
914-
})
907+
impl HasAttrs for Vec<Attribute> {
908+
fn attrs(&self) -> &[Attribute] {
909+
&self
910+
}
911+
fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
912+
f(self)
915913
}
916914
}
917915

918-
impl WithAttrs for P<Local> {
919-
fn with_attrs(self, attrs: ThinAttributes) -> Self {
920-
self.map(|Local { pat, ty, init, id, span, attrs: mut ats }| {
921-
ats.update(|a| a.append(attrs));
922-
Local {
923-
pat: pat,
924-
ty: ty,
925-
init: init,
926-
id: id,
927-
span: span,
928-
attrs: ats,
929-
}
930-
})
916+
impl HasAttrs for ThinAttributes {
917+
fn attrs(&self) -> &[Attribute] {
918+
self.as_attr_slice()
919+
}
920+
fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
921+
self.map_thin_attrs(f)
931922
}
932923
}
933924

934-
impl WithAttrs for P<Decl> {
935-
fn with_attrs(self, attrs: ThinAttributes) -> Self {
936-
self.map(|Spanned { span, node }| {
937-
Spanned {
938-
span: span,
939-
node: match node {
940-
DeclKind::Local(local) => DeclKind::Local(local.with_attrs(attrs)),
941-
DeclKind::Item(item) => DeclKind::Item(item.with_attrs(attrs)),
942-
}
943-
}
944-
})
925+
impl<T: HasAttrs + 'static> HasAttrs for P<T> {
926+
fn attrs(&self) -> &[Attribute] {
927+
(**self).attrs()
928+
}
929+
fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
930+
self.map(|t| t.map_attrs(f))
945931
}
946932
}
947933

948-
impl WithAttrs for P<Stmt> {
949-
fn with_attrs(self, attrs: ThinAttributes) -> Self {
950-
self.map(|Spanned { span, node }| {
951-
Spanned {
952-
span: span,
953-
node: match node {
954-
StmtKind::Decl(decl, id) => StmtKind::Decl(decl.with_attrs(attrs), id),
955-
StmtKind::Expr(expr, id) => StmtKind::Expr(expr.with_attrs(attrs), id),
956-
StmtKind::Semi(expr, id) => StmtKind::Semi(expr.with_attrs(attrs), id),
957-
StmtKind::Mac(mac, style, mut ats) => {
958-
ats.update(|a| a.append(attrs));
959-
StmtKind::Mac(mac, style, ats)
960-
}
961-
},
962-
}
963-
})
934+
impl HasAttrs for DeclKind {
935+
fn attrs(&self) -> &[Attribute] {
936+
match *self {
937+
DeclKind::Local(ref local) => local.attrs(),
938+
DeclKind::Item(ref item) => item.attrs(),
939+
}
940+
}
941+
942+
fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
943+
match self {
944+
DeclKind::Local(local) => DeclKind::Local(local.map_attrs(f)),
945+
DeclKind::Item(item) => DeclKind::Item(item.map_attrs(f)),
946+
}
964947
}
965948
}
949+
950+
impl HasAttrs for StmtKind {
951+
fn attrs(&self) -> &[Attribute] {
952+
match *self {
953+
StmtKind::Decl(ref decl, _) => decl.attrs(),
954+
StmtKind::Expr(ref expr, _) | StmtKind::Semi(ref expr, _) => expr.attrs(),
955+
StmtKind::Mac(_, _, ref attrs) => attrs.attrs(),
956+
}
957+
}
958+
959+
fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
960+
match self {
961+
StmtKind::Decl(decl, id) => StmtKind::Decl(decl.map_attrs(f), id),
962+
StmtKind::Expr(expr, id) => StmtKind::Expr(expr.map_attrs(f), id),
963+
StmtKind::Semi(expr, id) => StmtKind::Semi(expr.map_attrs(f), id),
964+
StmtKind::Mac(mac, style, attrs) =>
965+
StmtKind::Mac(mac, style, attrs.map_attrs(f)),
966+
}
967+
}
968+
}
969+
970+
macro_rules! derive_has_attrs_from_field {
971+
($($ty:path),*) => { derive_has_attrs_from_field!($($ty: .attrs),*); };
972+
($($ty:path : $(.$field:ident)*),*) => { $(
973+
impl HasAttrs for $ty {
974+
fn attrs(&self) -> &[Attribute] {
975+
self $(.$field)* .attrs()
976+
}
977+
978+
fn map_attrs<F>(mut self, f: F) -> Self
979+
where F: FnOnce(Vec<Attribute>) -> Vec<Attribute>,
980+
{
981+
self $(.$field)* = self $(.$field)* .map_attrs(f);
982+
self
983+
}
984+
}
985+
)* }
986+
}
987+
988+
derive_has_attrs_from_field! {
989+
Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::ImplItem, ast::TraitItem, ast::Arm
990+
}
991+
992+
derive_has_attrs_from_field! { Decl: .node, Stmt: .node, ast::Variant: .node.attrs }

‎src/libsyntax/codemap.rs

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,31 +1258,6 @@ impl CodeMap {
12581258
return a;
12591259
}
12601260

1261-
/// Check if the backtrace `subtrace` contains `suptrace` as a prefix.
1262-
pub fn more_specific_trace(&self,
1263-
mut subtrace: ExpnId,
1264-
suptrace: ExpnId)
1265-
-> bool {
1266-
loop {
1267-
if subtrace == suptrace {
1268-
return true;
1269-
}
1270-
1271-
let stop = self.with_expn_info(subtrace, |opt_expn_info| {
1272-
if let Some(expn_info) = opt_expn_info {
1273-
subtrace = expn_info.call_site.expn_id;
1274-
false
1275-
} else {
1276-
true
1277-
}
1278-
});
1279-
1280-
if stop {
1281-
return false;
1282-
}
1283-
}
1284-
}
1285-
12861261
pub fn record_expansion(&self, expn_info: ExpnInfo) -> ExpnId {
12871262
let mut expansions = self.expansions.borrow_mut();
12881263
expansions.push(expn_info);

‎src/libsyntax/config.rs

Lines changed: 184 additions & 412 deletions
Large diffs are not rendered by default.

‎src/libsyntax/ext/expand.rs

Lines changed: 65 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use ext::build::AstBuilder;
1818
use attr;
1919
use attr::{AttrMetaMethods, WithAttrs, ThinAttributesExt};
2020
use codemap;
21-
use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
21+
use codemap::{Span, Spanned, ExpnInfo, ExpnId, NameAndSpan, MacroBang, MacroAttribute};
22+
use config::StripUnconfigured;
2223
use ext::base::*;
2324
use feature_gate::{self, Features};
2425
use fold;
@@ -33,7 +34,6 @@ use visit::Visitor;
3334
use std_inject;
3435

3536
use std::collections::HashSet;
36-
use std::env;
3737

3838
// A trait for AST nodes and AST node lists into which macro invocations may expand.
3939
trait MacroGenerable: Sized {
@@ -77,25 +77,35 @@ impl_macro_generable! {
7777
"statement", .make_stmts, lift .fold_stmt, |_span| SmallVector::zero();
7878
}
7979

80-
pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
81-
return e.and_then(|ast::Expr {id, node, span, attrs}| match node {
80+
impl MacroGenerable for Option<P<ast::Expr>> {
81+
fn kind_name() -> &'static str { "expression" }
82+
fn dummy(_span: Span) -> Self { None }
83+
fn make_with<'a>(result: Box<MacResult + 'a>) -> Option<Self> {
84+
result.make_expr().map(Some)
85+
}
86+
fn fold_with<F: Folder>(self, folder: &mut F) -> Self {
87+
self.and_then(|expr| folder.fold_opt_expr(expr))
88+
}
89+
}
8290

91+
pub fn expand_expr(expr: ast::Expr, fld: &mut MacroExpander) -> P<ast::Expr> {
92+
match expr.node {
8393
// expr_mac should really be expr_ext or something; it's the
8494
// entry-point for all syntax extensions.
8595
ast::ExprKind::Mac(mac) => {
86-
expand_mac_invoc(mac, None, attrs.into_attr_vec(), span, fld)
96+
expand_mac_invoc(mac, None, expr.attrs.into_attr_vec(), expr.span, fld)
8797
}
8898

8999
ast::ExprKind::While(cond, body, opt_ident) => {
90100
let cond = fld.fold_expr(cond);
91101
let (body, opt_ident) = expand_loop_block(body, opt_ident, fld);
92-
fld.cx.expr(span, ast::ExprKind::While(cond, body, opt_ident))
93-
.with_attrs(fold_thin_attrs(attrs, fld))
102+
fld.cx.expr(expr.span, ast::ExprKind::While(cond, body, opt_ident))
103+
.with_attrs(fold_thin_attrs(expr.attrs, fld))
94104
}
95105

96-
ast::ExprKind::WhileLet(pat, expr, body, opt_ident) => {
106+
ast::ExprKind::WhileLet(pat, cond, body, opt_ident) => {
97107
let pat = fld.fold_pat(pat);
98-
let expr = fld.fold_expr(expr);
108+
let cond = fld.fold_expr(cond);
99109

100110
// Hygienic renaming of the body.
101111
let ((body, opt_ident), mut rewritten_pats) =
@@ -107,14 +117,14 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
107117
});
108118
assert!(rewritten_pats.len() == 1);
109119

110-
let wl = ast::ExprKind::WhileLet(rewritten_pats.remove(0), expr, body, opt_ident);
111-
fld.cx.expr(span, wl).with_attrs(fold_thin_attrs(attrs, fld))
120+
let wl = ast::ExprKind::WhileLet(rewritten_pats.remove(0), cond, body, opt_ident);
121+
fld.cx.expr(expr.span, wl).with_attrs(fold_thin_attrs(expr.attrs, fld))
112122
}
113123

114124
ast::ExprKind::Loop(loop_block, opt_ident) => {
115125
let (loop_block, opt_ident) = expand_loop_block(loop_block, opt_ident, fld);
116-
fld.cx.expr(span, ast::ExprKind::Loop(loop_block, opt_ident))
117-
.with_attrs(fold_thin_attrs(attrs, fld))
126+
fld.cx.expr(expr.span, ast::ExprKind::Loop(loop_block, opt_ident))
127+
.with_attrs(fold_thin_attrs(expr.attrs, fld))
118128
}
119129

120130
ast::ExprKind::ForLoop(pat, head, body, opt_ident) => {
@@ -132,7 +142,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
132142

133143
let head = fld.fold_expr(head);
134144
let fl = ast::ExprKind::ForLoop(rewritten_pats.remove(0), head, body, opt_ident);
135-
fld.cx.expr(span, fl).with_attrs(fold_thin_attrs(attrs, fld))
145+
fld.cx.expr(expr.span, fl).with_attrs(fold_thin_attrs(expr.attrs, fld))
136146
}
137147

138148
ast::ExprKind::IfLet(pat, sub_expr, body, else_opt) => {
@@ -151,7 +161,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
151161
let else_opt = else_opt.map(|else_opt| fld.fold_expr(else_opt));
152162
let sub_expr = fld.fold_expr(sub_expr);
153163
let il = ast::ExprKind::IfLet(rewritten_pats.remove(0), sub_expr, body, else_opt);
154-
fld.cx.expr(span, il).with_attrs(fold_thin_attrs(attrs, fld))
164+
fld.cx.expr(expr.span, il).with_attrs(fold_thin_attrs(expr.attrs, fld))
155165
}
156166

157167
ast::ExprKind::Closure(capture_clause, fn_decl, block, fn_decl_span) => {
@@ -160,22 +170,15 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
160170
let new_node = ast::ExprKind::Closure(capture_clause,
161171
rewritten_fn_decl,
162172
rewritten_block,
163-
fld.new_span(fn_decl_span));
164-
P(ast::Expr{ id:id,
173+
fn_decl_span);
174+
P(ast::Expr{ id: expr.id,
165175
node: new_node,
166-
span: fld.new_span(span),
167-
attrs: fold_thin_attrs(attrs, fld) })
176+
span: expr.span,
177+
attrs: fold_thin_attrs(expr.attrs, fld) })
168178
}
169179

170-
_ => {
171-
P(noop_fold_expr(ast::Expr {
172-
id: id,
173-
node: node,
174-
span: span,
175-
attrs: attrs
176-
}, fld))
177-
}
178-
});
180+
_ => P(noop_fold_expr(expr, fld)),
181+
}
179182
}
180183

181184
/// Expand a macro invocation. Returns the result of expansion.
@@ -322,8 +325,9 @@ fn expand_mac_invoc<T>(mac: ast::Mac, ident: Option<Ident>, attrs: Vec<ast::Attr
322325
return T::dummy(span);
323326
};
324327

325-
let marked = expanded.fold_with(&mut Marker { mark: mark });
326-
let fully_expanded = marked.fold_with(fld);
328+
let marked = expanded.fold_with(&mut Marker { mark: mark, expn_id: Some(fld.cx.backtrace()) });
329+
let configured = marked.fold_with(&mut fld.strip_unconfigured());
330+
let fully_expanded = configured.fold_with(fld);
327331
fld.cx.bt_pop();
328332
fully_expanded
329333
}
@@ -699,12 +703,12 @@ impl<'a> Folder for PatIdentRenamer<'a> {
699703
mtwt::apply_renames(self.renames, ident.ctxt));
700704
let new_node =
701705
PatKind::Ident(binding_mode,
702-
Spanned{span: self.new_span(sp), node: new_ident},
706+
Spanned{span: sp, node: new_ident},
703707
sub.map(|p| self.fold_pat(p)));
704708
ast::Pat {
705709
id: id,
706710
node: new_node,
707-
span: self.new_span(span)
711+
span: span,
708712
}
709713
},
710714
_ => unreachable!()
@@ -774,7 +778,7 @@ fn expand_annotatable(a: Annotatable,
774778
}
775779
_ => unreachable!()
776780
},
777-
span: fld.new_span(ti.span)
781+
span: ti.span,
778782
})
779783
}
780784
_ => fold::noop_fold_trait_item(it.unwrap(), fld)
@@ -914,7 +918,7 @@ fn expand_impl_item(ii: ast::ImplItem, fld: &mut MacroExpander)
914918
}
915919
_ => unreachable!()
916920
},
917-
span: fld.new_span(ii.span)
921+
span: ii.span,
918922
}),
919923
ast::ImplItemKind::Macro(mac) => {
920924
expand_mac_invoc(mac, None, ii.attrs, ii.span, fld)
@@ -987,6 +991,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
987991
pub fn new(cx: &'a mut ExtCtxt<'b>) -> MacroExpander<'a, 'b> {
988992
MacroExpander { cx: cx }
989993
}
994+
995+
fn strip_unconfigured(&mut self) -> StripUnconfigured {
996+
StripUnconfigured::new(&self.cx.cfg,
997+
&self.cx.parse_sess.span_diagnostic,
998+
self.cx.feature_gated_cfgs)
999+
}
9901000
}
9911001

9921002
impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
@@ -996,7 +1006,15 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
9961006
}
9971007

9981008
fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
999-
expand_expr(expr, self)
1009+
expr.and_then(|expr| expand_expr(expr, self))
1010+
}
1011+
1012+
fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
1013+
expr.and_then(|expr| match expr.node {
1014+
ast::ExprKind::Mac(mac) =>
1015+
expand_mac_invoc(mac, None, expr.attrs.into_attr_vec(), expr.span, self),
1016+
_ => Some(expand_expr(expr, self)),
1017+
})
10001018
}
10011019

10021020
fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
@@ -1059,10 +1077,6 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
10591077
fn fold_ty(&mut self, ty: P<ast::Ty>) -> P<ast::Ty> {
10601078
expand_type(ty, self)
10611079
}
1062-
1063-
fn new_span(&mut self, span: Span) -> Span {
1064-
new_span(self.cx, span)
1065-
}
10661080
}
10671081

10681082
impl<'a, 'b> MacroExpander<'a, 'b> {
@@ -1080,45 +1094,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
10801094
}
10811095
}
10821096

1083-
fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
1084-
debug!("new_span(sp={:?})", sp);
1085-
1086-
if cx.codemap().more_specific_trace(sp.expn_id, cx.backtrace()) {
1087-
// If the span we are looking at has a backtrace that has more
1088-
// detail than our current backtrace, then we keep that
1089-
// backtrace. Honestly, I have no idea if this makes sense,
1090-
// because I have no idea why we are stripping the backtrace
1091-
// below. But the reason I made this change is because, in
1092-
// deriving, we were generating attributes with a specific
1093-
// backtrace, which was essential for `#[structural_match]` to
1094-
// be properly supported, but these backtraces were being
1095-
// stripped and replaced with a null backtrace. Sort of
1096-
// unclear why this is the case. --nmatsakis
1097-
debug!("new_span: keeping trace from {:?} because it is more specific",
1098-
sp.expn_id);
1099-
sp
1100-
} else {
1101-
// This discards information in the case of macro-defining macros.
1102-
//
1103-
// The comment above was originally added in
1104-
// b7ec2488ff2f29681fe28691d20fd2c260a9e454 in Feb 2012. I
1105-
// *THINK* the reason we are doing this is because we want to
1106-
// replace the backtrace of the macro contents with the
1107-
// backtrace that contains the macro use. But it's pretty
1108-
// unclear to me. --nmatsakis
1109-
let sp1 = Span {
1110-
lo: sp.lo,
1111-
hi: sp.hi,
1112-
expn_id: cx.backtrace(),
1113-
};
1114-
debug!("new_span({:?}) = {:?}", sp, sp1);
1115-
if sp.expn_id.into_u32() == 0 && env::var_os("NDM").is_some() {
1116-
panic!("NDM");
1117-
}
1118-
sp1
1119-
}
1120-
}
1121-
11221097
pub struct ExpansionConfig<'feat> {
11231098
pub crate_name: String,
11241099
pub features: Option<&'feat Features>,
@@ -1205,8 +1180,9 @@ pub fn expand_crate(mut cx: ExtCtxt,
12051180
// the ones defined here include:
12061181
// Marker - add a mark to a context
12071182

1208-
// A Marker adds the given mark to the syntax context
1209-
struct Marker { mark: Mrk }
1183+
// A Marker adds the given mark to the syntax context and
1184+
// sets spans' `expn_id` to the given expn_id (unless it is `None`).
1185+
struct Marker { mark: Mrk, expn_id: Option<ExpnId> }
12101186

12111187
impl Folder for Marker {
12121188
fn fold_ident(&mut self, id: Ident) -> Ident {
@@ -1219,14 +1195,21 @@ impl Folder for Marker {
12191195
tts: self.fold_tts(&node.tts),
12201196
ctxt: mtwt::apply_mark(self.mark, node.ctxt),
12211197
},
1222-
span: span,
1198+
span: self.new_span(span),
1199+
}
1200+
}
1201+
1202+
fn new_span(&mut self, mut span: Span) -> Span {
1203+
if let Some(expn_id) = self.expn_id {
1204+
span.expn_id = expn_id;
12231205
}
1206+
span
12241207
}
12251208
}
12261209

12271210
// apply a given mark to the given token trees. Used prior to expansion of a macro.
12281211
fn mark_tts(tts: &[TokenTree], m: Mrk) -> Vec<TokenTree> {
1229-
noop_fold_tts(tts, &mut Marker{mark:m})
1212+
noop_fold_tts(tts, &mut Marker{mark:m, expn_id: None})
12301213
}
12311214

12321215
/// Check that there are no macro invocations left in the AST:

‎src/libsyntax/test.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub fn modify_for_testing(sess: &ParseSess,
8787
if should_test {
8888
generate_test_harness(sess, reexport_test_harness_main, krate, cfg, span_diagnostic)
8989
} else {
90-
strip_test_functions(span_diagnostic, krate)
90+
strip_test_functions(krate)
9191
}
9292
}
9393

@@ -312,14 +312,17 @@ fn generate_test_harness(sess: &ParseSess,
312312
return res;
313313
}
314314

315-
fn strip_test_functions(diagnostic: &errors::Handler, krate: ast::Crate)
316-
-> ast::Crate {
315+
fn strip_test_functions(krate: ast::Crate) -> ast::Crate {
317316
// When not compiling with --test we should not compile the
318317
// #[test] functions
319-
config::strip_items(diagnostic, krate, |attrs| {
320-
!attr::contains_name(&attrs[..], "test") &&
321-
!attr::contains_name(&attrs[..], "bench")
322-
})
318+
struct StripTests;
319+
impl config::CfgFolder for StripTests {
320+
fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool {
321+
!attr::contains_name(attrs, "test") && !attr::contains_name(attrs, "bench")
322+
}
323+
}
324+
325+
StripTests.fold_crate(krate)
323326
}
324327

325328
/// Craft a span that will be ignored by the stability lint's

‎src/test/compile-fail/expanded-cfg.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,21 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#![feature(rustc_attrs)]
11+
#![feature(custom_attribute, rustc_attrs)]
1212

1313
macro_rules! mac {
1414
{} => {
1515
#[cfg(attr)]
1616
mod m {
1717
#[lang_item]
1818
fn f() {}
19+
20+
#[cfg_attr(target_thread_local, custom)]
21+
fn g() {}
1922
}
23+
24+
#[cfg(attr)]
25+
unconfigured_invocation!();
2026
}
2127
}
2228

0 commit comments

Comments
 (0)
Please sign in to comment.