Skip to content

MIR inlining doesn't properly adjust SourceScopeData parent_scope fields. #76997

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
eddyb opened this issue Sep 21, 2020 · 1 comment · Fixed by #68965
Closed

MIR inlining doesn't properly adjust SourceScopeData parent_scope fields. #76997

eddyb opened this issue Sep 21, 2020 · 1 comment · Fixed by #68965
Assignees
Labels
A-mir-opt-inlining Area: MIR inlining C-bug Category: This is a bug.

Comments

@eddyb
Copy link
Member

eddyb commented Sep 21, 2020

After MIR inlining, this example (see on godbolt):

fn foo() {
    let f = |x| { let y = x; y };
    f(())
}

produces this scope shape (I've removed all the lets and spans):

    scope 1 {
        debug f => _1;
        scope 2 {
            debug x => _4;
        }
    }
    scope 3 {
        debug y => _3;
    }

You can see x is properly located, in the inlined outermost callee scope (2) as a child of the callsite scope (1).
But y isn't, as its scope (3) keeps the original parent_scope (0) it had in the callee body, pre-inlining.

Will try to fix this as part of #68965, or maybe open a separate PR if I can shuffle the commits around.
cc @rust-lang/wg-mir-opt

@eddyb eddyb self-assigned this Sep 21, 2020
@eddyb eddyb added A-mir-opt-inlining Area: MIR inlining C-bug Category: This is a bug. labels Sep 21, 2020
@eddyb
Copy link
Member Author

eddyb commented Sep 21, 2020

Fixing this has (correct) effects on existing mir-opt tests, e.g.:

diff --git a/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir
index 4e61f1c2ef0..26139b02f56 100644
--- a/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir
@@ -16,11 +16,11 @@ fn foo(_1: T, _2: &i32) -> i32 {
         scope 2 (inlined foo::<T>::{{closure}}#0) { // at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12
             debug r => _8;               // in scope 2 at $DIR/inline-closure-borrows-arg.rs:12:14: 12:15
             debug _s => _9;              // in scope 2 at $DIR/inline-closure-borrows-arg.rs:12:23: 12:25
+            scope 3 {
+                debug variable => _8;    // in scope 3 at $DIR/inline-closure-borrows-arg.rs:13:13: 13:21
+            }
         }
     }
-    scope 3 {
-        debug variable => _8;            // in scope 3 at $DIR/inline-closure-borrows-arg.rs:13:13: 13:21
-    }
 
     bb0: {
         StorageLive(_3);                 // scope 0 at $DIR/inline-closure-borrows-arg.rs:12:9: 12:10

I remember seeing some of this and wondering why the scopes were unnested like that, hah!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-mir-opt-inlining Area: MIR inlining C-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant