@@ -2,7 +2,7 @@ use std::convert::{Infallible, identity};
22use unwrap_infallible:: UnwrapInfallible ;
33
44use super :: {
5- Checkpoint , ErrProof , Parser , Recovery , define_scope,
5+ Checkpoint , ErrProof , Parser , Recovery , TextSize , define_scope,
66 expr_atom:: { self , is_expr_atom_head} ,
77 param:: { CallArgListScope , GenericArgListScope } ,
88 path:: is_qualified_type,
@@ -61,13 +61,21 @@ fn parse_expr_with_min_bp<S: TokenStream>(
6161 && has_line_break_before ( parser)
6262 && !is_aug_assign ( parser)
6363 {
64+ let range = line_start_op_range ( parser) ;
6465 parser. add_error ( ParseError :: Msg (
6566 "line-start `-` after an expression is ambiguous; move `-` to the previous line for subtraction or parenthesize explicitly"
6667 . to_string ( ) ,
67- TextRange :: empty ( parser . end_of_prev_token ) ,
68+ range ,
6869 ) ) ;
6970 break ;
7071 }
72+ if min_bp == 0
73+ && kind == SyntaxKind :: Lt
74+ && has_line_break_before ( parser)
75+ && is_line_start_qualified_type ( parser)
76+ {
77+ break ;
78+ }
7179
7280 // Parse postfix operators.
7381 match postfix_binding_power ( parser) {
@@ -201,10 +209,6 @@ fn infix_binding_power<S: TokenStream>(parser: &mut Parser<S>) -> Option<(u8, u8
201209 Amp2 => ( 60 , 61 ) ,
202210 NotEq | Eq2 => ( 70 , 71 ) ,
203211 Lt => {
204- if has_line_break_before ( parser) && is_qualified_type ( parser) {
205- parser. set_newline_as_trivia ( is_trivia) ;
206- return None ;
207- }
208212 if is_lshift ( parser) {
209213 ( 110 , 111 )
210214 } else {
@@ -495,6 +499,26 @@ fn has_line_break_before<S: TokenStream>(parser: &mut Parser<S>) -> bool {
495499 has_line_break
496500}
497501
502+ fn is_line_start_qualified_type < S : TokenStream > ( parser : & mut Parser < S > ) -> bool {
503+ let nt = parser. set_newline_as_trivia ( true ) ;
504+ let is_qualified = parser. current_kind ( ) == Some ( SyntaxKind :: Lt ) && is_qualified_type ( parser) ;
505+ parser. set_newline_as_trivia ( nt) ;
506+ is_qualified
507+ }
508+
509+ fn line_start_op_range < S : TokenStream > ( parser : & mut Parser < S > ) -> TextRange {
510+ parser. dry_run ( |parser| {
511+ let nt = parser. set_newline_as_trivia ( true ) ;
512+ parser. bump_trivias ( ) ;
513+ let start = parser. current_pos ;
514+ let end = parser
515+ . current_token ( )
516+ . map_or ( start, |current_token| start + current_token. text_size ( ) ) ;
517+ parser. set_newline_as_trivia ( nt) ;
518+ TextRange :: new ( start, end)
519+ } )
520+ }
521+
498522fn bump_bin_op < S : TokenStream > ( parser : & mut Parser < S > ) {
499523 match parser. current_kind ( ) {
500524 Some ( SyntaxKind :: Lt ) => {
0 commit comments