@@ -136,6 +136,9 @@ impl CollapsibleIf {
136
136
return ;
137
137
}
138
138
139
+ // Peel off any parentheses.
140
+ let ( _, else_block_span, _) = peel_parens ( cx. tcx . sess . source_map ( ) , else_. span ) ;
141
+
139
142
// Prevent "elseif"
140
143
// Check that the "else" is followed by whitespace
141
144
let requires_space = if let Some ( c) = snippet ( cx, up_to_else, ".." ) . chars ( ) . last ( ) {
@@ -152,7 +155,7 @@ impl CollapsibleIf {
152
155
if requires_space { " " } else { "" } ,
153
156
snippet_block_with_applicability(
154
157
cx,
155
- else_ . span ,
158
+ else_block_span ,
156
159
".." ,
157
160
Some ( else_block. span) ,
158
161
& mut applicability
@@ -298,39 +301,36 @@ fn span_extract_keyword(sm: &SourceMap, span: Span, keyword: &str) -> Option<Spa
298
301
. next ( )
299
302
}
300
303
304
+ /// Peel the parentheses from an `if` expression, e.g. `((if true {} else {}))`.
301
305
fn peel_parens ( sm : & SourceMap , mut span : Span ) -> ( Span , Span , Span ) {
302
306
use crate :: rustc_span:: Pos ;
303
- use rustc_span:: SpanData ;
304
307
305
308
let start = span. shrink_to_lo ( ) ;
306
309
let end = span. shrink_to_hi ( ) ;
307
310
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
+ }
326
318
327
- continue ;
328
- }
319
+ ( start . with_hi ( span . lo ( ) ) , span , end . with_lo ( span . hi ( ) ) )
320
+ }
329
321
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 ;
331
326
}
332
327
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
+ } )
336
336
}
0 commit comments