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

Document behavior of create_dir_all wrt. empty path #125112

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

tbu-
Copy link
Contributor

@tbu- tbu- commented May 14, 2024

The behavior makes sense because Path::new("one_component").parent() == Some(Path::new("")), so if one naively wants to create the parent directory for a file to be written, it simply works.

Closes #105108 by documenting the current behavior.

@rustbot
Copy link
Collaborator

rustbot commented May 14, 2024

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels May 14, 2024
@Mark-Simulacrum
Copy link
Member

r? dtolnay - technically a new stable guarantee, I think? So probably needs libs-api FCP.

@rustbot rustbot assigned dtolnay and unassigned Mark-Simulacrum May 19, 2024
@Mark-Simulacrum Mark-Simulacrum added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. and removed T-libs Relevant to the library team, which will review and decide on the PR/issue. labels May 19, 2024
@dtolnay
Copy link
Member

dtolnay commented May 20, 2024

@rust-lang/libs-api:
@rfcbot fcp merge

fs::create_dir_all("") does not try to create the current directory, even if the current directory does not exist. Is this the intended behavior? Can it be documented?

fn main() {
    let tempdir = tempfile::tempdir().unwrap();
    let repro = tempdir.path().join("repro");
    std::fs::create_dir(&repro).unwrap();
    std::env::set_current_dir(&repro).unwrap();
    std::fs::remove_dir(&repro).unwrap();
    std::fs::write(&repro, "").unwrap();
    std::fs::create_dir_all(&repro).unwrap_err(); // FAIL
    std::fs::create_dir_all("").unwrap(); // ok
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=39a021f969f8b24a38bd729535041664

@rfcbot
Copy link

rfcbot commented May 20, 2024

Team member @dtolnay has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels May 20, 2024
@dtolnay
Copy link
Member

dtolnay commented May 20, 2024

Our previous empty paths topic: #114149. In that case we decided not to regard the empty path as current dir for read_dir.

@dtolnay
Copy link
Member

dtolnay commented May 20, 2024

Interestingly fs::create_dir_all(".") does not try to create the current dir either, and fs::create_dir_all("./x") fails with "No such file or directory" if the current dir does not exist.

@tbu-
Copy link
Contributor Author

tbu- commented May 20, 2024

Our previous empty paths topic: #114149. In that case we decided not to regard the empty path as current dir for read_dir.

I'd add that this case is a bit different, because create_dir_all creates all the directories present in the given parameter. The empty string contains no directories to be created, so it can immediately return. This is different from e.g. create_dir which creates exactly one directory.

@tbu-
Copy link
Contributor Author

tbu- commented May 20, 2024

Interestingly fs::create_dir_all(".") does not try to create the current dir either, and fs::create_dir_all("./x") fails with "No such file or directory" if the current dir does not exist.

On Linux, mkdir . also seems to fail even when the current directory was unlinked:

$ mkdir .
mkdir: cannot create directory ‘.’: File exists

@BurntSushi
Copy link
Member

I think the wording here is a little vague. It says that it always "succeeds," but doesn't say what "succeeds" means. Can we elaborate on what success means for this case?

The behavior makes sense because `Path::new("one_component").parent() ==
Some(Path::new(""))`, so if one naively wants to create the parent
directory for a file to be written, it simply works.

Closes rust-lang#105108 by documenting the current behavior.
@tbu- tbu- force-pushed the pr_create_dir_all_empty branch from 04d2e35 to 6add5c9 Compare May 21, 2024 05:57
@tbu-
Copy link
Contributor Author

tbu- commented May 21, 2024

I think the wording here is a little vague. It says that it always "succeeds," but doesn't say what "succeeds" means. Can we elaborate on what success means for this case?

Done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

create_dir_all("") should complain about invalid filename
6 participants