about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2021-11-19 13:06:34 +0900
committerGitHub <noreply@github.com>2021-11-19 13:06:34 +0900
commit48947eafda511bf7acb43eff63b8ff61de1816d3 (patch)
tree5689a6bd7f0e1fbc7a213664b92be764747fcd05
parent81fd01684820b3937f6ae5e281b844ffbe5e1377 (diff)
parent59edb9d38280eed96a3012f3ea2a46cb8c254218 (diff)
downloadrust-48947eafda511bf7acb43eff63b8ff61de1816d3.tar.gz
rust-48947eafda511bf7acb43eff63b8ff61de1816d3.zip
Rollup merge of #90633 - tmiasko:candidate-struct, r=nagisa
Refactor single variant `Candidate` enum into a struct

`Candidate` enum has only a single `Ref` variant.  Refactor it into a
struct and reduce overall indentation of the code by two levels.

No functional changes.
-rw-r--r--compiler/rustc_const_eval/src/transform/promote_consts.rs183
1 files changed, 82 insertions, 101 deletions
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index 7bf378601e0..a92b20f5cb5 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -93,17 +93,8 @@ impl TempState {
 /// returned value in a promoted MIR, unless it's a subset
 /// of a larger candidate.
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub enum Candidate {
-    /// Borrow of a constant temporary, candidate for lifetime extension.
-    Ref(Location),
-}
-
-impl Candidate {
-    fn source_info(&self, body: &Body<'_>) -> SourceInfo {
-        match self {
-            Candidate::Ref(location) => *body.source_info(*location),
-        }
-    }
+pub struct Candidate {
+    location: Location,
 }
 
 struct Collector<'a, 'tcx> {
@@ -167,7 +158,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
 
         match *rvalue {
             Rvalue::Ref(..) => {
-                self.candidates.push(Candidate::Ref(location));
+                self.candidates.push(Candidate { location });
             }
             _ => {}
         }
@@ -209,36 +200,33 @@ struct Unpromotable;
 
 impl<'tcx> Validator<'_, 'tcx> {
     fn validate_candidate(&self, candidate: Candidate) -> Result<(), Unpromotable> {
-        match candidate {
-            Candidate::Ref(loc) => {
-                let statement = &self.body[loc.block].statements[loc.statement_index];
-                match &statement.kind {
-                    StatementKind::Assign(box (_, Rvalue::Ref(_, kind, place))) => {
-                        // We can only promote interior borrows of promotable temps (non-temps
-                        // don't get promoted anyway).
-                        self.validate_local(place.local)?;
-
-                        // The reference operation itself must be promotable.
-                        // (Needs to come after `validate_local` to avoid ICEs.)
-                        self.validate_ref(*kind, place)?;
-
-                        // We do not check all the projections (they do not get promoted anyway),
-                        // but we do stay away from promoting anything involving a dereference.
-                        if place.projection.contains(&ProjectionElem::Deref) {
-                            return Err(Unpromotable);
-                        }
+        let loc = candidate.location;
+        let statement = &self.body[loc.block].statements[loc.statement_index];
+        match &statement.kind {
+            StatementKind::Assign(box (_, Rvalue::Ref(_, kind, place))) => {
+                // We can only promote interior borrows of promotable temps (non-temps
+                // don't get promoted anyway).
+                self.validate_local(place.local)?;
+
+                // The reference operation itself must be promotable.
+                // (Needs to come after `validate_local` to avoid ICEs.)
+                self.validate_ref(*kind, place)?;
 
-                        // We cannot promote things that need dropping, since the promoted value
-                        // would not get dropped.
-                        if self.qualif_local::<qualifs::NeedsDrop>(place.local) {
-                            return Err(Unpromotable);
-                        }
+                // We do not check all the projections (they do not get promoted anyway),
+                // but we do stay away from promoting anything involving a dereference.
+                if place.projection.contains(&ProjectionElem::Deref) {
+                    return Err(Unpromotable);
+                }
 
-                        Ok(())
-                    }
-                    _ => bug!(),
+                // We cannot promote things that need dropping, since the promoted value
+                // would not get dropped.
+                if self.qualif_local::<qualifs::NeedsDrop>(place.local) {
+                    return Err(Unpromotable);
                 }
+
+                Ok(())
             }
+            _ => bug!(),
         }
     }
 
@@ -871,58 +859,55 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                 }))
             };
             let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut();
-            match candidate {
-                Candidate::Ref(loc) => {
-                    let statement = &mut blocks[loc.block].statements[loc.statement_index];
-                    match statement.kind {
-                        StatementKind::Assign(box (
-                            _,
-                            Rvalue::Ref(ref mut region, borrow_kind, ref mut place),
-                        )) => {
-                            // Use the underlying local for this (necessarily interior) borrow.
-                            let ty = local_decls.local_decls()[place.local].ty;
-                            let span = statement.source_info.span;
-
-                            let ref_ty = tcx.mk_ref(
-                                tcx.lifetimes.re_erased,
-                                ty::TypeAndMut { ty, mutbl: borrow_kind.to_mutbl_lossy() },
-                            );
-
-                            *region = tcx.lifetimes.re_erased;
-
-                            let mut projection = vec![PlaceElem::Deref];
-                            projection.extend(place.projection);
-                            place.projection = tcx.intern_place_elems(&projection);
-
-                            // Create a temp to hold the promoted reference.
-                            // This is because `*r` requires `r` to be a local,
-                            // otherwise we would use the `promoted` directly.
-                            let mut promoted_ref = LocalDecl::new(ref_ty, span);
-                            promoted_ref.source_info = statement.source_info;
-                            let promoted_ref = local_decls.push(promoted_ref);
-                            assert_eq!(self.temps.push(TempState::Unpromotable), promoted_ref);
-
-                            let promoted_ref_statement = Statement {
-                                source_info: statement.source_info,
-                                kind: StatementKind::Assign(Box::new((
-                                    Place::from(promoted_ref),
-                                    Rvalue::Use(promoted_operand(ref_ty, span)),
-                                ))),
-                            };
-                            self.extra_statements.push((loc, promoted_ref_statement));
-
-                            Rvalue::Ref(
-                                tcx.lifetimes.re_erased,
-                                borrow_kind,
-                                Place {
-                                    local: mem::replace(&mut place.local, promoted_ref),
-                                    projection: List::empty(),
-                                },
-                            )
-                        }
-                        _ => bug!(),
-                    }
+            let loc = candidate.location;
+            let statement = &mut blocks[loc.block].statements[loc.statement_index];
+            match statement.kind {
+                StatementKind::Assign(box (
+                    _,
+                    Rvalue::Ref(ref mut region, borrow_kind, ref mut place),
+                )) => {
+                    // Use the underlying local for this (necessarily interior) borrow.
+                    let ty = local_decls.local_decls()[place.local].ty;
+                    let span = statement.source_info.span;
+
+                    let ref_ty = tcx.mk_ref(
+                        tcx.lifetimes.re_erased,
+                        ty::TypeAndMut { ty, mutbl: borrow_kind.to_mutbl_lossy() },
+                    );
+
+                    *region = tcx.lifetimes.re_erased;
+
+                    let mut projection = vec![PlaceElem::Deref];
+                    projection.extend(place.projection);
+                    place.projection = tcx.intern_place_elems(&projection);
+
+                    // Create a temp to hold the promoted reference.
+                    // This is because `*r` requires `r` to be a local,
+                    // otherwise we would use the `promoted` directly.
+                    let mut promoted_ref = LocalDecl::new(ref_ty, span);
+                    promoted_ref.source_info = statement.source_info;
+                    let promoted_ref = local_decls.push(promoted_ref);
+                    assert_eq!(self.temps.push(TempState::Unpromotable), promoted_ref);
+
+                    let promoted_ref_statement = Statement {
+                        source_info: statement.source_info,
+                        kind: StatementKind::Assign(Box::new((
+                            Place::from(promoted_ref),
+                            Rvalue::Use(promoted_operand(ref_ty, span)),
+                        ))),
+                    };
+                    self.extra_statements.push((loc, promoted_ref_statement));
+
+                    Rvalue::Ref(
+                        tcx.lifetimes.re_erased,
+                        borrow_kind,
+                        Place {
+                            local: mem::replace(&mut place.local, promoted_ref),
+                            projection: List::empty(),
+                        },
+                    )
                 }
+                _ => bug!(),
             }
         };
 
@@ -964,17 +949,13 @@ pub fn promote_candidates<'tcx>(
 
     let mut extra_statements = vec![];
     for candidate in candidates.into_iter().rev() {
-        match candidate {
-            Candidate::Ref(Location { block, statement_index }) => {
-                if let StatementKind::Assign(box (place, _)) =
-                    &body[block].statements[statement_index].kind
-                {
-                    if let Some(local) = place.as_local() {
-                        if temps[local] == TempState::PromotedOut {
-                            // Already promoted.
-                            continue;
-                        }
-                    }
+        let Location { block, statement_index } = candidate.location;
+        if let StatementKind::Assign(box (place, _)) = &body[block].statements[statement_index].kind
+        {
+            if let Some(local) = place.as_local() {
+                if temps[local] == TempState::PromotedOut {
+                    // Already promoted.
+                    continue;
                 }
             }
         }
@@ -982,7 +963,7 @@ pub fn promote_candidates<'tcx>(
         // Declare return place local so that `mir::Body::new` doesn't complain.
         let initial_locals = iter::once(LocalDecl::new(tcx.types.never, body.span)).collect();
 
-        let mut scope = body.source_scopes[candidate.source_info(body).scope].clone();
+        let mut scope = body.source_scopes[body.source_info(candidate.location).scope].clone();
         scope.parent_scope = None;
 
         let promoted = Body::new(