Funny Rust compiler behavior on Windows

Rust has many artifacts on Windows I already pointed earlier, for example, using the bright white to display error messages. Another one I found just recently:

error: the generated executable for the input file "C:\Users\sunil\projects\rust_bee\src\main.rs" conflicts with the existing directory "rb"

error: aborting due to 1 previous error

What's wrong here? Executable on Windows has extension 'exe'. However Rust ignores that and checks if it can be created without any extension and fails. The issue clear specifies that finding bugs should never stop, Rust compiler exists since 2015, but after 10 years still has childish bugs.

I can not reproduce with cargo init --name rb && cargo build, what commands are you running? And why do you have an rb directory in your target-dir?

I also can not reproduce if I manually create an rb directory under target\debug

Unfortunately, I do not use Cargo. My tool is 'rustc'. I invoke it using the script. I guess the bug wasn't found for a decade, because people use front end - Cargo.

Cargo is just a front end to rustc, so you are likely invoking rustc in a weird/unusual way. I can't tell from your script where you actually invoke rustc, what flags do you provide to it?

If you are a beginner in Rust (and since you're asking this question, you probably are) not using Cargo is a big mistake. Cargo is the standard way to build Rust code, unless your project has very specific requirements.

Please report bugs to github.com/rust-lang/rust, not the user forums where they typically will not be seen. Additionally, you need to provide more information as your bug does not repro:

> ls

    Directory: D:\code

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----          7/6/2026   3:03 PM                foobar
-a----          7/6/2026   3:03 PM             46 foobar.rs

> rustc foobar.rs

> ./foobar.exe
hello world

> ls

    Directory: D:\code

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----          7/6/2026   3:03 PM                foobar
-a----          7/6/2026   3:03 PM         136704 foobar.exe
-a----          7/6/2026   3:03 PM        1282048 foobar.pdb
-a----          7/6/2026   3:03 PM             46 foobar.rs


There was a topic in the user forum - when should I stop testing? I just illustrated that even Rust may have simple bugs after a decade. The intention of the topic was not in a bug reporting.

Here is an invocation command of rustc:

Command: "rustc" ["--color", "always", "-L", "all=..\crates", "--extern", "simzip", "--edition", "2024", "-o", "rb", "C:\Users\sunil\projects\rust_bee\src\main.rs"] in C:\Users\sunil\projects\rust_bee

As you can see, the difference of 'rustc' invocation was that in my case, I added '-o' option.

If you want those bugs to get fixed, then you should report them. If you only want to complain how Rust is buggy, then I'm not even sure it has place here.

Anyway what you describe isn't a bug but working as intended: executables end with .exe in Windows by convention only, and the -o flag in rustc specifies the exact file name. If you want the output file to be rb.exe, you need to say -o rb.exe.

I think your problem is the -o flag. I would expect -o rb to produce an executable named rb, not rb.exe, and this is the documented behavior so it isn't really a bug.

Is there a reason you can't set your crate name to rb and then pass --crate-name rb to rustc instead? This is how cargo invokes rustc.

I think this may also be a source of confusion for you. Windows executables can have different extensions, try running echo %pathext% in a command prompt to see one possible subset of recognized extensions. On my machine it does not list .scr which is another valid extension for screensavers.

Could you elaborate on why you added -o? That flag causes the generated binary to be created with the exact name that passed in, without the default extension, which is why the error was emitted: a binary called rb (without .exe) would have been created, but there's a directory called rb in that place.

I must also echo other's comments to ask you that you file tickets, once you've validated that it is actually a bug. You reference your earlier thread about the behavior of bolded text under Windows being white. Looked at it again and different people did a little bit of digging to figure out why the behavior was special cased back in 2016, but no one ended up filing a ticket, so I just did. If a ticket isn't filed, it won't get fixed. Not everyone in the team even visits this forums.

You caught the root cause. Indeed, Rust thinks that a generated file shouldn't have any extension, however in reality it can't generate an executable without exe extension.

I applied a simple work around, so it addressed the problem.

Thanks ryanavella and wesleywiser as usually an awesome work.

I do not want the bug was fixed because it's a good illustration for students.

PS

As you admitted, executable on Windows must have some extension.

An executable does not, in fact, have to have an extension on Windows to be run. This is disguised by many parts of the user interface layering (including CreateProcess) that attempt to route to various helper such as invoking cmd.exe for .bat or .cmd extensions. You can sometimes work around this by appending a ".", or for ShellExecute by setting the "class" parameter to "exefile" but Windows itself doesn't care.

But that's besides the point, because rustc can emit non-exe output, either not a binary or not a Windows platform binary, depending on the options you give it.

Even if you wanted it to guess (like it does by default) the point of "-o" is to override that guess, for example node plugins must have the extension ".node" despite being shared libraries.

Thanks a lot, really appreciate it. Otherwise, I have to switch in the dark mode on Windows to see error messages, but I hate the theme. Regarding this bug, since I have a work around, it doesn't bother me. So filing it is really optional for me. Thank you for understanding.

yes it can.

the error in OP is because there's an existing directory with a conflicting name. if you give it a file name without conflicts, it will happily generate a file without .exe suffix.

that's a windows thing, not a compiler thing.

granted, the msvc compiler frontend uses a special option /Fefilename, which translates to the linker option /out:filename.exe, but this is a microsoft special behavior, it's not the usual behavior of most cross-platform non-microsoft tools, unless the tool is claiming to be compatible with msvc compiler command line, such as clang-cl.

for example, gcc will not append the .exe suffix if you give it an explicit -o option, neither will clang (not clang-cl). and rustc isn't claiming to to compatible with msvc either.

even the microsoft linker will happily generate an output without .exe if you give it an /out:filename option.

you can play with these commands to see how msvc handles different output file names:

> rem compile only, no linking, /Fo is respected, /Fe is ignored
> cl /c /Fofoo /Febar test.c
> rem compile and link, /Fe is translated to /out: when invoking the linker
> cl /Fofoo /Febar test.c
> rem compile and link, but manual linker option /out: will override /Fe, no .exe appended
> cl /Fofoo /Febar test.c /link /out:baz

that's not a "bug". that's the behavior you have to take into account when you manually invoke the compiler.

for example, if I write my own build commands, I have to do something like this if I want the makefile to be portable:

ifeq ($(OS),Windows_NT)
    EXE_EXT = .exe
else
    EXE_EXT =
endif

TARGET = myprogram$(EXE_EXT)

alternatively, I can use cmake, which handles the platform specific suffix automatically:

add_executable(myprogram myprogram.c)

it's the similar case for rustc and cargo, if you invoke rustc in makefile or scripts, you should handle the platform specific behavior yourself. if you want a tool handle that for you, there's cargo.

I eager to see rustc command to generate an executable without exe extension on Windows. I would love to use it after.

Exact same command as you've used for this topic, except -o rb being replaced with -o not-previously-existing-file.

Is it your guess or you are confident?

It is correct. Although running the file will be quite hard; you can't do it from Explorer for example. I believe you can do it by invoking Windows APIs programatically.

So, you are also confident that using 'rustc' on Windows you can generate a file without extension. What is the value of your knowledge? Are you ready to put $1,000,000 on an escrow?

Why exactly are you so convinced that these people are wrong about this? It's a basic command. If you want to know if it works, run it yourself. There is no need for curiosity; literally all it takes is one file and one command. The file can be any valid Rust, and you already have the command. You don't need to get aggressive about information you can verify yourself in 30 seconds.