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.

`