]> git.lizzy.rs Git - rust.git/commitdiff
NRVO: Allow occurrences of the return place in var debug info
authorTomasz Miąsko <tomasz.miasko@gmail.com>
Thu, 3 Sep 2020 00:00:00 +0000 (00:00 +0000)
committerTomasz Miąsko <tomasz.miasko@gmail.com>
Fri, 4 Sep 2020 00:33:37 +0000 (02:33 +0200)
The non-use occurrence of the return place in var debug info does not
currently inhibit NRVO optimization, but it will fail assertion in
`visit_place` when optimization is performed.

Relax assertion check to allow the return place in var debug info.

This case might be impossible to hit in optimization pipelines as of
now, but can be encountered in customized mir-opt-level=2 pipeline with
copy propagation disabled. For example in:

```
pub fn b(s: String) -> String {
    a(s)
}

#[inline]
pub fn a(s: String) -> String {
    let x = s;
    let y = x;
    y
}
```

compiler/rustc_mir/src/transform/nrvo.rs

index 1f3d7bb7cc6f41c2ab16dcf425667893c323462f..3673b6a4aa223c2e5e9c0b9dd139c3133aed904e 100644 (file)
@@ -1,6 +1,6 @@
 use rustc_hir::Mutability;
 use rustc_index::bit_set::HybridBitSet;
-use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
+use rustc_middle::mir::visit::{MutVisitor, NonUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::{self, BasicBlock, Local, Location};
 use rustc_middle::ty::TyCtxt;
 
@@ -196,9 +196,10 @@ fn visit_terminator(&mut self, terminator: &mut mir::Terminator<'tcx>, loc: Loca
         self.super_terminator(terminator, loc);
     }
 
-    fn visit_local(&mut self, l: &mut Local, _: PlaceContext, _: Location) {
-        assert_ne!(*l, mir::RETURN_PLACE);
-        if *l == self.to_rename {
+    fn visit_local(&mut self, l: &mut Local, ctxt: PlaceContext, _: Location) {
+        if *l == mir::RETURN_PLACE {
+            assert_eq!(ctxt, PlaceContext::NonUse(NonUseContext::VarDebugInfo));
+        } else if *l == self.to_rename {
             *l = mir::RETURN_PLACE;
         }
     }