about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-06-15 20:01:37 +0000
committerbors <bors@rust-lang.org>2022-06-15 20:01:37 +0000
commit519d7484f3b1beb25dec9f2249adeaaa21033433 (patch)
tree1ef3bfd60915f0c75a4889283ddde41da7050f17
parentd39d520a210e5d92c7c5d7ad5b6e9ecd0a0a4f07 (diff)
parentc32f1332363fd719cade4b4b2a7ba885a3ded4e7 (diff)
downloadrust-519d7484f3b1beb25dec9f2249adeaaa21033433.tar.gz
rust-519d7484f3b1beb25dec9f2249adeaaa21033433.zip
Auto merge of #12545 - jeremyBanks:shebangs, r=Veykril
fix: inserted imports must come after a shebang if present

The current `insert_use` logic adds the first `use` item near the beginning of the file, only skipping past comments and whitespace. However, it does not skip leading [shebang lines](https://en.wikipedia.org/wiki/Shebang_\(Unix\)). This can produce a syntax error, as shebangs are only accepted (ignored) on the first line of the file.

### Before Insertion (valid syntax)

```rust
#!/usr/bin/env rust

fn main() {}
```

### After Insertion (invalid syntax)

```rust
use foo::bar::Baz;

#!/usr/bin/env rust

fn main() {}
```

Rust analyzer's grammar is already shebang-aware, so this PR just adds that to the array of SyntaxKinds that are skipped past when looking for an insertion location, and adds a corresponding test case.
-rw-r--r--crates/ide-db/src/imports/insert_use.rs3
-rw-r--r--crates/ide-db/src/imports/insert_use/tests.rs11
2 files changed, 13 insertions, 1 deletions
diff --git a/crates/ide-db/src/imports/insert_use.rs b/crates/ide-db/src/imports/insert_use.rs
index 66d0b2ee82c..d1cd3478197 100644
--- a/crates/ide-db/src/imports/insert_use.rs
+++ b/crates/ide-db/src/imports/insert_use.rs
@@ -403,7 +403,8 @@ fn insert_use_(
         .take_while(|child| match child {
             NodeOrToken::Node(node) => is_inner_attribute(node.clone()),
             NodeOrToken::Token(token) => {
-                [SyntaxKind::WHITESPACE, SyntaxKind::COMMENT].contains(&token.kind())
+                [SyntaxKind::WHITESPACE, SyntaxKind::COMMENT, SyntaxKind::SHEBANG]
+                    .contains(&token.kind())
             }
         })
         .filter(|child| child.as_token().map_or(true, |t| t.kind() != SyntaxKind::WHITESPACE))
diff --git a/crates/ide-db/src/imports/insert_use/tests.rs b/crates/ide-db/src/imports/insert_use/tests.rs
index 6569e4ed8c6..70a7a152321 100644
--- a/crates/ide-db/src/imports/insert_use/tests.rs
+++ b/crates/ide-db/src/imports/insert_use/tests.rs
@@ -455,6 +455,17 @@ use foo::bar::Baz;"#,
 }
 
 #[test]
+fn inserts_after_shebang() {
+    check_none(
+        "foo::bar::Baz",
+        "#!/usr/bin/env rust",
+        r#"#!/usr/bin/env rust
+
+use foo::bar::Baz;"#,
+    );
+}
+
+#[test]
 fn inserts_after_multiple_single_line_comments() {
     check_none(
         "foo::bar::Baz",