Skip to content

Commit

Permalink
No need to re-establish temporaries
Browse files Browse the repository at this point in the history
  • Loading branch information
Nadrieril committed Mar 16, 2024
1 parent bc1fb59 commit 07e4549
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 45 deletions.
34 changes: 1 addition & 33 deletions compiler/rustc_mir_build/src/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -993,17 +993,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}

/// A temporary that must be set like `let temp = Deref::deref(&place)` after the candidate
/// `pre_binding_block`. This is because fake edges prevent us from keeping the temporaries we set
/// up while testing which branch to take.
#[derive(Debug, Copy, Clone)]
struct DerefTemporary<'tcx> {
place: Place<'tcx>,
temp: Place<'tcx>,
ty: Ty<'tcx>,
span: Span,
}

/// Data extracted from a pattern that doesn't affect which branch is taken. Collected during
/// pattern simplification and not mutated later.
#[derive(Debug, Clone, Default)]
Expand All @@ -1016,15 +1005,12 @@ struct PatternExtraData<'tcx> {

/// Types that must be asserted.
ascriptions: Vec<Ascription<'tcx>>,

/// Temporaries that must be set up in order.
deref_temps: Vec<DerefTemporary<'tcx>>,
}

impl<'tcx> PatternExtraData<'tcx> {
fn is_empty(&self) -> bool {
// FIXME(deref_patterns): can we merge trivial subcandidates that use deref patterns?
self.bindings.is_empty() && self.ascriptions.is_empty() && self.deref_temps.is_empty()
self.bindings.is_empty() && self.ascriptions.is_empty()
}
}

Expand All @@ -1051,7 +1037,6 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
span: pattern.span,
bindings: Vec::new(),
ascriptions: Vec::new(),
deref_temps: Vec::new(),
},
};
cx.simplify_match_pairs(&mut flat_pat.match_pairs, &mut flat_pat.extra_data);
Expand Down Expand Up @@ -2098,23 +2083,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block = fresh_block;
}

for d in collected_data.iter() {
for deref_call in d.deref_temps.iter() {
// Re-establish `Deref::deref` temporaries because false edges trick borrowck into
// believing they may not be initialized.
let next_block = self.cfg.start_new_block();
self.call_deref(
block,
next_block,
deref_call.place,
deref_call.ty,
deref_call.temp,
deref_call.span,
);
block = next_block;
}
}

self.ascribe_types(block, collected_data.iter().flat_map(|d| &d.ascriptions).cloned());

// rust-lang/rust#27282: The `autoref` business deserves some
Expand Down
13 changes: 1 addition & 12 deletions compiler/rustc_mir_build/src/build/matches/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//! sort of test: for example, testing which variant an enum is, or
//! testing a value against a constant.

use crate::build::matches::{DerefTemporary, MatchPair, PatternExtraData, TestCase};
use crate::build::matches::{MatchPair, PatternExtraData, TestCase};
use crate::build::Builder;

use std::mem;
Expand Down Expand Up @@ -44,17 +44,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// after any bindings in `pat`. This doesn't work for or-patterns: the current structure of
// match lowering forces us to lower bindings inside or-patterns last.
for mut match_pair in mem::take(match_pairs) {
if let TestCase::Deref { temp } = &match_pair.test_case {
// Re-establish these temporaries after matching the candidate in case we have
// bindings that depend on them.
extra_data.deref_temps.push(DerefTemporary {
place: match_pair.place.to_place(self),
temp: *temp,
ty: match_pair.pattern.ty,
span: match_pair.pattern.span,
});
}

self.simplify_match_pairs(&mut match_pair.subpairs, extra_data);
if let TestCase::Irrefutable { binding, ascription } = match_pair.test_case {
if let Some(binding) = binding {
Expand Down

0 comments on commit 07e4549

Please sign in to comment.