@@ -785,7 +785,7 @@ fn check_matcher_core(sess: &ParseSess,
785785 // against SUFFIX
786786 continue ' each_token;
787787 }
788- TokenTree :: Sequence ( sp , ref seq_rep) => {
788+ TokenTree :: Sequence ( delim_sp , ref seq_rep) => {
789789 suffix_first = build_suffix_first ( ) ;
790790 // The trick here: when we check the interior, we want
791791 // to include the separator (if any) as a potential
@@ -800,16 +800,16 @@ fn check_matcher_core(sess: &ParseSess,
800800 let mut new;
801801 let my_suffix = if let Some ( ref u) = seq_rep. separator {
802802 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 ( ) ) ) ;
804804 & new
805805 } else {
806806 if let (
807807 Some ( tok) ,
808808 Some ( TokenTree :: MetaVarDecl ( sp, name, frag_spec) ) ,
809809 ) = ( seq_rep. tts . first ( ) , seq_rep. tts . last ( ) ) {
810810 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 ) => {
813813 let tok_sp = tok. span ( ) ;
814814 let next = if * sp == tok_sp {
815815 "itself" . to_owned ( )
@@ -843,6 +843,49 @@ fn check_matcher_core(sess: &ParseSess,
843843 "this is the first fragment in the evaluated repetition" ,
844844 ) ;
845845 }
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+ }
846889 err. emit ( ) ;
847890 }
848891 }
@@ -1007,7 +1050,7 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> IsInFollow {
10071050 IsInFollow :: Yes
10081051 } ,
10091052 "stmt" | "expr" => {
1010- let tokens = vec ! [ "`=> `" , "`, `" , "`; `" ] ;
1053+ let tokens = vec ! [ "`; `" , "`=> `" , "`, `" ] ;
10111054 match * tok {
10121055 TokenTree :: Token ( _, ref tok) => match * tok {
10131056 FatArrow | Comma | Semi => IsInFollow :: Yes ,
@@ -1029,7 +1072,7 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> IsInFollow {
10291072 } ,
10301073 "path" | "ty" => {
10311074 let tokens = vec ! [
1032- "`{ `" , "`[ `" , "`=> `" , "`, `" , "`>`" , "`=`" , "`:`" , "`;`" , "`|`" , "`as`" ,
1075+ "`, `" , "`{ `" , "`[ `" , "`=> `" , "`>`" , "`=`" , "`:`" , "`;`" , "`|`" , "`as`" ,
10331076 "`where`" ,
10341077 ] ;
10351078 match * tok {
0 commit comments