Skip to content

Commit 154ca08

Browse files
committed
use trait rather than fns
please note the snapshot-waiting unpleasantness. I'm unable to use the traditional #[cfg(stage0)] mechanism to swap the new style in for later compiler stages, because macros invocations in method positions cause the parser to choke before cfg can strip it out. Parenthetical note: this problem wouldn't arise with an interleaved parsing/expansion....
1 parent b422373 commit 154ca08

File tree

1 file changed

+81
-21
lines changed

1 file changed

+81
-21
lines changed

src/libsyntax/ast_util.rs

Lines changed: 81 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -742,37 +742,98 @@ pub fn static_has_significant_address(mutbl: ast::Mutability,
742742
inline == InlineNever || inline == InlineNone
743743
}
744744

745-
746745
/// Macro invocations are guaranteed not to occur after expansion is complete.
747-
/// extracting fields of a method requires a dynamic check to make sure that it's
748-
/// not a macro invocation, though this check is guaranteed to succeed, assuming
746+
/// Extracting fields of a method requires a dynamic check to make sure that it's
747+
/// not a macro invocation. This check is guaranteed to succeed, assuming
749748
/// that the invocations are indeed gone.
750-
macro_rules! method_field_extractor {
751-
($fn_name:ident, $field_ty:ty, $field_pat:pat, $result:ident) => {
752-
/// Returns the ident of a Method. To be used after expansion is complete
753-
pub fn $fn_name<'a>(method: &'a ast::Method) -> $field_ty {
754-
match method.node {
749+
pub trait PostExpansionMethod {
750+
fn pe_ident(&self) -> ast::Ident;
751+
fn pe_generics<'a>(&'a self) -> &'a ast::Generics;
752+
fn pe_explicit_self<'a>(&'a self) -> &'a ast::ExplicitSelf;
753+
fn pe_fn_style(&self) -> ast::FnStyle;
754+
fn pe_fn_decl(&self) -> P<ast::FnDecl>;
755+
fn pe_body(&self) -> P<ast::Block>;
756+
fn pe_vis(&self) -> ast::Visibility;
757+
}
758+
759+
760+
/// can't use the standard cfg(stage0) tricks here, because the error occurs in
761+
/// parsing, before cfg gets a chance to save the day. (yes, interleaved parsing
762+
/// / expansion / configuring would solve this problem...)
763+
764+
// NOTE: remove after next snapshot
765+
/// to be more specific: after a snapshot, swap out the "PRE" stuff, and
766+
// swap in the "POST" stuff.
767+
768+
/// PRE
769+
macro_rules! mf_method_body{
770+
($slf:ident, $field_pat:pat, $result:ident) => {
771+
match $slf.node {
772+
$field_pat => $result,
773+
MethMac(_) => {
774+
fail!("expected an AST without macro invocations");
775+
}
776+
}
777+
}
778+
}
779+
780+
/// POST
781+
/*
782+
#[cfg(not(stage0))]
783+
macro_rules! mf_method{
784+
($meth_name:ident, $field_ty:ty, $field_pat:pat, $result:ident) => {
785+
fn $meth_name<'a>(&'a self) -> $field_ty {
786+
match self.node {
755787
$field_pat => $result,
756788
MethMac(_) => {
757789
fail!("expected an AST without macro invocations");
758790
}
759791
}
760792
}
761793
}
794+
}*/
795+
796+
797+
// PRE
798+
impl PostExpansionMethod for Method {
799+
fn pe_ident(&self) -> ast::Ident {
800+
mf_method_body!(self,MethDecl(ident,_,_,_,_,_,_),ident)
801+
}
802+
fn pe_generics<'a>(&'a self) -> &'a ast::Generics {
803+
mf_method_body!(self,MethDecl(_,ref generics,_,_,_,_,_),generics)
804+
}
805+
fn pe_explicit_self<'a>(&'a self) -> &'a ast::ExplicitSelf {
806+
mf_method_body!(self,MethDecl(_,_,ref explicit_self,_,_,_,_),explicit_self)
807+
}
808+
fn pe_fn_style(&self) -> ast::FnStyle{
809+
mf_method_body!(self,MethDecl(_,_,_,fn_style,_,_,_),fn_style)
810+
}
811+
fn pe_fn_decl(&self) -> P<ast::FnDecl> {
812+
mf_method_body!(self,MethDecl(_,_,_,_,decl,_,_),decl)
813+
}
814+
fn pe_body(&self) -> P<ast::Block> {
815+
mf_method_body!(self,MethDecl(_,_,_,_,_,body,_),body)
816+
}
817+
fn pe_vis(&self) -> ast::Visibility {
818+
mf_method_body!(self,MethDecl(_,_,_,_,_,_,vis),vis)
819+
}
762820
}
763821

764-
// Note: this is unhygienic in the lifetime 'a. In order to fix this, we'd have to
765-
// add :lifetime as a macro argument type, so that the 'a could be supplied by the macro
766-
// invocation.
767-
pub method_field_extractor!(method_ident,ast::Ident,MethDecl(ident,_,_,_,_,_,_),ident)
768-
pub method_field_extractor!(method_generics,&'a ast::Generics,
769-
MethDecl(_,ref generics,_,_,_,_,_),generics)
770-
pub method_field_extractor!(method_explicit_self,&'a ast::ExplicitSelf,
771-
MethDecl(_,_,ref explicit_self,_,_,_,_),explicit_self)
772-
pub method_field_extractor!(method_fn_style,ast::FnStyle,MethDecl(_,_,_,fn_style,_,_,_),fn_style)
773-
pub method_field_extractor!(method_fn_decl,P<ast::FnDecl>,MethDecl(_,_,_,_,decl,_,_),decl)
774-
pub method_field_extractor!(method_body,P<ast::Block>,MethDecl(_,_,_,_,_,body,_),body)
775-
pub method_field_extractor!(method_vis,ast::Visibility,MethDecl(_,_,_,_,_,_,vis),vis)
822+
// POST
823+
/*
824+
#[cfg(not(stage0))]
825+
impl PostExpansionMethod for Method {
826+
mf_method!(pe_ident,ast::Ident,MethDecl(ident,_,_,_,_,_,_),ident)
827+
mf_method!(pe_generics,&'a ast::Generics,
828+
MethDecl(_,ref generics,_,_,_,_,_),generics)
829+
mf_method!(pe_explicit_self,&'a ast::ExplicitSelf,
830+
MethDecl(_,_,ref explicit_self,_,_,_,_),explicit_self)
831+
mf_method!(pe_fn_style,ast::FnStyle,MethDecl(_,_,_,fn_style,_,_,_),fn_style)
832+
mf_method!(pe_fn_decl,P<ast::FnDecl>,MethDecl(_,_,_,_,decl,_,_),decl)
833+
mf_method!(pe_body,P<ast::Block>,MethDecl(_,_,_,_,_,body,_),body)
834+
mf_method!(pe_vis,ast::Visibility,MethDecl(_,_,_,_,_,_,vis),vis)
835+
}
836+
*/
776837

777838
#[cfg(test)]
778839
mod test {
@@ -799,4 +860,3 @@ mod test {
799860
.iter().map(ident_to_segment).collect::<Vec<PathSegment>>().as_slice()));
800861
}
801862
}
802-

0 commit comments

Comments
 (0)