Skip to content

Commit 85c3989

Browse files
committed
Auto merge of #134677 - tgross35:rollup-ozoeyop, r=tgross35
Rollup of 4 pull requests Successful merges: - #129220 (Add platform docs for FreeBSD.) - #134659 (test-infra: improve compiletest and run-make-support symlink handling) - #134668 (Make sure we don't lose default struct value when formatting struct) - #134672 (Revert stabilization of the `#[coverage(..)]` attribute) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 66bb586 + 8fc4ba2 commit 85c3989

File tree

142 files changed

+969
-433
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

142 files changed

+969
-433
lines changed

Diff for: compiler/rustc_feature/src/accepted.rs

-3
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,6 @@ declare_features! (
157157
(accepted, const_refs_to_static, "1.83.0", Some(119618)),
158158
/// Allows implementing `Copy` for closures where possible (RFC 2132).
159159
(accepted, copy_closures, "1.26.0", Some(44490)),
160-
/// Allows function attribute `#[coverage(on/off)]`, to control coverage
161-
/// instrumentation of that function.
162-
(accepted, coverage_attribute, "CURRENT_RUSTC_VERSION", Some(84605)),
163160
/// Allows `crate` in paths.
164161
(accepted, crate_in_paths, "1.30.0", Some(45477)),
165162
/// Allows users to provide classes for fenced code block using `class:classname`.

Diff for: compiler/rustc_feature/src/builtin_attrs.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -480,9 +480,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
480480
template!(List: "address, kcfi, memory, thread"), DuplicatesOk,
481481
EncodeCrossCrate::No, experimental!(no_sanitize)
482482
),
483-
ungated!(
483+
gated!(
484484
coverage, Normal, template!(OneOf: &[sym::off, sym::on]),
485485
ErrorPreceding, EncodeCrossCrate::No,
486+
coverage_attribute, experimental!(coverage)
486487
),
487488

488489
ungated!(

Diff for: compiler/rustc_feature/src/unstable.rs

+3
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,9 @@ declare_features! (
447447
(unstable, coroutine_clone, "1.65.0", Some(95360)),
448448
/// Allows defining coroutines.
449449
(unstable, coroutines, "1.21.0", Some(43122)),
450+
/// Allows function attribute `#[coverage(on/off)]`, to control coverage
451+
/// instrumentation of that function.
452+
(unstable, coverage_attribute, "1.74.0", Some(84605)),
450453
/// Allows non-builtin attributes in inner attribute position.
451454
(unstable, custom_inner_attributes, "1.30.0", Some(54726)),
452455
/// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`.

Diff for: library/core/src/cmp.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ pub trait Eq: PartialEq<Self> {
348348
#[rustc_builtin_macro]
349349
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
350350
#[allow_internal_unstable(core_intrinsics, derive_eq, structural_match)]
351-
#[cfg_attr(bootstrap, allow_internal_unstable(coverage_attribute))]
351+
#[allow_internal_unstable(coverage_attribute)]
352352
pub macro Eq($item:item) {
353353
/* compiler built-in */
354354
}

Diff for: library/core/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,13 @@
107107
//
108108
// Library features:
109109
// tidy-alphabetical-start
110-
#![cfg_attr(bootstrap, feature(coverage_attribute))]
111110
#![cfg_attr(bootstrap, feature(do_not_recommend))]
112111
#![feature(array_ptr_get)]
113112
#![feature(asm_experimental_arch)]
114113
#![feature(const_eval_select)]
115114
#![feature(const_typed_swap)]
116115
#![feature(core_intrinsics)]
116+
#![feature(coverage_attribute)]
117117
#![feature(internal_impls_macro)]
118118
#![feature(ip)]
119119
#![feature(is_ascii_octdigit)]

Diff for: library/core/src/macros/mod.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1673,8 +1673,7 @@ pub(crate) mod builtin {
16731673
///
16741674
/// [the reference]: ../../../reference/attributes/testing.html#the-test-attribute
16751675
#[stable(feature = "rust1", since = "1.0.0")]
1676-
#[allow_internal_unstable(test, rustc_attrs)]
1677-
#[cfg_attr(bootstrap, allow_internal_unstable(coverage_attribute))]
1676+
#[allow_internal_unstable(test, rustc_attrs, coverage_attribute)]
16781677
#[rustc_builtin_macro]
16791678
pub macro test($item:item) {
16801679
/* compiler built-in */
@@ -1687,8 +1686,7 @@ pub(crate) mod builtin {
16871686
soft,
16881687
reason = "`bench` is a part of custom test frameworks which are unstable"
16891688
)]
1690-
#[allow_internal_unstable(test, rustc_attrs)]
1691-
#[cfg_attr(bootstrap, allow_internal_unstable(coverage_attribute))]
1689+
#[allow_internal_unstable(test, rustc_attrs, coverage_attribute)]
16921690
#[rustc_builtin_macro]
16931691
pub macro bench($item:item) {
16941692
/* compiler built-in */

Diff for: src/build_helper/src/fs/mod.rs

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//! Misc filesystem related helpers for use by bootstrap and tools.
2+
use std::fs::Metadata;
3+
use std::path::Path;
4+
use std::{fs, io};
5+
6+
#[cfg(test)]
7+
mod tests;
8+
9+
/// Helper to ignore [`std::io::ErrorKind::NotFound`], but still propagate other
10+
/// [`std::io::ErrorKind`]s.
11+
pub fn ignore_not_found<Op>(mut op: Op) -> io::Result<()>
12+
where
13+
Op: FnMut() -> io::Result<()>,
14+
{
15+
match op() {
16+
Ok(()) => Ok(()),
17+
Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(()),
18+
Err(e) => Err(e),
19+
}
20+
}
21+
22+
/// A wrapper around [`std::fs::remove_dir_all`] that can also be used on *non-directory entries*,
23+
/// including files and symbolic links.
24+
///
25+
/// - This will produce an error if the target path is not found.
26+
/// - Like [`std::fs::remove_dir_all`], this helper does not traverse symbolic links, will remove
27+
/// symbolic link itself.
28+
/// - This helper is **not** robust against races on the underlying filesystem, behavior is
29+
/// unspecified if this helper is called concurrently.
30+
/// - This helper is not robust against TOCTOU problems.
31+
///
32+
/// FIXME: this implementation is insufficiently robust to replace bootstrap's clean `rm_rf`
33+
/// implementation:
34+
///
35+
/// - This implementation currently does not perform retries.
36+
#[track_caller]
37+
pub fn recursive_remove<P: AsRef<Path>>(path: P) -> io::Result<()> {
38+
let path = path.as_ref();
39+
let metadata = fs::symlink_metadata(path)?;
40+
#[cfg(windows)]
41+
let is_dir_like = |meta: &fs::Metadata| {
42+
use std::os::windows::fs::FileTypeExt;
43+
meta.is_dir() || meta.file_type().is_symlink_dir()
44+
};
45+
#[cfg(not(windows))]
46+
let is_dir_like = fs::Metadata::is_dir;
47+
48+
if is_dir_like(&metadata) {
49+
fs::remove_dir_all(path)
50+
} else {
51+
try_remove_op_set_perms(fs::remove_file, path, metadata)
52+
}
53+
}
54+
55+
fn try_remove_op_set_perms<'p, Op>(mut op: Op, path: &'p Path, metadata: Metadata) -> io::Result<()>
56+
where
57+
Op: FnMut(&'p Path) -> io::Result<()>,
58+
{
59+
match op(path) {
60+
Ok(()) => Ok(()),
61+
Err(e) if e.kind() == io::ErrorKind::PermissionDenied => {
62+
let mut perms = metadata.permissions();
63+
perms.set_readonly(false);
64+
fs::set_permissions(path, perms)?;
65+
op(path)
66+
}
67+
Err(e) => Err(e),
68+
}
69+
}

Diff for: src/build_helper/src/fs/tests.rs

+214
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
#![deny(unused_must_use)]
2+
3+
use std::{env, fs, io};
4+
5+
use super::recursive_remove;
6+
7+
mod recursive_remove_tests {
8+
use super::*;
9+
10+
// Basic cases
11+
12+
#[test]
13+
fn nonexistent_path() {
14+
let tmpdir = env::temp_dir();
15+
let path = tmpdir.join("__INTERNAL_BOOTSTRAP_nonexistent_path");
16+
assert!(fs::symlink_metadata(&path).is_err_and(|e| e.kind() == io::ErrorKind::NotFound));
17+
assert!(recursive_remove(&path).is_err_and(|e| e.kind() == io::ErrorKind::NotFound));
18+
}
19+
20+
#[test]
21+
fn file() {
22+
let tmpdir = env::temp_dir();
23+
let path = tmpdir.join("__INTERNAL_BOOTSTRAP_file");
24+
fs::write(&path, b"").unwrap();
25+
assert!(fs::symlink_metadata(&path).is_ok());
26+
assert!(recursive_remove(&path).is_ok());
27+
assert!(fs::symlink_metadata(&path).is_err_and(|e| e.kind() == io::ErrorKind::NotFound));
28+
}
29+
30+
mod dir_tests {
31+
use super::*;
32+
33+
#[test]
34+
fn dir_empty() {
35+
let tmpdir = env::temp_dir();
36+
let path = tmpdir.join("__INTERNAL_BOOTSTRAP_dir_tests_dir_empty");
37+
fs::create_dir_all(&path).unwrap();
38+
assert!(fs::symlink_metadata(&path).is_ok());
39+
assert!(recursive_remove(&path).is_ok());
40+
assert!(
41+
fs::symlink_metadata(&path).is_err_and(|e| e.kind() == io::ErrorKind::NotFound)
42+
);
43+
}
44+
45+
#[test]
46+
fn dir_recursive() {
47+
let tmpdir = env::temp_dir();
48+
let path = tmpdir.join("__INTERNAL_BOOTSTRAP_dir_tests_dir_recursive");
49+
fs::create_dir_all(&path).unwrap();
50+
assert!(fs::symlink_metadata(&path).is_ok());
51+
52+
let file_a = path.join("a.txt");
53+
fs::write(&file_a, b"").unwrap();
54+
assert!(fs::symlink_metadata(&file_a).is_ok());
55+
56+
let dir_b = path.join("b");
57+
fs::create_dir_all(&dir_b).unwrap();
58+
assert!(fs::symlink_metadata(&dir_b).is_ok());
59+
60+
let file_c = dir_b.join("c.rs");
61+
fs::write(&file_c, b"").unwrap();
62+
assert!(fs::symlink_metadata(&file_c).is_ok());
63+
64+
assert!(recursive_remove(&path).is_ok());
65+
66+
assert!(
67+
fs::symlink_metadata(&file_a).is_err_and(|e| e.kind() == io::ErrorKind::NotFound)
68+
);
69+
assert!(
70+
fs::symlink_metadata(&dir_b).is_err_and(|e| e.kind() == io::ErrorKind::NotFound)
71+
);
72+
assert!(
73+
fs::symlink_metadata(&file_c).is_err_and(|e| e.kind() == io::ErrorKind::NotFound)
74+
);
75+
}
76+
}
77+
78+
/// Check that [`recursive_remove`] does not traverse symlinks and only removes symlinks
79+
/// themselves.
80+
///
81+
/// Symlink-to-file versus symlink-to-dir is a distinction that's important on Windows, but not
82+
/// on Unix.
83+
mod symlink_tests {
84+
use super::*;
85+
86+
#[cfg(unix)]
87+
#[test]
88+
fn unix_symlink() {
89+
let tmpdir = env::temp_dir();
90+
let path = tmpdir.join("__INTERNAL_BOOTSTRAP_symlink_tests_unix_symlink");
91+
let symlink_path =
92+
tmpdir.join("__INTERNAL_BOOTSTRAP__symlink_tests_unix_symlink_symlink");
93+
fs::write(&path, b"").unwrap();
94+
95+
assert!(fs::symlink_metadata(&path).is_ok());
96+
assert!(
97+
fs::symlink_metadata(&symlink_path)
98+
.is_err_and(|e| e.kind() == io::ErrorKind::NotFound)
99+
);
100+
101+
std::os::unix::fs::symlink(&path, &symlink_path).unwrap();
102+
103+
assert!(recursive_remove(&symlink_path).is_ok());
104+
105+
// Check that the symlink got removed...
106+
assert!(
107+
fs::symlink_metadata(&symlink_path)
108+
.is_err_and(|e| e.kind() == io::ErrorKind::NotFound)
109+
);
110+
// ... but pointed-to file still exists.
111+
assert!(fs::symlink_metadata(&path).is_ok());
112+
113+
fs::remove_file(&path).unwrap();
114+
}
115+
116+
#[cfg(windows)]
117+
#[test]
118+
fn windows_symlink_to_file() {
119+
let tmpdir = env::temp_dir();
120+
let path = tmpdir.join("__INTERNAL_BOOTSTRAP_symlink_tests_windows_symlink_to_file");
121+
let symlink_path = tmpdir
122+
.join("__INTERNAL_BOOTSTRAP_SYMLINK_symlink_tests_windows_symlink_to_file_symlink");
123+
fs::write(&path, b"").unwrap();
124+
125+
assert!(fs::symlink_metadata(&path).is_ok());
126+
assert!(
127+
fs::symlink_metadata(&symlink_path)
128+
.is_err_and(|e| e.kind() == io::ErrorKind::NotFound)
129+
);
130+
131+
std::os::windows::fs::symlink_file(&path, &symlink_path).unwrap();
132+
133+
assert!(recursive_remove(&symlink_path).is_ok());
134+
135+
// Check that the symlink-to-file got removed...
136+
assert!(
137+
fs::symlink_metadata(&symlink_path)
138+
.is_err_and(|e| e.kind() == io::ErrorKind::NotFound)
139+
);
140+
// ... but pointed-to file still exists.
141+
assert!(fs::symlink_metadata(&path).is_ok());
142+
143+
fs::remove_file(&path).unwrap();
144+
}
145+
146+
#[cfg(windows)]
147+
#[test]
148+
fn windows_symlink_to_dir() {
149+
let tmpdir = env::temp_dir();
150+
let path = tmpdir.join("__INTERNAL_BOOTSTRAP_symlink_tests_windows_symlink_to_dir");
151+
let symlink_path =
152+
tmpdir.join("__INTERNAL_BOOTSTRAP_symlink_tests_windows_symlink_to_dir_symlink");
153+
fs::create_dir_all(&path).unwrap();
154+
155+
assert!(fs::symlink_metadata(&path).is_ok());
156+
assert!(
157+
fs::symlink_metadata(&symlink_path)
158+
.is_err_and(|e| e.kind() == io::ErrorKind::NotFound)
159+
);
160+
161+
std::os::windows::fs::symlink_dir(&path, &symlink_path).unwrap();
162+
163+
assert!(recursive_remove(&symlink_path).is_ok());
164+
165+
// Check that the symlink-to-dir got removed...
166+
assert!(
167+
fs::symlink_metadata(&symlink_path)
168+
.is_err_and(|e| e.kind() == io::ErrorKind::NotFound)
169+
);
170+
// ... but pointed-to dir still exists.
171+
assert!(fs::symlink_metadata(&path).is_ok());
172+
173+
fs::remove_dir_all(&path).unwrap();
174+
}
175+
}
176+
177+
/// Read-only file and directories only need special handling on Windows.
178+
#[cfg(windows)]
179+
mod readonly_tests {
180+
use super::*;
181+
182+
#[test]
183+
fn overrides_readonly() {
184+
let tmpdir = env::temp_dir();
185+
let path = tmpdir.join("__INTERNAL_BOOTSTRAP_readonly_tests_overrides_readonly");
186+
187+
// In case of a previous failed test:
188+
if let Ok(mut perms) = fs::symlink_metadata(&path).map(|m| m.permissions()) {
189+
perms.set_readonly(false);
190+
fs::set_permissions(&path, perms).unwrap();
191+
fs::remove_file(&path).unwrap();
192+
}
193+
194+
fs::write(&path, b"").unwrap();
195+
196+
let mut perms = fs::symlink_metadata(&path).unwrap().permissions();
197+
perms.set_readonly(true);
198+
fs::set_permissions(&path, perms).unwrap();
199+
200+
// Check that file exists but is read-only, and that normal `std::fs::remove_file` fails
201+
// to delete the file.
202+
assert!(fs::symlink_metadata(&path).is_ok_and(|m| m.permissions().readonly()));
203+
assert!(
204+
fs::remove_file(&path).is_err_and(|e| e.kind() == io::ErrorKind::PermissionDenied)
205+
);
206+
207+
assert!(recursive_remove(&path).is_ok());
208+
209+
assert!(
210+
fs::symlink_metadata(&path).is_err_and(|e| e.kind() == io::ErrorKind::NotFound)
211+
);
212+
}
213+
}
214+
}

Diff for: src/build_helper/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
pub mod ci;
44
pub mod drop_bomb;
5+
pub mod fs;
56
pub mod git;
67
pub mod metrics;
78
pub mod stage0_parser;

Diff for: src/doc/rustc/src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
- [\*-nto-qnx-\*](platform-support/nto-qnx.md)
8282
- [*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md)
8383
- [*-unknown-hermit](platform-support/hermit.md)
84+
- [*-unknown-freebsd](platform-support/freebsd.md)
8485
- [\*-unknown-netbsd\*](platform-support/netbsd.md)
8586
- [*-unknown-openbsd](platform-support/openbsd.md)
8687
- [*-unknown-redox](platform-support/redox.md)

0 commit comments

Comments
 (0)