@@ -21,18 +21,14 @@ use rustc_parse::parser::Parser;
21
21
use rustc_session:: parse:: ParseSess ;
22
22
use rustc_span:: edition:: Edition ;
23
23
use rustc_span:: hygiene:: Transparency ;
24
- use rustc_span:: symbol:: { kw, sym, Ident , MacroRulesNormalizedIdent , Symbol } ;
24
+ use rustc_span:: symbol:: { kw, sym, Ident , MacroRulesNormalizedIdent } ;
25
25
use rustc_span:: Span ;
26
26
27
27
use log:: debug;
28
28
use std:: borrow:: Cow ;
29
29
use std:: collections:: hash_map:: Entry ;
30
30
use std:: { mem, slice} ;
31
31
32
- const VALID_FRAGMENT_NAMES_MSG : & str = "valid fragment specifiers are \
33
- `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \
34
- `literal`, `path`, `meta`, `tt`, `item` and `vis`";
35
-
36
32
crate struct ParserAnyMacro < ' a > {
37
33
parser : Parser < ' a > ,
38
34
@@ -403,7 +399,7 @@ pub fn compile_declarative_macro(
403
399
let diag = & sess. span_diagnostic ;
404
400
let lhs_nm = Ident :: new ( sym:: lhs, def. span ) ;
405
401
let rhs_nm = Ident :: new ( sym:: rhs, def. span ) ;
406
- let tt_spec = Ident :: new ( sym :: tt , def . span ) ;
402
+ let tt_spec = Some ( NonterminalKind :: TT ) ;
407
403
408
404
// Parse the macro_rules! invocation
409
405
let ( macro_rules, body) = match & def. kind {
@@ -571,7 +567,7 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
571
567
TokenTree :: Sequence ( span, ref seq) => {
572
568
if seq. separator . is_none ( )
573
569
&& seq. tts . iter ( ) . all ( |seq_tt| match * seq_tt {
574
- TokenTree :: MetaVarDecl ( _, _, id ) => id . name == sym :: vis ,
570
+ TokenTree :: MetaVarDecl ( _, _, Some ( NonterminalKind :: Vis ) ) => true ,
575
571
TokenTree :: Sequence ( _, ref sub_seq) => {
576
572
sub_seq. kleene . op == mbe:: KleeneOp :: ZeroOrMore
577
573
|| sub_seq. kleene . op == mbe:: KleeneOp :: ZeroOrOne
@@ -890,21 +886,7 @@ fn check_matcher_core(
890
886
// of NT tokens that might end the sequence `... token`.
891
887
match * token {
892
888
TokenTree :: Token ( ..) | TokenTree :: MetaVar ( ..) | TokenTree :: MetaVarDecl ( ..) => {
893
- let can_be_followed_by_any;
894
- if let Err ( bad_frag) = has_legal_fragment_specifier ( sess, features, attrs, token) {
895
- let msg = format ! ( "invalid fragment specifier `{}`" , bad_frag) ;
896
- sess. span_diagnostic
897
- . struct_span_err ( token. span ( ) , & msg)
898
- . help ( VALID_FRAGMENT_NAMES_MSG )
899
- . emit ( ) ;
900
- // (This eliminates false positives and duplicates
901
- // from error messages.)
902
- can_be_followed_by_any = true ;
903
- } else {
904
- can_be_followed_by_any = token_can_be_followed_by_any ( token) ;
905
- }
906
-
907
- if can_be_followed_by_any {
889
+ if token_can_be_followed_by_any ( token) {
908
890
// don't need to track tokens that work with any,
909
891
last. replace_with_irrelevant ( ) ;
910
892
// ... and don't need to check tokens that can be
@@ -967,19 +949,10 @@ fn check_matcher_core(
967
949
968
950
// Now `last` holds the complete set of NT tokens that could
969
951
// end the sequence before SUFFIX. Check that every one works with `suffix`.
970
- ' each_last : for token in & last. tokens {
971
- if let TokenTree :: MetaVarDecl ( _, name, frag_spec ) = * token {
952
+ for token in & last. tokens {
953
+ if let TokenTree :: MetaVarDecl ( _, name, Some ( kind ) ) = * token {
972
954
for next_token in & suffix_first. tokens {
973
- match is_in_follow ( next_token, frag_spec. name ) {
974
- IsInFollow :: Invalid ( msg, help) => {
975
- sess. span_diagnostic
976
- . struct_span_err ( next_token. span ( ) , & msg)
977
- . help ( help)
978
- . emit ( ) ;
979
- // don't bother reporting every source of
980
- // conflict for a particular element of `last`.
981
- continue ' each_last;
982
- }
955
+ match is_in_follow ( next_token, kind) {
983
956
IsInFollow :: Yes => { }
984
957
IsInFollow :: No ( possible) => {
985
958
let may_be = if last. tokens . len ( ) == 1 && suffix_first. tokens . len ( ) == 1
@@ -996,22 +969,19 @@ fn check_matcher_core(
996
969
"`${name}:{frag}` {may_be} followed by `{next}`, which \
997
970
is not allowed for `{frag}` fragments",
998
971
name = name,
999
- frag = frag_spec ,
972
+ frag = kind ,
1000
973
next = quoted_tt_to_string( next_token) ,
1001
974
may_be = may_be
1002
975
) ,
1003
976
) ;
1004
- err. span_label (
1005
- sp,
1006
- format ! ( "not allowed after `{}` fragments" , frag_spec) ,
1007
- ) ;
977
+ err. span_label ( sp, format ! ( "not allowed after `{}` fragments" , kind) ) ;
1008
978
let msg = "allowed there are: " ;
1009
979
match possible {
1010
980
& [ ] => { }
1011
981
& [ t] => {
1012
982
err. note ( & format ! (
1013
983
"only {} is allowed after `{}` fragments" ,
1014
- t, frag_spec ,
984
+ t, kind ,
1015
985
) ) ;
1016
986
}
1017
987
ts => {
@@ -1038,8 +1008,8 @@ fn check_matcher_core(
1038
1008
}
1039
1009
1040
1010
fn token_can_be_followed_by_any ( tok : & mbe:: TokenTree ) -> bool {
1041
- if let mbe:: TokenTree :: MetaVarDecl ( _, _, frag_spec ) = * tok {
1042
- frag_can_be_followed_by_any ( frag_spec . name )
1011
+ if let mbe:: TokenTree :: MetaVarDecl ( _, _, Some ( kind ) ) = * tok {
1012
+ frag_can_be_followed_by_any ( kind )
1043
1013
} else {
1044
1014
// (Non NT's can always be followed by anything in matchers.)
1045
1015
true
@@ -1054,26 +1024,23 @@ fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool {
1054
1024
/// specifier which consumes at most one token tree can be followed by
1055
1025
/// a fragment specifier (indeed, these fragments can be followed by
1056
1026
/// ANYTHING without fear of future compatibility hazards).
1057
- fn frag_can_be_followed_by_any ( frag : Symbol ) -> bool {
1058
- match frag {
1059
- sym:: item | // always terminated by `}` or `;`
1060
- sym:: block | // exactly one token tree
1061
- sym:: ident | // exactly one token tree
1062
- sym:: literal | // exactly one token tree
1063
- sym:: meta | // exactly one token tree
1064
- sym:: lifetime | // exactly one token tree
1065
- sym:: tt => // exactly one token tree
1066
- true ,
1067
-
1068
- _ =>
1069
- false ,
1027
+ fn frag_can_be_followed_by_any ( kind : NonterminalKind ) -> bool {
1028
+ match kind {
1029
+ NonterminalKind :: Item // always terminated by `}` or `;`
1030
+ | NonterminalKind :: Block // exactly one token tree
1031
+ | NonterminalKind :: Ident // exactly one token tree
1032
+ | NonterminalKind :: Literal // exactly one token tree
1033
+ | NonterminalKind :: Meta // exactly one token tree
1034
+ | NonterminalKind :: Lifetime // exactly one token tree
1035
+ | NonterminalKind :: TT => true , // exactly one token tree
1036
+
1037
+ _ => false ,
1070
1038
}
1071
1039
}
1072
1040
1073
1041
enum IsInFollow {
1074
1042
Yes ,
1075
1043
No ( & ' static [ & ' static str ] ) ,
1076
- Invalid ( String , & ' static str ) ,
1077
1044
}
1078
1045
1079
1046
/// Returns `true` if `frag` can legally be followed by the token `tok`. For
@@ -1084,26 +1051,26 @@ enum IsInFollow {
1084
1051
/// break macros that were relying on that binary operator as a
1085
1052
/// separator.
1086
1053
// when changing this do not forget to update doc/book/macros.md!
1087
- fn is_in_follow ( tok : & mbe:: TokenTree , frag : Symbol ) -> IsInFollow {
1054
+ fn is_in_follow ( tok : & mbe:: TokenTree , kind : NonterminalKind ) -> IsInFollow {
1088
1055
use mbe:: TokenTree ;
1089
1056
1090
1057
if let TokenTree :: Token ( Token { kind : token:: CloseDelim ( _) , .. } ) = * tok {
1091
1058
// closing a token tree can never be matched by any fragment;
1092
1059
// iow, we always require that `(` and `)` match, etc.
1093
1060
IsInFollow :: Yes
1094
1061
} else {
1095
- match frag {
1096
- sym :: item => {
1062
+ match kind {
1063
+ NonterminalKind :: Item => {
1097
1064
// since items *must* be followed by either a `;` or a `}`, we can
1098
1065
// accept anything after them
1099
1066
IsInFollow :: Yes
1100
1067
}
1101
- sym :: block => {
1068
+ NonterminalKind :: Block => {
1102
1069
// anything can follow block, the braces provide an easy boundary to
1103
1070
// maintain
1104
1071
IsInFollow :: Yes
1105
1072
}
1106
- sym :: stmt | sym :: expr => {
1073
+ NonterminalKind :: Stmt | NonterminalKind :: Expr => {
1107
1074
const TOKENS : & [ & str ] = & [ "`=>`" , "`,`" , "`;`" ] ;
1108
1075
match tok {
1109
1076
TokenTree :: Token ( token) => match token. kind {
@@ -1113,7 +1080,7 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow {
1113
1080
_ => IsInFollow :: No ( TOKENS ) ,
1114
1081
}
1115
1082
}
1116
- sym :: pat => {
1083
+ NonterminalKind :: Pat => {
1117
1084
const TOKENS : & [ & str ] = & [ "`=>`" , "`,`" , "`=`" , "`|`" , "`if`" , "`in`" ] ;
1118
1085
match tok {
1119
1086
TokenTree :: Token ( token) => match token. kind {
@@ -1124,7 +1091,7 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow {
1124
1091
_ => IsInFollow :: No ( TOKENS ) ,
1125
1092
}
1126
1093
}
1127
- sym :: path | sym :: ty => {
1094
+ NonterminalKind :: Path | NonterminalKind :: Ty => {
1128
1095
const TOKENS : & [ & str ] = & [
1129
1096
"`{`" , "`[`" , "`=>`" , "`,`" , "`>`" , "`=`" , "`:`" , "`;`" , "`|`" , "`as`" ,
1130
1097
"`where`" ,
@@ -1146,26 +1113,24 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow {
1146
1113
}
1147
1114
_ => IsInFollow :: No ( TOKENS ) ,
1148
1115
} ,
1149
- TokenTree :: MetaVarDecl ( _, _, frag) if frag. name == sym:: block => {
1150
- IsInFollow :: Yes
1151
- }
1116
+ TokenTree :: MetaVarDecl ( _, _, Some ( NonterminalKind :: Block ) ) => IsInFollow :: Yes ,
1152
1117
_ => IsInFollow :: No ( TOKENS ) ,
1153
1118
}
1154
1119
}
1155
- sym :: ident | sym :: lifetime => {
1120
+ NonterminalKind :: Ident | NonterminalKind :: Lifetime => {
1156
1121
// being a single token, idents and lifetimes are harmless
1157
1122
IsInFollow :: Yes
1158
1123
}
1159
- sym :: literal => {
1124
+ NonterminalKind :: Literal => {
1160
1125
// literals may be of a single token, or two tokens (negative numbers)
1161
1126
IsInFollow :: Yes
1162
1127
}
1163
- sym :: meta | sym :: tt => {
1128
+ NonterminalKind :: Meta | NonterminalKind :: TT => {
1164
1129
// being either a single token or a delimited sequence, tt is
1165
1130
// harmless
1166
1131
IsInFollow :: Yes
1167
1132
}
1168
- sym :: vis => {
1133
+ NonterminalKind :: Vis => {
1169
1134
// Explicitly disallow `priv`, on the off chance it comes back.
1170
1135
const TOKENS : & [ & str ] = & [ "`,`" , "an ident" , "a type" ] ;
1171
1136
match tok {
@@ -1180,62 +1145,24 @@ fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow {
1180
1145
}
1181
1146
}
1182
1147
} ,
1183
- TokenTree :: MetaVarDecl ( _, _, frag)
1184
- if frag. name == sym:: ident
1185
- || frag. name == sym:: ty
1186
- || frag. name == sym:: path =>
1187
- {
1188
- IsInFollow :: Yes
1189
- }
1148
+ TokenTree :: MetaVarDecl (
1149
+ _,
1150
+ _,
1151
+ Some ( NonterminalKind :: Ident | NonterminalKind :: Ty | NonterminalKind :: Path ) ,
1152
+ ) => IsInFollow :: Yes ,
1190
1153
_ => IsInFollow :: No ( TOKENS ) ,
1191
1154
}
1192
1155
}
1193
- kw:: Invalid => IsInFollow :: Yes ,
1194
- _ => IsInFollow :: Invalid (
1195
- format ! ( "invalid fragment specifier `{}`" , frag) ,
1196
- VALID_FRAGMENT_NAMES_MSG ,
1197
- ) ,
1198
1156
}
1199
1157
}
1200
1158
}
1201
1159
1202
- fn has_legal_fragment_specifier (
1203
- sess : & ParseSess ,
1204
- features : & Features ,
1205
- attrs : & [ ast:: Attribute ] ,
1206
- tok : & mbe:: TokenTree ,
1207
- ) -> Result < ( ) , String > {
1208
- debug ! ( "has_legal_fragment_specifier({:?})" , tok) ;
1209
- if let mbe:: TokenTree :: MetaVarDecl ( _, _, ref frag_spec) = * tok {
1210
- let frag_span = tok. span ( ) ;
1211
- if !is_legal_fragment_specifier ( sess, features, attrs, frag_spec. name , frag_span) {
1212
- return Err ( frag_spec. to_string ( ) ) ;
1213
- }
1214
- }
1215
- Ok ( ( ) )
1216
- }
1217
-
1218
- fn is_legal_fragment_specifier (
1219
- _sess : & ParseSess ,
1220
- _features : & Features ,
1221
- _attrs : & [ ast:: Attribute ] ,
1222
- frag_name : Symbol ,
1223
- _frag_span : Span ,
1224
- ) -> bool {
1225
- /*
1226
- * If new fragment specifiers are invented in nightly, `_sess`,
1227
- * `_features`, `_attrs`, and `_frag_span` will be useful here
1228
- * for checking against feature gates. See past versions of
1229
- * this function.
1230
- */
1231
- NonterminalKind :: from_symbol ( frag_name) . is_some ( ) || frag_name == kw:: Invalid
1232
- }
1233
-
1234
1160
fn quoted_tt_to_string ( tt : & mbe:: TokenTree ) -> String {
1235
1161
match * tt {
1236
1162
mbe:: TokenTree :: Token ( ref token) => pprust:: token_to_string ( & token) ,
1237
1163
mbe:: TokenTree :: MetaVar ( _, name) => format ! ( "${}" , name) ,
1238
- mbe:: TokenTree :: MetaVarDecl ( _, name, kind) => format ! ( "${}:{}" , name, kind) ,
1164
+ mbe:: TokenTree :: MetaVarDecl ( _, name, Some ( kind) ) => format ! ( "${}:{}" , name, kind) ,
1165
+ mbe:: TokenTree :: MetaVarDecl ( _, name, None ) => format ! ( "${}:" , name) ,
1239
1166
_ => panic ! (
1240
1167
"unexpected mbe::TokenTree::{{Sequence or Delimited}} \
1241
1168
in follow set checker"
0 commit comments