@@ -79,6 +79,9 @@ use thin_vec::ThinVec;
79
79
/// Provides the original input contents from the span
80
80
/// of a chain element with trailing spaces trimmed.
81
81
fn format_overflow_style ( span : Span , context : & RewriteContext < ' _ > ) -> Option < String > {
82
+ // TODO(ding-young): Currently returning None when the given span is out of the range
83
+ // covered by the snippet provider. If this is a common cause for internal
84
+ // rewrite failure, add a new enum variant and return RewriteError instead of None
82
85
context. snippet_provider . span_to_snippet ( span) . map ( |s| {
83
86
s. lines ( )
84
87
. map ( |l| l. trim_end ( ) )
@@ -92,12 +95,16 @@ fn format_chain_item(
92
95
context : & RewriteContext < ' _ > ,
93
96
rewrite_shape : Shape ,
94
97
allow_overflow : bool ,
95
- ) -> Option < String > {
98
+ ) -> RewriteResult {
96
99
if allow_overflow {
97
- item. rewrite ( context, rewrite_shape)
98
- . or_else ( || format_overflow_style ( item. span , context) )
100
+ // TODO(ding-young): Consider calling format_overflow_style()
101
+ // only when item.rewrite_result() returns RewriteError::ExceedsMaxWidth.
102
+ // It may be inappropriate to call format_overflow_style on other RewriteError
103
+ // since the current approach retries formatting if allow_overflow is true
104
+ item. rewrite_result ( context, rewrite_shape)
105
+ . or_else ( |_| format_overflow_style ( item. span , context) . unknown_error ( ) )
99
106
} else {
100
- item. rewrite ( context, rewrite_shape)
107
+ item. rewrite_result ( context, rewrite_shape)
101
108
}
102
109
}
103
110
@@ -134,17 +141,17 @@ pub(crate) fn rewrite_chain(
134
141
expr : & ast:: Expr ,
135
142
context : & RewriteContext < ' _ > ,
136
143
shape : Shape ,
137
- ) -> Option < String > {
144
+ ) -> RewriteResult {
138
145
let chain = Chain :: from_ast ( expr, context) ;
139
146
debug ! ( "rewrite_chain {:?} {:?}" , chain, shape) ;
140
147
141
148
// If this is just an expression with some `?`s, then format it trivially and
142
149
// return early.
143
150
if chain. children . is_empty ( ) {
144
- return chain. parent . rewrite ( context, shape) ;
151
+ return chain. parent . rewrite_result ( context, shape) ;
145
152
}
146
153
147
- chain. rewrite ( context, shape)
154
+ chain. rewrite_result ( context, shape)
148
155
}
149
156
150
157
#[ derive( Debug ) ]
@@ -524,6 +531,10 @@ impl Chain {
524
531
525
532
impl Rewrite for Chain {
526
533
fn rewrite ( & self , context : & RewriteContext < ' _ > , shape : Shape ) -> Option < String > {
534
+ self . rewrite_result ( context, shape) . ok ( )
535
+ }
536
+
537
+ fn rewrite_result ( & self , context : & RewriteContext < ' _ > , shape : Shape ) -> RewriteResult {
527
538
debug ! ( "rewrite chain {:?} {:?}" , self , shape) ;
528
539
529
540
let mut formatter = match context. config . indent_style ( ) {
@@ -537,17 +548,25 @@ impl Rewrite for Chain {
537
548
538
549
formatter. format_root ( & self . parent , context, shape) ?;
539
550
if let Some ( result) = formatter. pure_root ( ) {
540
- return wrap_str ( result, context. config . max_width ( ) , shape) ;
551
+ return wrap_str ( result, context. config . max_width ( ) , shape)
552
+ . max_width_error ( shape. width , self . parent . span ) ;
541
553
}
542
554
555
+ let first = self . children . first ( ) . unwrap_or ( & self . parent ) ;
556
+ let last = self . children . last ( ) . unwrap_or ( & self . parent ) ;
557
+ let children_span = mk_sp ( first. span . lo ( ) , last. span . hi ( ) ) ;
558
+ let full_span = self . parent . span . with_hi ( children_span. hi ( ) ) ;
559
+
543
560
// Decide how to layout the rest of the chain.
544
- let child_shape = formatter. child_shape ( context, shape) ?;
561
+ let child_shape = formatter
562
+ . child_shape ( context, shape)
563
+ . max_width_error ( shape. width , children_span) ?;
545
564
546
565
formatter. format_children ( context, child_shape) ?;
547
566
formatter. format_last_child ( context, shape, child_shape) ?;
548
567
549
568
let result = formatter. join_rewrites ( context, child_shape) ?;
550
- wrap_str ( result, context. config . max_width ( ) , shape)
569
+ wrap_str ( result, context. config . max_width ( ) , shape) . max_width_error ( shape . width , full_span )
551
570
}
552
571
}
553
572
@@ -569,16 +588,20 @@ trait ChainFormatter {
569
588
parent : & ChainItem ,
570
589
context : & RewriteContext < ' _ > ,
571
590
shape : Shape ,
572
- ) -> Option < ( ) > ;
591
+ ) -> Result < ( ) , RewriteError > ;
573
592
fn child_shape ( & self , context : & RewriteContext < ' _ > , shape : Shape ) -> Option < Shape > ;
574
- fn format_children ( & mut self , context : & RewriteContext < ' _ > , child_shape : Shape ) -> Option < ( ) > ;
593
+ fn format_children (
594
+ & mut self ,
595
+ context : & RewriteContext < ' _ > ,
596
+ child_shape : Shape ,
597
+ ) -> Result < ( ) , RewriteError > ;
575
598
fn format_last_child (
576
599
& mut self ,
577
600
context : & RewriteContext < ' _ > ,
578
601
shape : Shape ,
579
602
child_shape : Shape ,
580
- ) -> Option < ( ) > ;
581
- fn join_rewrites ( & self , context : & RewriteContext < ' _ > , child_shape : Shape ) -> Option < String > ;
603
+ ) -> Result < ( ) , RewriteError > ;
604
+ fn join_rewrites ( & self , context : & RewriteContext < ' _ > , child_shape : Shape ) -> RewriteResult ;
582
605
// Returns `Some` if the chain is only a root, None otherwise.
583
606
fn pure_root ( & mut self ) -> Option < String > ;
584
607
}
@@ -621,12 +644,16 @@ impl<'a> ChainFormatterShared<'a> {
621
644
}
622
645
}
623
646
624
- fn format_children ( & mut self , context : & RewriteContext < ' _ > , child_shape : Shape ) -> Option < ( ) > {
647
+ fn format_children (
648
+ & mut self ,
649
+ context : & RewriteContext < ' _ > ,
650
+ child_shape : Shape ,
651
+ ) -> Result < ( ) , RewriteError > {
625
652
for item in & self . children [ ..self . children . len ( ) - 1 ] {
626
653
let rewrite = format_chain_item ( item, context, child_shape, self . allow_overflow ) ?;
627
654
self . rewrites . push ( rewrite) ;
628
655
}
629
- Some ( ( ) )
656
+ Ok ( ( ) )
630
657
}
631
658
632
659
// Rewrite the last child. The last child of a chain requires special treatment. We need to
@@ -667,8 +694,8 @@ impl<'a> ChainFormatterShared<'a> {
667
694
context : & RewriteContext < ' _ > ,
668
695
shape : Shape ,
669
696
child_shape : Shape ,
670
- ) -> Option < ( ) > {
671
- let last = self . children . last ( ) ?;
697
+ ) -> Result < ( ) , RewriteError > {
698
+ let last = self . children . last ( ) . unknown_error ( ) ?;
672
699
let extendable = may_extend && last_line_extendable ( & self . rewrites [ 0 ] ) ;
673
700
let prev_last_line_width = last_line_width ( & self . rewrites [ 0 ] ) ;
674
701
@@ -692,11 +719,17 @@ impl<'a> ChainFormatterShared<'a> {
692
719
&& self . rewrites . iter ( ) . all ( |s| !s. contains ( '\n' ) )
693
720
&& one_line_budget > 0 ;
694
721
let last_shape = if all_in_one_line {
695
- shape. sub_width ( last. tries ) ?
722
+ shape
723
+ . sub_width ( last. tries )
724
+ . max_width_error ( shape. width , last. span ) ?
696
725
} else if extendable {
697
- child_shape. sub_width ( last. tries ) ?
726
+ child_shape
727
+ . sub_width ( last. tries )
728
+ . max_width_error ( child_shape. width , last. span ) ?
698
729
} else {
699
- child_shape. sub_width ( shape. rhs_overhead ( context. config ) + last. tries ) ?
730
+ child_shape
731
+ . sub_width ( shape. rhs_overhead ( context. config ) + last. tries )
732
+ . max_width_error ( child_shape. width , last. span ) ?
700
733
} ;
701
734
702
735
let mut last_subexpr_str = None ;
@@ -712,7 +745,7 @@ impl<'a> ChainFormatterShared<'a> {
712
745
} ;
713
746
714
747
if let Some ( one_line_shape) = one_line_shape {
715
- if let Some ( rw) = last. rewrite ( context, one_line_shape) {
748
+ if let Ok ( rw) = last. rewrite_result ( context, one_line_shape) {
716
749
// We allow overflowing here only if both of the following conditions match:
717
750
// 1. The entire chain fits in a single line except the last child.
718
751
// 2. `last_child_str.lines().count() >= 5`.
@@ -727,17 +760,18 @@ impl<'a> ChainFormatterShared<'a> {
727
760
// last child on its own line, and compare two rewrites to choose which is
728
761
// better.
729
762
let last_shape = child_shape
730
- . sub_width ( shape. rhs_overhead ( context. config ) + last. tries ) ?;
731
- match last. rewrite ( context, last_shape) {
732
- Some ( ref new_rw) if !could_fit_single_line => {
763
+ . sub_width ( shape. rhs_overhead ( context. config ) + last. tries )
764
+ . max_width_error ( child_shape. width , last. span ) ?;
765
+ match last. rewrite_result ( context, last_shape) {
766
+ Ok ( ref new_rw) if !could_fit_single_line => {
733
767
last_subexpr_str = Some ( new_rw. clone ( ) ) ;
734
768
}
735
- Some ( ref new_rw) if new_rw. lines ( ) . count ( ) >= line_count => {
769
+ Ok ( ref new_rw) if new_rw. lines ( ) . count ( ) >= line_count => {
736
770
last_subexpr_str = Some ( rw) ;
737
771
self . fits_single_line = could_fit_single_line && all_in_one_line;
738
772
}
739
- new_rw @ Some ( .. ) => {
740
- last_subexpr_str = new_rw;
773
+ Ok ( new_rw ) => {
774
+ last_subexpr_str = Some ( new_rw) ;
741
775
}
742
776
_ => {
743
777
last_subexpr_str = Some ( rw) ;
@@ -752,22 +786,28 @@ impl<'a> ChainFormatterShared<'a> {
752
786
let last_shape = if context. use_block_indent ( ) {
753
787
last_shape
754
788
} else {
755
- child_shape. sub_width ( shape. rhs_overhead ( context. config ) + last. tries ) ?
789
+ child_shape
790
+ . sub_width ( shape. rhs_overhead ( context. config ) + last. tries )
791
+ . max_width_error ( child_shape. width , last. span ) ?
756
792
} ;
757
793
758
- last_subexpr_str = last_subexpr_str. or_else ( || last. rewrite ( context, last_shape) ) ;
759
- self . rewrites . push ( last_subexpr_str?) ;
760
- Some ( ( ) )
794
+ let last_subexpr_str =
795
+ last_subexpr_str. unwrap_or ( last. rewrite_result ( context, last_shape) ?) ;
796
+ self . rewrites . push ( last_subexpr_str) ;
797
+ Ok ( ( ) )
761
798
}
762
799
763
- fn join_rewrites ( & self , context : & RewriteContext < ' _ > , child_shape : Shape ) -> Option < String > {
800
+ fn join_rewrites ( & self , context : & RewriteContext < ' _ > , child_shape : Shape ) -> RewriteResult {
764
801
let connector = if self . fits_single_line {
765
802
// Yay, we can put everything on one line.
766
803
Cow :: from ( "" )
767
804
} else {
768
805
// Use new lines.
769
806
if context. force_one_line_chain . get ( ) {
770
- return None ;
807
+ return Err ( RewriteError :: ExceedsMaxWidth {
808
+ configured_width : child_shape. width ,
809
+ span : self . children . last ( ) . unknown_error ( ) ?. span ,
810
+ } ) ;
771
811
}
772
812
child_shape. to_string_with_newline ( context. config )
773
813
} ;
@@ -786,7 +826,7 @@ impl<'a> ChainFormatterShared<'a> {
786
826
result. push_str ( rewrite) ;
787
827
}
788
828
789
- Some ( result)
829
+ Ok ( result)
790
830
}
791
831
}
792
832
@@ -811,8 +851,8 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
811
851
parent : & ChainItem ,
812
852
context : & RewriteContext < ' _ > ,
813
853
shape : Shape ,
814
- ) -> Option < ( ) > {
815
- let mut root_rewrite: String = parent. rewrite ( context, shape) ?;
854
+ ) -> Result < ( ) , RewriteError > {
855
+ let mut root_rewrite: String = parent. rewrite_result ( context, shape) ?;
816
856
817
857
let mut root_ends_with_block = parent. kind . is_block_like ( context, & root_rewrite) ;
818
858
let tab_width = context. config . tab_spaces ( ) . saturating_sub ( shape. offset ) ;
@@ -822,10 +862,12 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
822
862
if let ChainItemKind :: Comment ( ..) = item. kind {
823
863
break ;
824
864
}
825
- let shape = shape. offset_left ( root_rewrite. len ( ) ) ?;
826
- match & item. rewrite ( context, shape) {
827
- Some ( rewrite) => root_rewrite. push_str ( rewrite) ,
828
- None => break ,
865
+ let shape = shape
866
+ . offset_left ( root_rewrite. len ( ) )
867
+ . max_width_error ( shape. width , item. span ) ?;
868
+ match & item. rewrite_result ( context, shape) {
869
+ Ok ( rewrite) => root_rewrite. push_str ( rewrite) ,
870
+ Err ( _) => break ,
829
871
}
830
872
831
873
root_ends_with_block = last_line_extendable ( & root_rewrite) ;
@@ -837,15 +879,19 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
837
879
}
838
880
self . shared . rewrites . push ( root_rewrite) ;
839
881
self . root_ends_with_block = root_ends_with_block;
840
- Some ( ( ) )
882
+ Ok ( ( ) )
841
883
}
842
884
843
885
fn child_shape ( & self , context : & RewriteContext < ' _ > , shape : Shape ) -> Option < Shape > {
844
886
let block_end = self . root_ends_with_block ;
845
887
Some ( get_block_child_shape ( block_end, context, shape) )
846
888
}
847
889
848
- fn format_children ( & mut self , context : & RewriteContext < ' _ > , child_shape : Shape ) -> Option < ( ) > {
890
+ fn format_children (
891
+ & mut self ,
892
+ context : & RewriteContext < ' _ > ,
893
+ child_shape : Shape ,
894
+ ) -> Result < ( ) , RewriteError > {
849
895
self . shared . format_children ( context, child_shape)
850
896
}
851
897
@@ -854,12 +900,12 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
854
900
context : & RewriteContext < ' _ > ,
855
901
shape : Shape ,
856
902
child_shape : Shape ,
857
- ) -> Option < ( ) > {
903
+ ) -> Result < ( ) , RewriteError > {
858
904
self . shared
859
905
. format_last_child ( true , context, shape, child_shape)
860
906
}
861
907
862
- fn join_rewrites ( & self , context : & RewriteContext < ' _ > , child_shape : Shape ) -> Option < String > {
908
+ fn join_rewrites ( & self , context : & RewriteContext < ' _ > , child_shape : Shape ) -> RewriteResult {
863
909
self . shared . join_rewrites ( context, child_shape)
864
910
}
865
911
@@ -890,9 +936,9 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
890
936
parent : & ChainItem ,
891
937
context : & RewriteContext < ' _ > ,
892
938
shape : Shape ,
893
- ) -> Option < ( ) > {
939
+ ) -> Result < ( ) , RewriteError > {
894
940
let parent_shape = shape. visual_indent ( 0 ) ;
895
- let mut root_rewrite = parent. rewrite ( context, parent_shape) ?;
941
+ let mut root_rewrite = parent. rewrite_result ( context, parent_shape) ?;
896
942
let multiline = root_rewrite. contains ( '\n' ) ;
897
943
self . offset = if multiline {
898
944
last_line_width ( & root_rewrite) . saturating_sub ( shape. used_width ( ) )
@@ -904,18 +950,19 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
904
950
let item = & self . shared . children [ 0 ] ;
905
951
if let ChainItemKind :: Comment ( ..) = item. kind {
906
952
self . shared . rewrites . push ( root_rewrite) ;
907
- return Some ( ( ) ) ;
953
+ return Ok ( ( ) ) ;
908
954
}
909
955
let child_shape = parent_shape
910
956
. visual_indent ( self . offset )
911
- . sub_width ( self . offset ) ?;
912
- let rewrite = item. rewrite ( context, child_shape) ?;
957
+ . sub_width ( self . offset )
958
+ . max_width_error ( parent_shape. width , item. span ) ?;
959
+ let rewrite = item. rewrite_result ( context, child_shape) ?;
913
960
if filtered_str_fits ( & rewrite, context. config . max_width ( ) , shape) {
914
961
root_rewrite. push_str ( & rewrite) ;
915
962
} else {
916
963
// We couldn't fit in at the visual indent, try the last
917
964
// indent.
918
- let rewrite = item. rewrite ( context, parent_shape) ?;
965
+ let rewrite = item. rewrite_result ( context, parent_shape) ?;
919
966
root_rewrite. push_str ( & rewrite) ;
920
967
self . offset = 0 ;
921
968
}
@@ -924,7 +971,7 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
924
971
}
925
972
926
973
self . shared . rewrites . push ( root_rewrite) ;
927
- Some ( ( ) )
974
+ Ok ( ( ) )
928
975
}
929
976
930
977
fn child_shape ( & self , context : & RewriteContext < ' _ > , shape : Shape ) -> Option < Shape > {
@@ -937,7 +984,11 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
937
984
)
938
985
}
939
986
940
- fn format_children ( & mut self , context : & RewriteContext < ' _ > , child_shape : Shape ) -> Option < ( ) > {
987
+ fn format_children (
988
+ & mut self ,
989
+ context : & RewriteContext < ' _ > ,
990
+ child_shape : Shape ,
991
+ ) -> Result < ( ) , RewriteError > {
941
992
self . shared . format_children ( context, child_shape)
942
993
}
943
994
@@ -946,12 +997,12 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
946
997
context : & RewriteContext < ' _ > ,
947
998
shape : Shape ,
948
999
child_shape : Shape ,
949
- ) -> Option < ( ) > {
1000
+ ) -> Result < ( ) , RewriteError > {
950
1001
self . shared
951
1002
. format_last_child ( false , context, shape, child_shape)
952
1003
}
953
1004
954
- fn join_rewrites ( & self , context : & RewriteContext < ' _ > , child_shape : Shape ) -> Option < String > {
1005
+ fn join_rewrites ( & self , context : & RewriteContext < ' _ > , child_shape : Shape ) -> RewriteResult {
955
1006
self . shared . join_rewrites ( context, child_shape)
956
1007
}
957
1008
0 commit comments