about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform
diff options
context:
space:
mode:
authorLaurențiu Nicola <lnicola@users.noreply.github.com>2025-01-07 16:13:25 +0000
committerGitHub <noreply@github.com>2025-01-07 16:13:25 +0000
commitfd1e95538fa3b3ca87fc4f7df5e9abd918949536 (patch)
treef2f3317a4a2031c7cc1a141c5703166e6fa1d107 /compiler/rustc_mir_transform
parent8e4409cce3e4a7f7eb974462c943e717db818ed8 (diff)
parente103ab16084dc735b8db6b90186cd7b6967402ee (diff)
downloadrust-fd1e95538fa3b3ca87fc4f7df5e9abd918949536.tar.gz
rust-fd1e95538fa3b3ca87fc4f7df5e9abd918949536.zip
Merge pull request #18874 from lnicola/sync-from-rust
minor: Sync from downstream
Diffstat (limited to 'compiler/rustc_mir_transform')
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs28
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs3
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs3
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs3
-rw-r--r--compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs4
-rw-r--r--compiler/rustc_mir_transform/src/match_branches.rs30
6 files changed, 39 insertions, 32 deletions
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index a3320f99cc3..f6536d78761 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -1822,9 +1822,6 @@ impl<'tcx> Visitor<'tcx> for EnsureCoroutineFieldAssignmentsNeverAlias<'_> {
 fn check_suspend_tys<'tcx>(tcx: TyCtxt<'tcx>, layout: &CoroutineLayout<'tcx>, body: &Body<'tcx>) {
     let mut linted_tys = FxHashSet::default();
 
-    // We want a user-facing param-env.
-    let param_env = tcx.param_env(body.source.def_id());
-
     for (variant, yield_source_info) in
         layout.variant_fields.iter().zip(&layout.variant_source_info)
     {
@@ -1838,7 +1835,7 @@ fn check_suspend_tys<'tcx>(tcx: TyCtxt<'tcx>, layout: &CoroutineLayout<'tcx>, bo
                     continue;
                 };
 
-                check_must_not_suspend_ty(tcx, decl.ty, hir_id, param_env, SuspendCheckData {
+                check_must_not_suspend_ty(tcx, decl.ty, hir_id, SuspendCheckData {
                     source_span: decl.source_info.span,
                     yield_span: yield_source_info.span,
                     plural_len: 1,
@@ -1868,7 +1865,6 @@ fn check_must_not_suspend_ty<'tcx>(
     tcx: TyCtxt<'tcx>,
     ty: Ty<'tcx>,
     hir_id: hir::HirId,
-    param_env: ty::ParamEnv<'tcx>,
     data: SuspendCheckData<'_>,
 ) -> bool {
     if ty.is_unit() {
@@ -1883,16 +1879,13 @@ fn check_must_not_suspend_ty<'tcx>(
         ty::Adt(_, args) if ty.is_box() => {
             let boxed_ty = args.type_at(0);
             let allocator_ty = args.type_at(1);
-            check_must_not_suspend_ty(tcx, boxed_ty, hir_id, param_env, SuspendCheckData {
+            check_must_not_suspend_ty(tcx, boxed_ty, hir_id, SuspendCheckData {
                 descr_pre: &format!("{}boxed ", data.descr_pre),
                 ..data
-            }) || check_must_not_suspend_ty(
-                tcx,
-                allocator_ty,
-                hir_id,
-                param_env,
-                SuspendCheckData { descr_pre: &format!("{}allocator ", data.descr_pre), ..data },
-            )
+            }) || check_must_not_suspend_ty(tcx, allocator_ty, hir_id, SuspendCheckData {
+                descr_pre: &format!("{}allocator ", data.descr_pre),
+                ..data
+            })
         }
         ty::Adt(def, _) => check_must_not_suspend_def(tcx, def.did(), hir_id, data),
         // FIXME: support adding the attribute to TAITs
@@ -1937,7 +1930,7 @@ fn check_must_not_suspend_ty<'tcx>(
             let mut has_emitted = false;
             for (i, ty) in fields.iter().enumerate() {
                 let descr_post = &format!(" in tuple element {i}");
-                if check_must_not_suspend_ty(tcx, ty, hir_id, param_env, SuspendCheckData {
+                if check_must_not_suspend_ty(tcx, ty, hir_id, SuspendCheckData {
                     descr_post,
                     ..data
                 }) {
@@ -1948,7 +1941,7 @@ fn check_must_not_suspend_ty<'tcx>(
         }
         ty::Array(ty, len) => {
             let descr_pre = &format!("{}array{} of ", data.descr_pre, plural_suffix);
-            check_must_not_suspend_ty(tcx, ty, hir_id, param_env, SuspendCheckData {
+            check_must_not_suspend_ty(tcx, ty, hir_id, SuspendCheckData {
                 descr_pre,
                 // FIXME(must_not_suspend): This is wrong. We should handle printing unevaluated consts.
                 plural_len: len.try_to_target_usize(tcx).unwrap_or(0) as usize + 1,
@@ -1959,10 +1952,7 @@ fn check_must_not_suspend_ty<'tcx>(
         // may not be considered live across the await point.
         ty::Ref(_region, ty, _mutability) => {
             let descr_pre = &format!("{}reference{} to ", data.descr_pre, plural_suffix);
-            check_must_not_suspend_ty(tcx, ty, hir_id, param_env, SuspendCheckData {
-                descr_pre,
-                ..data
-            })
+            check_must_not_suspend_ty(tcx, ty, hir_id, SuspendCheckData { descr_pre, ..data })
         }
         _ => false,
     }
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 7594583c4ad..cc44114782c 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -932,7 +932,8 @@ fn try_write_constant<'tcx>(
         | ty::Closure(..)
         | ty::CoroutineClosure(..)
         | ty::Coroutine(..)
-        | ty::Dynamic(..) => throw_machine_stop_str!("unsupported type"),
+        | ty::Dynamic(..)
+        | ty::UnsafeBinder(_) => throw_machine_stop_str!("unsupported type"),
 
         ty::Error(_) | ty::Infer(..) | ty::CoroutineWitness(..) => bug!(),
     }
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 35699acb318..339acbad6b9 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -190,7 +190,8 @@ impl<'tcx> Inliner<'tcx> {
 
         // Intrinsic fallback bodies are automatically made cross-crate inlineable,
         // but at this stage we don't know whether codegen knows the intrinsic,
-        // so just conservatively don't inline it.
+        // so just conservatively don't inline it. This also ensures that we do not
+        // accidentally inline the body of an intrinsic that *must* be overridden.
         if self.tcx.has_attr(callsite.callee.def_id(), sym::rustc_intrinsic) {
             return Err("Callee is an intrinsic, do not inline fallback bodies");
         }
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 5c090bf7cad..e1fba9be5bb 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -437,6 +437,8 @@ fn mir_promoted(
         Some(MirPhase::Analysis(AnalysisPhase::Initial)),
     );
 
+    lint_tail_expr_drop_order::run_lint(tcx, def, &body);
+
     let promoted = promote_pass.promoted_fragments.into_inner();
     (tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted))
 }
@@ -492,7 +494,6 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
     }
 
     let (body, _) = tcx.mir_promoted(def);
-    lint_tail_expr_drop_order::run_lint(tcx, def, &body.borrow());
     let mut body = body.steal();
 
     if let Some(error_reported) = tainted_by_errors {
diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
index 7fb421dea0c..e5a183bc75c 100644
--- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
+++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
@@ -285,7 +285,9 @@ fn ty_dtor_span<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Span> {
         | ty::Placeholder(_)
         | ty::Infer(_)
         | ty::Slice(_)
-        | ty::Array(_, _) => None,
+        | ty::Array(_, _)
+        | ty::UnsafeBinder(_) => None,
+
         ty::Adt(adt_def, _) => {
             let did = adt_def.did();
             let try_local_did_span = |did: DefId| {
diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs
index 20e2a65b311..534ba991780 100644
--- a/compiler/rustc_mir_transform/src/match_branches.rs
+++ b/compiler/rustc_mir_transform/src/match_branches.rs
@@ -7,6 +7,7 @@ use rustc_middle::mir::*;
 use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
 use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
 use rustc_type_ir::TyKind::*;
+use tracing::instrument;
 
 use super::simplify::simplify_cfg;
 
@@ -51,7 +52,7 @@ impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification {
 }
 
 trait SimplifyMatch<'tcx> {
-    /// Simplifies a match statement, returning true if the simplification succeeds, false
+    /// Simplifies a match statement, returning `Some` if the simplification succeeds, `None`
     /// otherwise. Generic code is written here, and we generally don't need a custom
     /// implementation.
     fn simplify(
@@ -159,6 +160,7 @@ struct SimplifyToIf;
 /// }
 /// ```
 impl<'tcx> SimplifyMatch<'tcx> for SimplifyToIf {
+    #[instrument(level = "debug", skip(self, tcx), ret)]
     fn can_simplify(
         &mut self,
         tcx: TyCtxt<'tcx>,
@@ -167,12 +169,15 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToIf {
         bbs: &IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
         _discr_ty: Ty<'tcx>,
     ) -> Option<()> {
-        if targets.iter().len() != 1 {
-            return None;
-        }
+        let (first, second) = match targets.all_targets() {
+            &[first, otherwise] => (first, otherwise),
+            &[first, second, otherwise] if bbs[otherwise].is_empty_unreachable() => (first, second),
+            _ => {
+                return None;
+            }
+        };
+
         // We require that the possible target blocks all be distinct.
-        let (_, first) = targets.iter().next().unwrap();
-        let second = targets.otherwise();
         if first == second {
             return None;
         }
@@ -221,8 +226,14 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToIf {
         discr_local: Local,
         discr_ty: Ty<'tcx>,
     ) {
-        let (val, first) = targets.iter().next().unwrap();
-        let second = targets.otherwise();
+        let ((val, first), second) = match (targets.all_targets(), targets.all_values()) {
+            (&[first, otherwise], &[val]) => ((val, first), otherwise),
+            (&[first, second, otherwise], &[val, _]) if bbs[otherwise].is_empty_unreachable() => {
+                ((val, first), second)
+            }
+            _ => unreachable!(),
+        };
+
         // We already checked that first and second are different blocks,
         // and bb_idx has a different terminator from both of them.
         let first = &bbs[first];
@@ -297,7 +308,7 @@ struct SimplifyToExp {
     transform_kinds: Vec<TransformKind>,
 }
 
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 enum ExpectedTransformKind<'a, 'tcx> {
     /// Identical statements.
     Same(&'a StatementKind<'tcx>),
@@ -362,6 +373,7 @@ impl From<ExpectedTransformKind<'_, '_>> for TransformKind {
 /// }
 /// ```
 impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp {
+    #[instrument(level = "debug", skip(self, tcx), ret)]
     fn can_simplify(
         &mut self,
         tcx: TyCtxt<'tcx>,