Setting up Rust with VS Code

There are many fantastic resources for learning Rust, but surprisingly there aren't many resources for setting up Rust in VS Code. Here's how I set up my IDE when I first started:

  1. Install Rust (Use this link to download the right version for your operating system. You may also have to download Xcode. On macOS, you can get this C compiler by typing: $ xcode-select --install into the terminal. If you're using a pc, you may have to download C++ build tools.

  2. Download Visual Studio

  3. Download The Right Extensions There are a few Rust extensions for VS Code. Surprisingly, you shouldn't download the Rust extension. You should instead download the Rust-analyzer. You can do so by searching for it in the extensions tab. Next, install Code Runner by searching in the extensions tab. It can also be helpful to download Better TOML (this helps you read TOML files). A helpful extension for debugging purposes is Code LLDB or the C/C++ (Windows) extension. To make sure all your crates are up to date, you can download the Crates extension. This displays the latest version of the crate next to it in the TOML file, as well as a few other nice features.

  4. Change Your Settings (Optional) Whilst not necessary, I think it's important to mention. This step can be the most confusing and frustrating because you may want to turn off something that you don't even know the name of. There are a few, in my opinion, annoying features that get in the way. This is something called inlay hints. They are the white highlighted text. They are not part of your code, but rather indicate what type of object you should consider using. They can be really helpful in certain situations, so I'd make them off until pressed. You can do this by going to settings and searching Editor > Inlay Hints. If you do this, you can press control alt to see the inlay hints whenever you want them! Another feature that may confuse you is auto imports. You start coding your first Rust program and you go to run it. But there's an error. You are importing a function that does not exist. What's strange is that you know that you didn't write that import statement. What happened? Well, at some point you might have called a function that you don't have access to. This prompted the auto import feature to include a function that doesn't exist. The issue is that after you fix your mistake the import statement stays around and causes an error. Some coders (especially those coding in Java Script) find this feature helpful. If you want to turn it off, go to settings and search Rust-analyzer › Completion › Autoimport and disable it. You can also go into settings and search Files: Auto Save and change it to afterDelay if you don't want to manually save after edits. Finally, by default Rust-analyzer uses cargo check to check your source code on save for errors. You can change this to clippy (this checks for all the cargo check errors as well as a bunch of common mistakes / broken Rust style conventions). To do this go to extensions, rust-analyzer, extension settings, search check on save and change check to clippy. Because clippy checks for more errors than cargo check it may take more time to process.

  5. Change Your Settings (Mandatory) Finally, the most important and strangely hidden setting that you must change to have VS Code running properly is changing how Code Runner actually runs your code. Many people have tried coding the Guessing Game activity from the Rust book. Their code resulted in errors even when they copy and pasted the solution (1) (2). There have been many "answers" as to why this is happening. None of them are correct. You need to go to extensions, Code Runner, press the gear, Extension Settings, Code-runner: Executor Map (edit in settings.json), and finally change "rust": "cd $dir && rustc $fileName && $dir$fileNameWithoutExt" to "rust": "cargo run # $fileName". This makes Code Runner load the crates you need before you run the code, and will fix the error.

Is there anything I missed? Are there any other suggestions for beginners on how to set up VS Code for Rust? Please let me know in the comments and I'll add them to this post!

11 Likes

One addition:
Install the CodeLLDB (Linux, OSX) or C/C++ (Windows) extension if you don't want to println! debug your code all the time but rather use a fully featured debugger for step by step execution.

Edit:
Oh an maybe also the crates extension for automatic version checking of crates on crates.io

Editedit:
Also configure the rust-analyzer extension to use clippy on save rather than cargo check. This can be found under @ext:rust-lang.rust-analyzer and then Rust-analyzer > Check on Save: Command

7 Likes

What a helpful comment! I'll add these extensions/settings!

3 Likes

Rust community is so dope.

3 Likes

Using git lens extension, setup code runner to use cargo instead of rustc (google it), using crates extension to stay up to date to the latest crate version and their docs, the tabnine AI assistant has been cool.

2 Likes

Definitely!

I agree the type inlay hints are visual clutter, and better removed most of the time, but they can be useful when you want to quickly check a variable's type. They can be set to off by default, to be revealed with a keypress (oddly hard-coded to ctrl-alt/option) with this setting: "editor.inlayHints.enabled": "offUnlessPressed".

This isn't needed for writing Rust in VSCode. From a quick look at the README it seems to be a way to run code directly from the editor. I'd be interested to know how you use this, and what advantages you find it offers over just cargo run or cargo test in a terminal.

2 Likes

The off unless pressed is a great way to check a variable's type without the visual clutter! And yes, code runner basically just puts cargo run into the terminal.

2 Likes

This was hugely helpful, especially the plugin settings part. TY

1 Like

You're welcome!

I have installed it just now and do not see rust row. So I have added it myself. Is it correct?
Is absence correct ?
Is adding extra row correct?

    "rust": "cargo run # $fileName",
    ".vb": "cd $dir && vbc /nologo $fileName && $dir$fileNameWithoutExt",
    ".vbs": "cscript //Nologo",
    ".scala": "scala",
    ".jl": "julia",
    ".cr": "crystal",
    ".ml": "ocaml",
    ".exs": "elixir",
    ".hx": "haxe --cwd $dirWithoutTrailingSlash --run $fileNameWithoutExt",
    ".rkt": "racket",
    ".scm": "csi -script",
    ".ahk": "autohotkey",
    ".au3": "autoit3",
    ".kt": "cd $dir && kotlinc $fileName -include-runtime -d $fileNameWithoutExt.jar && java -jar $fileNameWithoutExt.jar",
    ".kts": "kotlinc -script",
    ".dart": "dart",
    ".pas": "cd $dir && fpc $fileName && $dir$fileNameWithoutExt",
    ".pp": "cd $dir && fpc $fileName && $dir$fileNameWithoutExt",
    ".d": "cd $dir && dmd $fileName && $dir$fileNameWithoutExt",
    ".hs": "runhaskell",
    ".nim": "nim compile --verbosity:0 --hints:off --run",
    ".csproj": "dotnet run --project",
    ".fsproj": "dotnet run --project",
    ".lisp": "sbcl --script",
    ".kit": "kitc --run",
    ".v": "v run",
    ".vsh": "v run",
    ".sass": "sass --style expanded",
    ".cu": "cd $dir && nvcc $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
    ".ring": "ring",
    ".sml": "cd $dir && sml $fileName"
1 Like

No, you are looking at the executor map by file extension. You want to change the setting titled: executor map. Here's what it should look like:

"code-runner.executorMap": {
        


        "javascript": "node",
        "java": "cd $dir && javac $fileName && java $fileNameWithoutExt",
        "c": "cd $dir && gcc $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
        "cpp": "cd $dir && g++ $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
        "objective-c": "cd $dir && gcc -framework Cocoa $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
        "php": "php",
        "python": "python -u",
        "perl": "perl",
        "perl6": "perl6",
        "ruby": "ruby",
        "go": "go run",
        "lua": "lua",
        "groovy": "groovy",
        "powershell": "powershell -ExecutionPolicy ByPass -File",
        "bat": "cmd /c",
        "shellscript": "bash",
        "fsharp": "fsi",
        "csharp": "scriptcs",
        "vbscript": "cscript //Nologo",
        "typescript": "ts-node",
        "coffeescript": "coffee",
        "scala": "scala",
        "swift": "swift",
        "julia": "julia",
        "crystal": "crystal",
        "ocaml": "ocaml",
        "r": "Rscript",
        "applescript": "osascript",
        "clojure": "lein exec",
        "haxe": "haxe --cwd $dirWithoutTrailingSlash --run $fileNameWithoutExt",
        "rust": "cargo run # $fileName",
        "racket": "racket",
        "scheme": "csi -script",
        "ahk": "autohotkey",
        "autoit": "autoit3",
        "dart": "dart",
        "pascal": "cd $dir && fpc $fileName && $dir$fileNameWithoutExt",
        "d": "cd $dir && dmd $fileName && $dir$fileNameWithoutExt",
        "haskell": "runhaskell",
        "nim": "nim compile --verbosity:0 --hints:off --run",
        "lisp": "sbcl --script",
        "kit": "kitc --run",
        "v": "v run",
        "sass": "sass --style expanded",
        "scss": "scss --style expanded",
        "less": "cd $dir && lessc $fileName $fileNameWithoutExt.css",
        "FortranFreeForm": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
        "fortran-modern": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
        "fortran_fixed-form": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
        "fortran": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
        "sml": "cd $dir && sml $fileName"
    }

You can try running a hello world program in the editor. If it runs you are good to go!

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.