about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs19
-rw-r--r--tests/pretty/shebang-at-top.pp12
-rw-r--r--tests/pretty/shebang-at-top.rs6
3 files changed, 37 insertions, 0 deletions
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 0bf5de3ef89..0d6c6951082 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -243,6 +243,11 @@ pub fn print_crate<'a>(
     let mut s =
         State { s: pp::Printer::new(), comments: Some(Comments::new(sm, filename, input)), ann };
 
+    // We need to print shebang before anything else
+    // otherwise the resulting code will not compile
+    // and shebang will be useless.
+    s.maybe_print_shebang();
+
     if is_expanded && !krate.attrs.iter().any(|attr| attr.has_name(sym::no_core)) {
         // We need to print `#![no_std]` (and its feature gate) so that
         // compiling pretty-printed source won't inject libstd again.
@@ -574,6 +579,20 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
         self.word(st)
     }
 
+    fn maybe_print_shebang(&mut self) {
+        if let Some(cmnt) = self.peek_comment() {
+            // Comment is a shebang if it's:
+            // Isolated, starts with #! and doesn't continue with `[`
+            // See [rustc_lexer::strip_shebang] and [gather_comments] from pprust/state.rs for details
+            if cmnt.style == CommentStyle::Isolated
+                && cmnt.lines.first().map_or(false, |l| l.starts_with("#!"))
+            {
+                let cmnt = self.next_comment().unwrap();
+                self.print_comment(cmnt);
+            }
+        }
+    }
+
     fn print_inner_attributes(&mut self, attrs: &[ast::Attribute]) -> bool {
         self.print_either_attributes(attrs, ast::AttrStyle::Inner, false, true)
     }
diff --git a/tests/pretty/shebang-at-top.pp b/tests/pretty/shebang-at-top.pp
new file mode 100644
index 00000000000..a2797252636
--- /dev/null
+++ b/tests/pretty/shebang-at-top.pp
@@ -0,0 +1,12 @@
+#!/usr/bin/env rust
+#![feature(prelude_import)]
+#![no_std]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+//@ pretty-mode:expanded
+//@ pp-exact:shebang-at-top.pp
+//@ pretty-compare-only
+
+fn main() {}
diff --git a/tests/pretty/shebang-at-top.rs b/tests/pretty/shebang-at-top.rs
new file mode 100644
index 00000000000..8bfa925fa1a
--- /dev/null
+++ b/tests/pretty/shebang-at-top.rs
@@ -0,0 +1,6 @@
+#!/usr/bin/env rust
+//@ pretty-mode:expanded
+//@ pp-exact:shebang-at-top.pp
+//@ pretty-compare-only
+
+fn main() {}