@@ -785,7 +785,7 @@ fn check_matcher_core(sess: &ParseSess,
785
785
// against SUFFIX
786
786
continue ' each_token;
787
787
}
788
- TokenTree :: Sequence ( sp , ref seq_rep) => {
788
+ TokenTree :: Sequence ( delim_sp , ref seq_rep) => {
789
789
suffix_first = build_suffix_first ( ) ;
790
790
// The trick here: when we check the interior, we want
791
791
// to include the separator (if any) as a potential
@@ -800,16 +800,16 @@ fn check_matcher_core(sess: &ParseSess,
800
800
let mut new;
801
801
let my_suffix = if let Some ( ref u) = seq_rep. separator {
802
802
new = suffix_first. clone ( ) ;
803
- new. add_one_maybe ( TokenTree :: Token ( sp . entire ( ) , u. clone ( ) ) ) ;
803
+ new. add_one_maybe ( TokenTree :: Token ( delim_sp . entire ( ) , u. clone ( ) ) ) ;
804
804
& new
805
805
} else {
806
806
if let (
807
807
Some ( tok) ,
808
808
Some ( TokenTree :: MetaVarDecl ( sp, name, frag_spec) ) ,
809
809
) = ( seq_rep. tts . first ( ) , seq_rep. tts . last ( ) ) {
810
810
match is_in_follow ( tok, & frag_spec. as_str ( ) ) {
811
- Err ( _ ) | Ok ( true ) => { } // handled elsewhere
812
- Ok ( false ) => {
811
+ IsInFollow :: Invalid ( .. ) | IsInFollow :: Yes => { } // handled elsewhere
812
+ IsInFollow :: No ( possible ) => {
813
813
let tok_sp = tok. span ( ) ;
814
814
let next = if * sp == tok_sp {
815
815
"itself" . to_owned ( )
@@ -843,6 +843,49 @@ fn check_matcher_core(sess: &ParseSess,
843
843
"this is the first fragment in the evaluated repetition" ,
844
844
) ;
845
845
}
846
+ let sugg_span = sess. source_map ( ) . next_point ( delim_sp. close ) ;
847
+ let msg = "allowed there are: " ;
848
+ let sugg_msg = "add a valid separator for the repetition to be \
849
+ unambiguous";
850
+ match & possible[ ..] {
851
+ & [ ] => { }
852
+ & [ t] => {
853
+ err. note ( & format ! (
854
+ "only {} is allowed after `{}` fragments" ,
855
+ t,
856
+ frag_spec,
857
+ ) ) ;
858
+ if t. starts_with ( '`' ) && t. ends_with ( '`' ) {
859
+ err. span_suggestion_with_applicability (
860
+ sugg_span,
861
+ & format ! ( "{}, for example" , sugg_msg) ,
862
+ ( & t[ 1 ..t. len ( ) -1 ] ) . to_owned ( ) ,
863
+ Applicability :: MaybeIncorrect ,
864
+ ) ;
865
+ } else {
866
+ err. note ( sugg_msg) ;
867
+ }
868
+ }
869
+ ts => {
870
+ err. note ( & format ! (
871
+ "{}{} or {}" ,
872
+ msg,
873
+ ts[ ..ts. len( ) - 1 ] . iter( ) . map( |s| * s)
874
+ . collect:: <Vec <_>>( ) . join( ", " ) ,
875
+ ts[ ts. len( ) - 1 ] ,
876
+ ) ) ;
877
+ if ts[ 0 ] . starts_with ( '`' ) && ts[ 0 ] . ends_with ( '`' ) {
878
+ err. span_suggestion_with_applicability (
879
+ sugg_span,
880
+ & format ! ( "{}, for example" , sugg_msg) ,
881
+ ( & ts[ 0 ] [ 1 ..ts[ 0 ] . len ( ) -1 ] ) . to_owned ( ) ,
882
+ Applicability :: MaybeIncorrect ,
883
+ ) ;
884
+ } else {
885
+ err. note ( sugg_msg) ;
886
+ }
887
+ }
888
+ }
846
889
err. emit ( ) ;
847
890
}
848
891
}
@@ -1007,7 +1050,7 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> IsInFollow {
1007
1050
IsInFollow :: Yes
1008
1051
} ,
1009
1052
"stmt" | "expr" => {
1010
- let tokens = vec ! [ "`=> `" , "`, `" , "`; `" ] ;
1053
+ let tokens = vec ! [ "`; `" , "`=> `" , "`, `" ] ;
1011
1054
match * tok {
1012
1055
TokenTree :: Token ( _, ref tok) => match * tok {
1013
1056
FatArrow | Comma | Semi => IsInFollow :: Yes ,
@@ -1029,7 +1072,7 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> IsInFollow {
1029
1072
} ,
1030
1073
"path" | "ty" => {
1031
1074
let tokens = vec ! [
1032
- "`{ `" , "`[ `" , "`=> `" , "`, `" , "`>`" , "`=`" , "`:`" , "`;`" , "`|`" , "`as`" ,
1075
+ "`, `" , "`{ `" , "`[ `" , "`=> `" , "`>`" , "`=`" , "`:`" , "`;`" , "`|`" , "`as`" ,
1033
1076
"`where`" ,
1034
1077
] ;
1035
1078
match * tok {
0 commit comments