@@ -1445,40 +1445,86 @@ where
14451445}
14461446
14471447/// See [`Parser::delimited_by`].
1448- pub struct DelimitedBy < A , B , C , OB , OC > {
1448+ pub struct DelimitedBy < A , B , C , OB , OC , D = crate :: primitive :: Never , OD = Infallible > {
14491449 pub ( crate ) parser : A ,
14501450 pub ( crate ) start : B ,
14511451 pub ( crate ) end : C ,
1452+ pub ( crate ) invalid_end : D ,
14521453 #[ allow( dead_code) ]
1453- pub ( crate ) phantom : EmptyPhantom < ( OB , OC ) > ,
1454+ pub ( crate ) phantom : EmptyPhantom < ( OB , OC , OD ) > ,
14541455}
14551456
1456- impl < A : Copy , B : Copy , C : Copy , OB , OC > Copy for DelimitedBy < A , B , C , OB , OC > { }
1457- impl < A : Clone , B : Clone , C : Clone , OB , OC > Clone for DelimitedBy < A , B , C , OB , OC > {
1457+ impl < A : Copy , B : Copy , C : Copy , OB , OC , D : Copy , OD > Copy for DelimitedBy < A , B , C , OB , OC , D , OD > { }
1458+ impl < A : Clone , B : Clone , C : Clone , OB , OC , D : Clone , OD > Clone
1459+ for DelimitedBy < A , B , C , OB , OC , D , OD >
1460+ {
14581461 fn clone ( & self ) -> Self {
14591462 Self {
14601463 parser : self . parser . clone ( ) ,
14611464 start : self . start . clone ( ) ,
14621465 end : self . end . clone ( ) ,
1466+ invalid_end : self . invalid_end . clone ( ) ,
1467+ phantom : EmptyPhantom :: new ( ) ,
1468+ }
1469+ }
1470+ }
1471+
1472+ impl < A , B , C , OB , OC , D , OD > DelimitedBy < A , B , C , OB , OC , D , OD > {
1473+ /// Indicate that when the given mismatched pattern is found, errors should be marked as 'unclosed delimiters'.
1474+ ///
1475+ /// This can result in improved error messages in certain cases.
1476+ pub fn with_mismatched_end < D2 , OD2 > ( self , end : D2 ) -> DelimitedBy < A , B , C , OB , OC , D2 , OD2 > {
1477+ DelimitedBy {
1478+ parser : self . parser ,
1479+ start : self . start ,
1480+ end : self . end ,
1481+ invalid_end : end,
14631482 phantom : EmptyPhantom :: new ( ) ,
14641483 }
14651484 }
14661485}
14671486
1468- impl < ' src , I , E , A , B , C , OA , OB , OC > Parser < ' src , I , OA , E > for DelimitedBy < A , B , C , OB , OC >
1487+ impl < ' src , I , E , A , B , C , OA , OB , OC , D , OD > Parser < ' src , I , OA , E >
1488+ for DelimitedBy < A , B , C , OB , OC , D , OD >
14691489where
14701490 I : Input < ' src > ,
14711491 E : ParserExtra < ' src , I > ,
14721492 A : Parser < ' src , I , OA , E > ,
14731493 B : Parser < ' src , I , OB , E > ,
14741494 C : Parser < ' src , I , OC , E > ,
1495+ D : Parser < ' src , I , OD , E > ,
1496+ I :: Span : Clone ,
14751497{
14761498 #[ inline( always) ]
14771499 fn go < M : Mode > ( & self , inp : & mut InputRef < ' src , ' _ , I , E > ) -> PResult < M , OA > {
1500+ let before_start = inp. cursor ( ) ;
14781501 self . start . go :: < Check > ( inp) ?;
1502+ let start_span = inp. span_since ( & before_start) ;
14791503 let a = self . parser . go :: < M > ( inp) ?;
1480- self . end . go :: < Check > ( inp) ?;
1481- Ok ( a)
1504+ // let before_errors = inp.errors.secondary.len();
1505+ let before_end = inp. save ( ) ;
1506+ let old_alt = inp. take_alt ( ) ;
1507+ let scope_span = inp. span_since ( & before_start) ;
1508+ let end_res = self . end . go :: < Check > ( inp) ;
1509+ let res = if end_res. is_err ( ) {
1510+ let mut new_alt = inp. take_alt ( ) . expect ( "error, but no alt" ) ;
1511+ inp. rewind ( before_end) ;
1512+ if self . invalid_end . go :: < Check > ( inp) . is_ok ( ) {
1513+ new_alt
1514+ . err
1515+ . in_delimited ( start_span. clone ( ) , scope_span. clone ( ) ) ;
1516+ }
1517+ inp. errors . alt = old_alt;
1518+ inp. add_alt_err ( & new_alt. pos , new_alt. err ) ;
1519+ Err ( ( ) )
1520+ } else {
1521+ inp. errors . alt = old_alt;
1522+ Ok ( a)
1523+ } ;
1524+ // for err in inp.errors.secondary_errors_since(before_errors) {
1525+ // err.err.in_delimited(start_span.clone(), scope_span.clone());
1526+ // }
1527+ res
14821528 }
14831529
14841530 go_extra ! ( OA ) ;
0 commit comments