@@ -136,6 +136,9 @@ impl CollapsibleIf {
136136 return ;
137137 }
138138
139+ // Peel off any parentheses.
140+ let ( _, else_block_span, _) = peel_parens ( cx. tcx . sess . source_map ( ) , else_. span ) ;
141+
139142 // Prevent "elseif"
140143 // Check that the "else" is followed by whitespace
141144 let requires_space = if let Some ( c) = snippet ( cx, up_to_else, ".." ) . chars ( ) . last ( ) {
@@ -152,7 +155,7 @@ impl CollapsibleIf {
152155 if requires_space { " " } else { "" } ,
153156 snippet_block_with_applicability(
154157 cx,
155- else_ . span ,
158+ else_block_span ,
156159 ".." ,
157160 Some ( else_block. span) ,
158161 & mut applicability
@@ -298,39 +301,36 @@ fn span_extract_keyword(sm: &SourceMap, span: Span, keyword: &str) -> Option<Spa
298301 . next ( )
299302}
300303
304+ /// Peel the parentheses from an `if` expression, e.g. `((if true {} else {}))`.
301305fn peel_parens ( sm : & SourceMap , mut span : Span ) -> ( Span , Span , Span ) {
302306 use crate :: rustc_span:: Pos ;
303- use rustc_span:: SpanData ;
304307
305308 let start = span. shrink_to_lo ( ) ;
306309 let end = span. shrink_to_hi ( ) ;
307310
308- loop {
309- let data = span. data ( ) ;
310- let snippet = sm. span_to_snippet ( span) . unwrap ( ) ;
311-
312- let trim_start = snippet. len ( ) - snippet. trim_start ( ) . len ( ) ;
313- let trim_end = snippet. len ( ) - snippet. trim_end ( ) . len ( ) ;
314-
315- let trimmed = snippet. trim ( ) ;
316-
317- if trimmed. starts_with ( '(' ) && trimmed. ends_with ( ')' ) {
318- // Try to remove one layer of parens by adjusting the span
319- span = SpanData {
320- lo : data. lo + BytePos :: from_usize ( trim_start + 1 ) ,
321- hi : data. hi - BytePos :: from_usize ( trim_end + 1 ) ,
322- ctxt : data. ctxt ,
323- parent : data. parent ,
324- }
325- . span ( ) ;
311+ let snippet = sm. span_to_snippet ( span) . unwrap ( ) ;
312+ if let Some ( ( trim_start, _, trim_end) ) = peel_parens_str ( & snippet) {
313+ let mut data = span. data ( ) ;
314+ data. lo = data. lo + BytePos :: from_usize ( trim_start) ;
315+ data. hi = data. hi - BytePos :: from_usize ( trim_end) ;
316+ span = data. span ( ) ;
317+ }
326318
327- continue ;
328- }
319+ ( start . with_hi ( span . lo ( ) ) , span , end . with_lo ( span . hi ( ) ) )
320+ }
329321
330- break ;
322+ fn peel_parens_str ( snippet : & str ) -> Option < ( usize , & str , usize ) > {
323+ let trimmed = snippet. trim ( ) ;
324+ if !( trimmed. starts_with ( '(' ) && trimmed. ends_with ( ')' ) ) {
325+ return None ;
331326 }
332327
333- ( start. with_hi ( span. lo ( ) ) ,
334- span,
335- end. with_lo ( span. hi ( ) ) )
328+ let trim_start = ( snippet. len ( ) - snippet. trim_start ( ) . len ( ) ) + 1 ;
329+ let trim_end = ( snippet. len ( ) - snippet. trim_end ( ) . len ( ) ) + 1 ;
330+
331+ let inner = snippet. get ( trim_start..snippet. len ( ) - trim_end) ?;
332+ Some ( match peel_parens_str ( inner) {
333+ None => ( trim_start, inner, trim_end) ,
334+ Some ( ( start, inner, end) ) => ( trim_start + start, inner, trim_end + end) ,
335+ } )
336336}
0 commit comments