about summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorDavid Wood <david@davidtw.co>2019-05-01 13:35:34 +0100
committerDavid Wood <david@davidtw.co>2019-05-01 14:40:59 +0100
commitb05d5db87bd9a3f31729a5c48dc5dd5bec6dbd2d (patch)
tree89ebc62179b1a604b975caa5a9c38cd061db2077 /src/libsyntax/ext
parent47e0803d5c2ad5952220f2c260d7e12921c1d3fe (diff)
downloadrust-b05d5db87bd9a3f31729a5c48dc5dd5bec6dbd2d.tar.gz
rust-b05d5db87bd9a3f31729a5c48dc5dd5bec6dbd2d.zip
Ensure that drop order of `async fn` matches `fn`.
This commit modifies the lowering of `async fn` arguments so that the
drop order matches the equivalent `fn`.

Previously, async function arguments were lowered as shown below:

    async fn foo(<pattern>: <ty>) {
      async move {
      }
    } // <-- dropped as you "exit" the fn

    // ...becomes...
    fn foo(__arg0: <ty>) {
      async move {
        let <pattern> = __arg0;
      } // <-- dropped as you "exit" the async block
    }

After this PR, async function arguments will be lowered as:

    async fn foo(<pattern>: <ty>, <pattern>: <ty>, <pattern>: <ty>) {
      async move {
      }
    } // <-- dropped as you "exit" the fn

    // ...becomes...
    fn foo(__arg0: <ty>, __arg1: <ty>, __arg2: <ty>) {
      async move {
        let __arg2 = __arg2;
        let <pattern> = __arg2;
        let __arg1 = __arg1;
        let <pattern> = __arg1;
        let __arg0 = __arg0;
        let <pattern> = __arg0;
      } // <-- dropped as you "exit" the async block
    }

If `<pattern>` is a simple ident, then it is lowered to a single
`let <pattern> = <pattern>;` statement as an optimization.
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/placeholders.rs5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs
index 68cd3c28676..f5e18e98436 100644
--- a/src/libsyntax/ext/placeholders.rs
+++ b/src/libsyntax/ext/placeholders.rs
@@ -199,7 +199,10 @@ impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> {
 
         if let ast::IsAsync::Async { ref mut arguments, .. } = a {
             for argument in arguments.iter_mut() {
-                self.next_id(&mut argument.stmt.id);
+                self.next_id(&mut argument.move_stmt.id);
+                if let Some(ref mut pat_stmt) = &mut argument.pat_stmt {
+                    self.next_id(&mut pat_stmt.id);
+                }
             }
         }
     }