The API of `Path::exists()` encourages broken code

My personal experience isn't inline with the claim. There are a bunch of calls to Path::exists in rust-analyzer codebase:

I've briefly looked at them, and they all seem correct to me? Any API other than Path::exists would make these calls clunkier. I might be missing something of course -- all those occurrences are pretty shallow, so, if you can spot a bug, please send a PR with improvements :slight_smile:

The usages fall into thee categories:

Probing: try several different paths to find which one exists (eg, discover Cargo.toml in one of the parent directories). Returning an IO error here would result a user-visible bug, as the paths after the erroring one won't be probed at all.

Freshness Check: the application itself creates a path, and uses .exists to skip the work. Bailing with an io::Error out of .exists in this case wouldn't be outright wrong, but would suffer from TOCTOU. It's better to fail when you try to do a specific thing after .exists returned false, rather than during a pre-flight check.

Sanity Check: the path should exist, and, if it doesn't, the app bails. Here, there's no meaningful difference between io::Error and the thing not actually existing.

7 Likes