]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_mir/src/transform/inline.rs
inliner: Copy unevaluated constants only after successful inlining
[rust.git] / compiler / rustc_mir / src / transform / inline.rs
index 010a7470ccd38d29166260b7e9814d693ba5e3a2..4de93739992542dd838e308c40627d073953bd9d 100644 (file)
@@ -8,6 +8,7 @@
 use rustc_middle::mir::*;
 use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
+use rustc_span::{hygiene::ExpnKind, ExpnData, Span};
 use rustc_target::spec::abi::Abi;
 
 use super::simplify::{remove_dead_blocks, CfgSimplifier};
@@ -139,14 +140,6 @@ fn run_pass(&self, caller_body: &mut Body<'tcx>) {
                 continue;
             };
 
-            // Copy only unevaluated constants from the callee_body into the caller_body.
-            // Although we are only pushing `ConstKind::Unevaluated` consts to
-            // `required_consts`, here we may not only have `ConstKind::Unevaluated`
-            // because we are calling `subst_and_normalize_erasing_regions`.
-            caller_body.required_consts.extend(callee_body.required_consts.iter().copied().filter(
-                |&constant| matches!(constant.literal.val, ConstKind::Unevaluated(_, _, _)),
-            ));
-
             let start = caller_body.basic_blocks().len();
             debug!("attempting to inline callsite {:?} - body={:?}", callsite, callee_body);
             if !self.inline_call(callsite, caller_body, callee_body) {
@@ -471,6 +464,8 @@ fn dest_needs_borrow(place: Place<'_>) -> bool {
                     cleanup_block: cleanup,
                     in_cleanup_block: false,
                     tcx: self.tcx,
+                    callsite_span: callsite.source_info.span,
+                    body_span: callee_body.span,
                 };
 
                 // Map all `Local`s, `SourceScope`s and `BasicBlock`s to new ones
@@ -519,6 +514,16 @@ fn dest_needs_borrow(place: Place<'_>) -> bool {
                     kind: TerminatorKind::Goto { target: integrator.map_block(START_BLOCK) },
                 });
 
+                // Copy only unevaluated constants from the callee_body into the caller_body.
+                // Although we are only pushing `ConstKind::Unevaluated` consts to
+                // `required_consts`, here we may not only have `ConstKind::Unevaluated`
+                // because we are calling `subst_and_normalize_erasing_regions`.
+                caller_body.required_consts.extend(
+                    callee_body.required_consts.iter().copied().filter(|&constant| {
+                        matches!(constant.literal.val, ConstKind::Unevaluated(_, _, _))
+                    }),
+                );
+
                 true
             }
             kind => {
@@ -682,6 +687,8 @@ struct Integrator<'a, 'tcx> {
     cleanup_block: Option<BasicBlock>,
     in_cleanup_block: bool,
     tcx: TyCtxt<'tcx>,
+    callsite_span: Span,
+    body_span: Span,
 }
 
 impl<'a, 'tcx> Integrator<'a, 'tcx> {
@@ -726,6 +733,14 @@ fn visit_source_scope(&mut self, scope: &mut SourceScope) {
         *scope = self.map_scope(*scope);
     }
 
+    fn visit_span(&mut self, span: &mut Span) {
+        // Make sure that all spans track the fact that they were inlined.
+        *span = self.callsite_span.fresh_expansion(ExpnData {
+            def_site: self.body_span,
+            ..ExpnData::default(ExpnKind::Inlined, *span, self.tcx.sess.edition(), None)
+        });
+    }
+
     fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
         // If this is the `RETURN_PLACE`, we need to rebase any projections onto it.
         let dest_proj_len = self.destination.projection.len();