Skip to content

Commit 8b012ed

Browse files
committed
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

-9
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

+5-20
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

+84-57
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

-25
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);

0 commit comments

Comments
 (0)