@@ -844,11 +844,23 @@ fn object_property(i: &mut TokenSlice) -> PResult<Node<ObjectProperty>> {
844844 ) )
845845 . parse_next ( i) ?;
846846 ignore_whitespace ( i) ;
847- let expr = expression
847+ let expr = match expression
848848 . context ( expected (
849849 "the value which you're setting the property to, e.g. in 'height: 4', the value is 4" ,
850850 ) )
851- . parse_next ( i) ?;
851+ . parse_next ( i)
852+ {
853+ Ok ( expr) => expr,
854+ Err ( _) => {
855+ return Err ( ErrMode :: Cut (
856+ CompilationError :: fatal (
857+ SourceRange :: from ( sep) ,
858+ "This property has a label, but no value. Put some value after the equals sign" ,
859+ )
860+ . into ( ) ,
861+ ) ) ;
862+ }
863+ } ;
852864
853865 let result = Node {
854866 start : key. start ,
@@ -2810,7 +2822,7 @@ fn fn_call_kw(i: &mut TokenSlice) -> PResult<Node<CallExpressionKw>> {
28102822 ignore_whitespace ( i) ;
28112823
28122824 #[ allow( clippy:: large_enum_variant) ]
2813- pub enum ArgPlace {
2825+ enum ArgPlace {
28142826 NonCode ( Node < NonCodeNode > ) ,
28152827 LabeledArg ( LabeledArg ) ,
28162828 UnlabeledArg ( Expr ) ,
@@ -2827,22 +2839,34 @@ fn fn_call_kw(i: &mut TokenSlice) -> PResult<Node<CallExpressionKw>> {
28272839 . parse_next ( i) ?;
28282840 let ( args, non_code_nodes) : ( Vec < _ > , BTreeMap < usize , _ > ) = args. into_iter ( ) . enumerate ( ) . try_fold (
28292841 ( Vec :: new ( ) , BTreeMap :: new ( ) ) ,
2830- |( mut args, mut non_code_nodes) , ( i , e) | {
2842+ |( mut args, mut non_code_nodes) , ( index , e) | {
28312843 match e {
28322844 ArgPlace :: NonCode ( x) => {
2833- non_code_nodes. insert ( i , vec ! [ x] ) ;
2845+ non_code_nodes. insert ( index , vec ! [ x] ) ;
28342846 }
28352847 ArgPlace :: LabeledArg ( x) => {
28362848 args. push ( x) ;
28372849 }
28382850 ArgPlace :: UnlabeledArg ( arg) => {
2839- return Err ( ErrMode :: Cut (
2840- CompilationError :: fatal (
2841- SourceRange :: from ( arg) ,
2842- "This argument needs a label, but it doesn't have one" ,
2851+ let followed_by_equals = peek ( ( opt ( whitespace) , equals) ) . parse_next ( i) . is_ok ( ) ;
2852+ let err = if followed_by_equals {
2853+ ErrMode :: Cut (
2854+ CompilationError :: fatal (
2855+ SourceRange :: from ( arg) ,
2856+ "This argument has a label, but no value. Put some value after the equals sign" ,
2857+ )
2858+ . into ( ) ,
28432859 )
2844- . into ( ) ,
2845- ) ) ;
2860+ } else {
2861+ ErrMode :: Cut (
2862+ CompilationError :: fatal (
2863+ SourceRange :: from ( arg) ,
2864+ "This argument needs a label, but it doesn't have one" ,
2865+ )
2866+ . into ( ) ,
2867+ )
2868+ } ;
2869+ return Err ( err) ;
28462870 }
28472871 }
28482872 Ok ( ( args, non_code_nodes) )
@@ -4678,6 +4702,42 @@ baz = 2
46784702 ) ;
46794703 }
46804704 }
4705+
4706+ #[ test]
4707+ fn test_sensible_error_when_missing_rhs_of_kw_arg ( ) {
4708+ for ( i, program) in [ "f(x, y=)" ] . into_iter ( ) . enumerate ( ) {
4709+ let tokens = crate :: parsing:: token:: lex ( program, ModuleId :: default ( ) ) . unwrap ( ) ;
4710+ let err = fn_call_kw. parse ( tokens. as_slice ( ) ) . unwrap_err ( ) ;
4711+ let cause = err. inner ( ) . cause . as_ref ( ) . unwrap ( ) ;
4712+ assert_eq ! (
4713+ cause. message, "This argument has a label, but no value. Put some value after the equals sign" ,
4714+ "failed test {i}: {program}"
4715+ ) ;
4716+ assert_eq ! (
4717+ cause. source_range. start( ) ,
4718+ program. find( "y" ) . unwrap( ) ,
4719+ "failed test {i}: {program}"
4720+ ) ;
4721+ }
4722+ }
4723+
4724+ #[ test]
4725+ fn test_sensible_error_when_missing_rhs_of_obj_property ( ) {
4726+ for ( i, program) in [ "{x = 1, y =}" ] . into_iter ( ) . enumerate ( ) {
4727+ let tokens = crate :: parsing:: token:: lex ( program, ModuleId :: default ( ) ) . unwrap ( ) ;
4728+ let err = object. parse ( tokens. as_slice ( ) ) . unwrap_err ( ) ;
4729+ let cause = err. inner ( ) . cause . as_ref ( ) . unwrap ( ) ;
4730+ assert_eq ! (
4731+ cause. message, "This property has a label, but no value. Put some value after the equals sign" ,
4732+ "failed test {i}: {program}"
4733+ ) ;
4734+ assert_eq ! (
4735+ cause. source_range. start( ) ,
4736+ program. rfind( '=' ) . unwrap( ) ,
4737+ "failed test {i}: {program}"
4738+ ) ;
4739+ }
4740+ }
46814741}
46824742
46834743#[ cfg( test) ]
0 commit comments