break out scopes when let-else fails to match · rust-lang/rust@9b56640 (original) (raw)
`@@ -2282,49 +2282,55 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
`
2282
2282
`initializer_span: Span,
`
2283
2283
`else_block: &Block,
`
2284
2284
`visibility_scope: Option,
`
``
2285
`+
remainder_scope: region::Scope,
`
2285
2286
`remainder_span: Span,
`
2286
2287
`pattern: &Pat<'tcx>,
`
2287
2288
`) -> BlockAnd<()> {
`
2288
``
`-
let scrutinee = unpack!(block = self.lower_scrutinee(block, init, initializer_span));
`
2289
``
`-
let pat = Pat { ty: init.ty, span: else_block.span, kind: Box::new(PatKind::Wild) };
`
2290
``
`-
let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false);
`
2291
``
`-
self.declare_bindings(
`
2292
``
`-
visibility_scope,
`
2293
``
`-
remainder_span,
`
2294
``
`-
pattern,
`
2295
``
`-
ArmHasGuard(false),
`
2296
``
`-
Some((None, initializer_span)),
`
2297
``
`-
);
`
2298
``
`-
let mut candidate = Candidate::new(scrutinee.clone(), pattern, false);
`
2299
``
`-
let fake_borrow_temps = self.lower_match_tree(
`
2300
``
`-
block,
`
2301
``
`-
initializer_span,
`
2302
``
`-
pattern.span,
`
2303
``
`-
false,
`
2304
``
`-
&mut [&mut candidate, &mut wildcard],
`
2305
``
`-
);
`
2306
``
`-
// This block is for the matching case
`
2307
``
`-
let matching = self.bind_pattern(
`
2308
``
`-
self.source_info(pattern.span),
`
2309
``
`-
candidate,
`
2310
``
`-
None,
`
2311
``
`-
&fake_borrow_temps,
`
2312
``
`-
initializer_span,
`
2313
``
`-
None,
`
2314
``
`-
None,
`
2315
``
`-
None,
`
2316
``
`-
);
`
2317
``
`-
// This block is for the failure case
`
2318
``
`-
let failure = self.bind_pattern(
`
2319
``
`-
self.source_info(else_block.span),
`
2320
``
`-
wildcard,
`
2321
``
`-
None,
`
2322
``
`-
&fake_borrow_temps,
`
2323
``
`-
initializer_span,
`
2324
``
`-
None,
`
2325
``
`-
None,
`
2326
``
`-
None,
`
2327
``
`-
);
`
``
2289
`+
let (matching, failure) = self.in_if_then_scope(remainder_scope, |this| {
`
``
2290
`+
let scrutinee = unpack!(block = this.lower_scrutinee(block, init, initializer_span));
`
``
2291
`+
let pat = Pat { ty: init.ty, span: else_block.span, kind: Box::new(PatKind::Wild) };
`
``
2292
`+
let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false);
`
``
2293
`+
this.declare_bindings(
`
``
2294
`+
visibility_scope,
`
``
2295
`+
remainder_span,
`
``
2296
`+
pattern,
`
``
2297
`+
ArmHasGuard(false),
`
``
2298
`+
Some((None, initializer_span)),
`
``
2299
`+
);
`
``
2300
`+
let mut candidate = Candidate::new(scrutinee.clone(), pattern, false);
`
``
2301
`+
let fake_borrow_temps = this.lower_match_tree(
`
``
2302
`+
block,
`
``
2303
`+
initializer_span,
`
``
2304
`+
pattern.span,
`
``
2305
`+
false,
`
``
2306
`+
&mut [&mut candidate, &mut wildcard],
`
``
2307
`+
);
`
``
2308
`+
// This block is for the matching case
`
``
2309
`+
let matching = this.bind_pattern(
`
``
2310
`+
this.source_info(pattern.span),
`
``
2311
`+
candidate,
`
``
2312
`+
None,
`
``
2313
`+
&fake_borrow_temps,
`
``
2314
`+
initializer_span,
`
``
2315
`+
None,
`
``
2316
`+
None,
`
``
2317
`+
None,
`
``
2318
`+
);
`
``
2319
`+
// This block is for the failure case
`
``
2320
`+
let failure = this.bind_pattern(
`
``
2321
`+
this.source_info(else_block.span),
`
``
2322
`+
wildcard,
`
``
2323
`+
None,
`
``
2324
`+
&fake_borrow_temps,
`
``
2325
`+
initializer_span,
`
``
2326
`+
None,
`
``
2327
`+
None,
`
``
2328
`+
None,
`
``
2329
`+
);
`
``
2330
`+
this.break_for_else(failure, remainder_scope, this.source_info(initializer_span));
`
``
2331
`+
matching.unit()
`
``
2332
`+
});
`
``
2333
+
2328
2334
`// This place is not really used because this destination place
`
2329
2335
`// should never be used to take values at the end of the failure
`
2330
2336
`// block.
`