Open2

[作って学ぶ]OSのしくみⅠ メモ

RR

rust-analyzer の設定

トラブル

p.55 のコードを VSCode で書くと以下のエラーが表示されました。

error[E0152]: found duplicate lang item panic_impl
--> src/main.rs:10:1
|
10 | / fn panic(info: &PanicInfo) -> ! {
11 | | loop {}
12 | | }
| |
^
|
= note: the lang item is first defined in crate std (which test depends on)
...

ターミナルで cargo check --target x86_64-unknown-uefi を実行すると発生しないエラーなのでなんとかしたいです。

原因

  • ポイント1: 今、main.rs#[no_std] をつけて no_std 環境にしています。no_std 環境では自前で panic_hanlder (panic! が呼ばれた時の挙動を定義) を書く必要があります。
  • ポイント2: rust-analyzer のデフォルトの check では、--all-targets オプションがつきます。これには test ターゲットも含まれます。test は std を利用します。
  • ポイント3: std には panic! が呼ばれた時の挙動として panic_impl が定義されています。

以上のポイントをまとめると、no_std 環境で自前で panic_hanlder を書いているのにもかかわらず、--all-targets オプションで test もターゲットに含めてしまい、test が依存している std の中の panic_impl と干渉してしまっているということです。

rust-analyzer のドキュメントを読むと、デフォルトで以下のコマンドを実行しているようです。

cargo check --quiet --workspace --message-format=json --all-targets --keep-going

https://rust-analyzer.github.io/book/configuration#cargo.buildScripts.overrideCommand

解決策

workspace の setting.json に以下を設定します。

{
    "rust-analyzer.cargo.allTargets": false, // --all-targets を外す
    "rust-analyzer.cargo.target": "x86_64-unknown-uefi" // target の指定
}

.cargo/config.toml を導入後

p.68 「Rust の便利機能を活用する」の .cargo/config.toml を導入した場合、target の設定が省略できて、以下のように書くこともできます。

ここではさらに cargo check の代わりに cargo clippy を利用するようにしています。

{
    "rust-analyzer.check.command": "clippy", // check の代わりに clippy を使う
    "rust-analyzer.cargo.allTargets": false
}
RR

no_std と rust-analyzer [調査中]

上記の設定を行って #[panic_handler] のついた関数をコメントアウトすると VSCode では特にエラーは出ませんが、ターミナルから以下を実行すると #[panic_handler] がないというエラーが出ました。

$ cargo clippy --target x86_64-unknown-uefi
    Checking wasabi v0.1.0 (/path/to/wasabi)
warning: unused import: `panic::PanicInfo`
 --> src/main.rs:7:5
  |
7 |     panic::PanicInfo,
  |     ^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

error: `#[panic_handler]` function required, but not found

warning: `wasabi` (bin "wasabi") generated 1 warning
error: could not compile `wasabi` (bin "wasabi") due to 1 previous error; 1 warning emitted

rust-analyzer が走らせているコマンドと上記のコマンドは同じはずですが、出力に差があります。
どうにか同じ挙動・出力にできるのでしょうか?