@@ -157,7 +157,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
157157 /// [ 0. Pre-match ]
158158 /// |
159159 /// [ 1. Evaluate Scrutinee (expression being matched on) ]
160- /// [ (fake read of scrutinee) ]
160+ /// [ (PlaceMention of scrutinee) ]
161161 /// |
162162 /// [ 2. Decision tree -- check discriminants ] <--------+
163163 /// | |
@@ -184,7 +184,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
184184 ///
185185 /// We generate MIR in the following steps:
186186 ///
187- /// 1. Evaluate the scrutinee and add the fake read of it ([Builder::lower_scrutinee]).
187+ /// 1. Evaluate the scrutinee and add the PlaceMention of it ([Builder::lower_scrutinee]).
188188 /// 2. Create the decision tree ([Builder::lower_match_tree]).
189189 /// 3. Determine the fake borrows that are needed from the places that were
190190 /// matched against and create the required temporaries for them
@@ -223,6 +223,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
223223 let fake_borrow_temps = self . lower_match_tree (
224224 block,
225225 scrutinee_span,
226+ & scrutinee_place,
226227 match_start_span,
227228 match_has_guard,
228229 & mut candidates,
@@ -238,34 +239,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
238239 )
239240 }
240241
241- /// Evaluate the scrutinee and add the fake read of it.
242+ /// Evaluate the scrutinee and add the PlaceMention for it.
242243 fn lower_scrutinee (
243244 & mut self ,
244245 mut block : BasicBlock ,
245246 scrutinee : & Expr < ' tcx > ,
246247 scrutinee_span : Span ,
247248 ) -> BlockAnd < PlaceBuilder < ' tcx > > {
248249 let scrutinee_place_builder = unpack ! ( block = self . as_place_builder( block, scrutinee) ) ;
249- // Matching on a `scrutinee_place` with an uninhabited type doesn't
250- // generate any memory reads by itself, and so if the place "expression"
251- // contains unsafe operations like raw pointer dereferences or union
252- // field projections, we wouldn't know to require an `unsafe` block
253- // around a `match` equivalent to `std::intrinsics::unreachable()`.
254- // See issue #47412 for this hole being discovered in the wild.
255- //
256- // HACK(eddyb) Work around the above issue by adding a dummy inspection
257- // of `scrutinee_place`, specifically by applying `ReadForMatch`.
258- //
259- // NOTE: ReadForMatch also checks that the scrutinee is initialized.
260- // This is currently needed to not allow matching on an uninitialized,
261- // uninhabited value. If we get never patterns, those will check that
262- // the place is initialized, and so this read would only be used to
263- // check safety.
264- let cause_matched_place = FakeReadCause :: ForMatchedPlace ( None ) ;
265- let source_info = self . source_info ( scrutinee_span) ;
266-
267250 if let Some ( scrutinee_place) = scrutinee_place_builder. try_to_place ( self ) {
268- self . cfg . push_fake_read ( block, source_info, cause_matched_place, scrutinee_place) ;
251+ let source_info = self . source_info ( scrutinee_span) ;
252+ self . cfg . push_place_mention ( block, source_info, scrutinee_place) ;
269253 }
270254
271255 block. and ( scrutinee_place_builder)
@@ -304,6 +288,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
304288 & mut self ,
305289 block : BasicBlock ,
306290 scrutinee_span : Span ,
291+ scrutinee_place_builder : & PlaceBuilder < ' tcx > ,
307292 match_start_span : Span ,
308293 match_has_guard : bool ,
309294 candidates : & mut [ & mut Candidate < ' pat , ' tcx > ] ,
@@ -331,6 +316,33 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
331316 // otherwise block. Match checking will ensure this is actually
332317 // unreachable.
333318 let source_info = self . source_info ( scrutinee_span) ;
319+
320+ // Matching on a `scrutinee_place` with an uninhabited type doesn't
321+ // generate any memory reads by itself, and so if the place "expression"
322+ // contains unsafe operations like raw pointer dereferences or union
323+ // field projections, we wouldn't know to require an `unsafe` block
324+ // around a `match` equivalent to `std::intrinsics::unreachable()`.
325+ // See issue #47412 for this hole being discovered in the wild.
326+ //
327+ // HACK(eddyb) Work around the above issue by adding a dummy inspection
328+ // of `scrutinee_place`, specifically by applying `ReadForMatch`.
329+ //
330+ // NOTE: ReadForMatch also checks that the scrutinee is initialized.
331+ // This is currently needed to not allow matching on an uninitialized,
332+ // uninhabited value. If we get never patterns, those will check that
333+ // the place is initialized, and so this read would only be used to
334+ // check safety.
335+ let cause_matched_place = FakeReadCause :: ForMatchedPlace ( None ) ;
336+
337+ if let Some ( scrutinee_place) = scrutinee_place_builder. try_to_place ( self ) {
338+ self . cfg . push_fake_read (
339+ otherwise_block,
340+ source_info,
341+ cause_matched_place,
342+ scrutinee_place,
343+ ) ;
344+ }
345+
334346 self . cfg . terminate ( otherwise_block, source_info, TerminatorKind :: Unreachable ) ;
335347 }
336348
@@ -599,13 +611,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
599611 }
600612
601613 _ => {
602- let place_builder = unpack ! ( block = self . as_place_builder( block, initializer) ) ;
603-
604- if let Some ( place) = place_builder. try_to_place ( self ) {
605- let source_info = self . source_info ( initializer. span ) ;
606- self . cfg . push_place_mention ( block, source_info, place) ;
607- }
608-
614+ let place_builder =
615+ unpack ! ( block = self . lower_scrutinee( block, initializer, initializer. span) ) ;
609616 self . place_into_pattern ( block, & irrefutable_pat, place_builder, true )
610617 }
611618 }
@@ -622,6 +629,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
622629 let fake_borrow_temps = self . lower_match_tree (
623630 block,
624631 irrefutable_pat. span ,
632+ & initializer,
625633 irrefutable_pat. span ,
626634 false ,
627635 & mut [ & mut candidate] ,
@@ -1841,6 +1849,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
18411849 let fake_borrow_temps = self . lower_match_tree (
18421850 block,
18431851 pat. span ,
1852+ & expr_place_builder,
18441853 pat. span ,
18451854 false ,
18461855 & mut [ & mut guard_candidate, & mut otherwise_candidate] ,
@@ -2342,6 +2351,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
23422351 let fake_borrow_temps = this. lower_match_tree (
23432352 block,
23442353 initializer_span,
2354+ & scrutinee,
23452355 pattern. span ,
23462356 false ,
23472357 & mut [ & mut candidate, & mut wildcard] ,
0 commit comments