Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Canonicalize rust-project.json manifest path #14430

Merged
merged 1 commit into from
Mar 29, 2023

Conversation

Veykril
Copy link
Member

@Veykril Veykril commented Mar 29, 2023

Looked a bit more into this and I think we can do this after all, I don't see any place where this should break things
cc #14168 #14402 (comment)

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 29, 2023
@Veykril
Copy link
Member Author

Veykril commented Mar 29, 2023

@bors r+

@bors
Copy link
Collaborator

bors commented Mar 29, 2023

📌 Commit f1de133 has been approved by Veykril

It is now in the queue for this repository.

@bors
Copy link
Collaborator

bors commented Mar 29, 2023

⌛ Testing commit f1de133 with merge 0d1ed56...

@bors
Copy link
Collaborator

bors commented Mar 29, 2023

☀️ Test successful - checks-actions
Approved by: Veykril
Pushing 0d1ed56 to master...

1 similar comment
@bors
Copy link
Collaborator

bors commented Mar 29, 2023

☀️ Test successful - checks-actions
Approved by: Veykril
Pushing 0d1ed56 to master...

@bors bors merged commit 0d1ed56 into rust-lang:master Mar 29, 2023
@bors
Copy link
Collaborator

bors commented Mar 29, 2023

👀 Test was successful, but fast-forwarding failed: 422 Changes must be made through a pull request.

@shadows-withal
Copy link
Member

This might have Possibly™️ broken our usage in Rustlings - see rust-lang/rustlings#1462


/// Equivalent of [`Path::canonicalize`] for `ManifestPath`.
pub fn canonicalize(&self) -> Result<ManifestPath, std::io::Error> {
Ok((&**self).canonicalize()?.try_into().unwrap())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So one thing I've learned from alexchrichton is that path canonicalization is a very fragile thing. It is not particularly well-defined operation, and, in practice, can create broken paths on windows.

The rule-of-thumb for robust software is to use user-supplied paths as is.

If the user gives you foo/bar/../baz/quux, you don't ask them why, but rather just relay the path as is to the operating systems. User believes that this particular path works, but any alias of this path might as well be broken.

Looking at #14168, I think I disagree that rust-analyzer needs any specific treatment for symlinks. If there's ./foo/rust-project.json, and it mentions ./src/lib.rs, then rust-analyzer should look into ./foo/src/lib.rs regardless of whether ./foo/rust-project.json is a real file, symlink, hardlink, or a mirage summoned by a fuse file system.

Can we special case meson? If it always puts rust-project.json into a specific build directory, we can probe that path. Messon is a fairly popular tool. But, from reading the docs, it seems that there's no standard build directory, and each project can use whatever name?

I think for Cargo.toml we do two-level search, I guess we can do the same for messon?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, eg, make treats symlinks this way:

19:34:58|~/tmp
λ exa -l
lrwxrwxrwx 17 matklad  3 May 19:25 Makefile -> ./subdir/Makefile
drwxr-xr-x  - matklad  3 May 19:34 subdir

19:35:00|~/tmp
λ bat Makefile
.PHONY: path
path:
    realpath .
    pwd

19:35:03|~/tmp
λ make path
realpath .
/home/matklad/tmp
pwd
/home/matklad/tmp

19:35:06|~/tmp
λ cd subdir

19:35:09|~/tmp/subdir
λ make path
realpath .
/home/matklad/tmp/subdir
pwd
/home/matklad/tmp/subdir

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, after having looked at this (and the issues it caused, where for windows we get nice NT paths for no reason after canonicalizing), I'm also on the ship of not handling symlinks in any way. It is causing too much of a headache.

I believe meson currently works without it again (by emitting absolute paths), so we should be able to just revert this as is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we should be able to just revert this as is.

Let's rather do

fn canonicalize(&self) -> ! {
    panic!("We explicitly do not provide canonicalization API, as that is almost always a wrong solution, see #14430")
}

Also, some prior art here: https://stackoverflow.com/questions/72898205/clang-tidy-10-and-compile-commands-json-does-not-support-relative-paths

TL;DR: clang requires absolute paths

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, I actually had the same idea of keeping the method with a panic behavior 😄

I think requiring absolute paths everywhere in rust-project.json would be a good idea in general. The format is meant to be generated by tooling anyways so the tool can always generate absolute paths instead.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we special case meson? If it always puts rust-project.json into a specific build directory, we can probe that path. Messon is a fairly popular tool. But, from reading the docs, it seems that there's no standard build directory, and each project can use whatever name?

Well, tbh there's not precisely a standard build directory for cargo either. ;) Even target/ is not enforced, so external tools interacting with cargo would have to know how cargo was invoked as well as the global cargo config file to detect where the build directory is. It's common for people to have a builddir-debug/ and builddir-release/ profile for meson build directories.

I believe meson currently works without it again (by emitting absolute paths), so we should be able to just revert this as is.

Yes, this bugfix was released in meson 1.1.0 (mesonbuild/meson@36e2c86) and backported to 1.0.2 (mesonbuild/meson@6a58ef7), so rust-analyzer should not need to guess or special-case meson as long as "use a modern version of the toolchain" is an acceptable answer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What we aim for here is to "just work" in 90% of the cases. To work in 100% of the cases, the user can always specify config explicitly. So just a default name for a build directory would be enough here, it doesn't need to be one true name. But I guess just two level search would solve this as well.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect in the majority of cases, given a project ./, checking for ./*/rust-project.json and accepting it if the glob only expands to a single name, will work well.

bors added a commit that referenced this pull request May 13, 2023
internal: Forbid canonicalization of paths and normalize all rust-project.json paths

Closes #14728
cc #14430

- Removes canonicalization (and forbids it from being used in a sense, clippy could help here again with its lint in the future)
- Normalizes all paths in rust-project.json which we weren't doing in some cases
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants