@@ -757,7 +757,7 @@ fn check_matcher_core(sess: &ParseSess,
757
757
// against SUFFIX
758
758
continue ' each_token;
759
759
}
760
- TokenTree :: Sequence ( sp , ref seq_rep) => {
760
+ TokenTree :: Sequence ( delim_sp , ref seq_rep) => {
761
761
suffix_first = build_suffix_first ( ) ;
762
762
// The trick here: when we check the interior, we want
763
763
// to include the separator (if any) as a potential
@@ -772,16 +772,16 @@ fn check_matcher_core(sess: &ParseSess,
772
772
let mut new;
773
773
let my_suffix = if let Some ( ref u) = seq_rep. separator {
774
774
new = suffix_first. clone ( ) ;
775
- new. add_one_maybe ( TokenTree :: Token ( sp . entire ( ) , u. clone ( ) ) ) ;
775
+ new. add_one_maybe ( TokenTree :: Token ( delim_sp . entire ( ) , u. clone ( ) ) ) ;
776
776
& new
777
777
} else {
778
778
if let (
779
779
Some ( tok) ,
780
780
Some ( TokenTree :: MetaVarDecl ( sp, name, frag_spec) ) ,
781
781
) = ( seq_rep. tts . first ( ) , seq_rep. tts . last ( ) ) {
782
782
match is_in_follow ( tok, & frag_spec. as_str ( ) ) {
783
- Err ( _ ) | Ok ( true ) => { } // handled elsewhere
784
- Ok ( false ) => {
783
+ IsInFollow :: Invalid ( .. ) | IsInFollow :: Yes => { } // handled elsewhere
784
+ IsInFollow :: No ( possible ) => {
785
785
let tok_sp = tok. span ( ) ;
786
786
let next = if * sp == tok_sp {
787
787
"itself" . to_owned ( )
@@ -815,6 +815,49 @@ fn check_matcher_core(sess: &ParseSess,
815
815
"this is the first fragment in the evaluated repetition" ,
816
816
) ;
817
817
}
818
+ let sugg_span = sess. source_map ( ) . next_point ( delim_sp. close ) ;
819
+ let msg = "allowed there are: " ;
820
+ let sugg_msg = "add a valid separator for the repetition to be \
821
+ unambiguous";
822
+ match & possible[ ..] {
823
+ & [ ] => { }
824
+ & [ t] => {
825
+ err. note ( & format ! (
826
+ "only {} is allowed after `{}` fragments" ,
827
+ t,
828
+ frag_spec,
829
+ ) ) ;
830
+ if t. starts_with ( '`' ) && t. ends_with ( '`' ) {
831
+ err. span_suggestion_with_applicability (
832
+ sugg_span,
833
+ & format ! ( "{}, for example" , sugg_msg) ,
834
+ ( & t[ 1 ..t. len ( ) -1 ] ) . to_owned ( ) ,
835
+ Applicability :: MaybeIncorrect ,
836
+ ) ;
837
+ } else {
838
+ err. note ( sugg_msg) ;
839
+ }
840
+ }
841
+ ts => {
842
+ err. note ( & format ! (
843
+ "{}{} or {}" ,
844
+ msg,
845
+ ts[ ..ts. len( ) - 1 ] . iter( ) . map( |s| * s)
846
+ . collect:: <Vec <_>>( ) . join( ", " ) ,
847
+ ts[ ts. len( ) - 1 ] ,
848
+ ) ) ;
849
+ if ts[ 0 ] . starts_with ( '`' ) && ts[ 0 ] . ends_with ( '`' ) {
850
+ err. span_suggestion_with_applicability (
851
+ sugg_span,
852
+ & format ! ( "{}, for example" , sugg_msg) ,
853
+ ( & ts[ 0 ] [ 1 ..ts[ 0 ] . len ( ) -1 ] ) . to_owned ( ) ,
854
+ Applicability :: MaybeIncorrect ,
855
+ ) ;
856
+ } else {
857
+ err. note ( sugg_msg) ;
858
+ }
859
+ }
860
+ }
818
861
err. emit ( ) ;
819
862
}
820
863
}
@@ -979,7 +1022,7 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> IsInFollow {
979
1022
IsInFollow :: Yes
980
1023
} ,
981
1024
"stmt" | "expr" => {
982
- let tokens = vec ! [ "`=> `" , "`, `" , "`; `" ] ;
1025
+ let tokens = vec ! [ "`; `" , "`=> `" , "`, `" ] ;
983
1026
match * tok {
984
1027
TokenTree :: Token ( _, ref tok) => match * tok {
985
1028
FatArrow | Comma | Semi => IsInFollow :: Yes ,
@@ -1001,7 +1044,7 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> IsInFollow {
1001
1044
} ,
1002
1045
"path" | "ty" => {
1003
1046
let tokens = vec ! [
1004
- "`{ `" , "`[ `" , "`=> `" , "`, `" , "`>`" , "`=`" , "`:`" , "`;`" , "`|`" , "`as`" ,
1047
+ "`, `" , "`{ `" , "`[ `" , "`=> `" , "`>`" , "`=`" , "`:`" , "`;`" , "`|`" , "`as`" ,
1005
1048
"`where`" ,
1006
1049
] ;
1007
1050
match * tok {
0 commit comments