Skip to content

Commit ebe145e

Browse files
committed
Auto merge of #147900 - Zalathar:rollup-ril6jsi, r=Zalathar
Rollup of 3 pull requests Successful merges: - #146167 (Deny-by-default never type lints) - #147382 (unused_must_use: Don't warn on `Result<(), Uninhabited>` or `ControlFlow<Uninhabited, ()>`) - #147821 (Do not GC the current active incremental session directory) r? `@ghost` `@rustbot` modify labels: rollup
2 parents c0c37ca + 95279f9 commit ebe145e

34 files changed

+453
-409
lines changed

compiler/rustc_incremental/src/persist/fs.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,11 +721,37 @@ pub(crate) fn garbage_collect_session_directories(sess: &Session) -> io::Result<
721721
}
722722
}
723723

724+
let current_session_directory_name =
725+
session_directory.file_name().expect("session directory is not `..`");
726+
724727
// Now garbage collect the valid session directories.
725728
let deletion_candidates =
726729
lock_file_to_session_dir.items().filter_map(|(lock_file_name, directory_name)| {
727730
debug!("garbage_collect_session_directories() - inspecting: {}", directory_name);
728731

732+
if directory_name.as_str() == current_session_directory_name {
733+
// Skipping our own directory is, unfortunately, important for correctness.
734+
//
735+
// To summarize #147821: we will try to lock directories before deciding they can be
736+
// garbage collected, but the ability of `flock::Lock` to detect a lock held *by the
737+
// same process* varies across file locking APIs. Then, if our own session directory
738+
// has become old enough to be eligible for GC, we are beholden to platform-specific
739+
// details about detecting the our own lock on the session directory.
740+
//
741+
// POSIX `fcntl(F_SETLK)`-style file locks are maintained across a process. On
742+
// systems where this is the mechanism for `flock::Lock`, there is no way to
743+
// discover if an `flock::Lock` has been created in the same process on the same
744+
// file. Attempting to set a lock on the lockfile again will succeed, even if the
745+
// lock was set by another thread, on another file descriptor. Then we would
746+
// garbage collect our own live directory, unable to tell it was locked perhaps by
747+
// this same thread.
748+
//
749+
// It's not clear that `flock::Lock` can be fixed for this in general, and our own
750+
// incremental session directory is the only one which this process may own, so skip
751+
// it here and avoid the problem. We know it's not garbage anyway: we're using it.
752+
return None;
753+
}
754+
729755
let Ok(timestamp) = extract_timestamp_from_session_dir(directory_name) else {
730756
debug!(
731757
"found session-dir with malformed timestamp: {}",

compiler/rustc_lint/src/unused.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,13 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
273273
expr: &hir::Expr<'_>,
274274
span: Span,
275275
) -> Option<MustUsePath> {
276-
if ty.is_unit()
277-
|| !ty.is_inhabited_from(
278-
cx.tcx,
279-
cx.tcx.parent_module(expr.hir_id).to_def_id(),
280-
cx.typing_env(),
281-
)
282-
{
276+
if ty.is_unit() {
277+
return Some(MustUsePath::Suppressed);
278+
}
279+
let parent_mod_did = cx.tcx.parent_module(expr.hir_id).to_def_id();
280+
let is_uninhabited =
281+
|t: Ty<'tcx>| !t.is_inhabited_from(cx.tcx, parent_mod_did, cx.typing_env());
282+
if is_uninhabited(ty) {
283283
return Some(MustUsePath::Suppressed);
284284
}
285285

@@ -293,6 +293,22 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
293293
is_ty_must_use(cx, pinned_ty, expr, span)
294294
.map(|inner| MustUsePath::Pinned(Box::new(inner)))
295295
}
296+
// Suppress warnings on `Result<(), Uninhabited>` (e.g. `Result<(), !>`).
297+
ty::Adt(def, args)
298+
if cx.tcx.is_diagnostic_item(sym::Result, def.did())
299+
&& args.type_at(0).is_unit()
300+
&& is_uninhabited(args.type_at(1)) =>
301+
{
302+
Some(MustUsePath::Suppressed)
303+
}
304+
// Suppress warnings on `ControlFlow<Uninhabited, ()>` (e.g. `ControlFlow<!, ()>`).
305+
ty::Adt(def, args)
306+
if cx.tcx.is_diagnostic_item(sym::ControlFlow, def.did())
307+
&& args.type_at(1).is_unit()
308+
&& is_uninhabited(args.type_at(0)) =>
309+
{
310+
Some(MustUsePath::Suppressed)
311+
}
296312
ty::Adt(def, _) => is_def_must_use(cx, def.did(), span),
297313
ty::Alias(ty::Opaque | ty::Projection, ty::AliasTy { def_id: def, .. }) => {
298314
elaborate(cx.tcx, cx.tcx.explicit_item_self_bounds(def).iter_identity_copied())

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4065,7 +4065,6 @@ declare_lint! {
40654065
/// ### Example
40664066
///
40674067
/// ```rust,compile_fail
4068-
/// #![deny(never_type_fallback_flowing_into_unsafe)]
40694068
/// fn main() {
40704069
/// if true {
40714070
/// // return has type `!` which, is some cases, causes never type fallback
@@ -4100,7 +4099,7 @@ declare_lint! {
41004099
/// [`!`]: https://doc.rust-lang.org/core/primitive.never.html
41014100
/// [`()`]: https://doc.rust-lang.org/core/primitive.unit.html
41024101
pub NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE,
4103-
Warn,
4102+
Deny,
41044103
"never type fallback affecting unsafe function calls",
41054104
@future_incompatible = FutureIncompatibleInfo {
41064105
reason: FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange(Edition::Edition2024),
@@ -4122,7 +4121,7 @@ declare_lint! {
41224121
/// ### Example
41234122
///
41244123
/// ```rust,compile_fail,edition2021
4125-
/// #![deny(dependency_on_unit_never_type_fallback)]
4124+
/// # #![deny(dependency_on_unit_never_type_fallback)]
41264125
/// fn main() {
41274126
/// if true {
41284127
/// // return has type `!` which, is some cases, causes never type fallback
@@ -4155,7 +4154,7 @@ declare_lint! {
41554154
///
41564155
/// See [Tracking Issue for making `!` fall back to `!`](https://github.com/rust-lang/rust/issues/123748).
41574156
pub DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK,
4158-
Warn,
4157+
Deny,
41594158
"never type fallback affecting unsafe function calls",
41604159
@future_incompatible = FutureIncompatibleInfo {
41614160
reason: FutureIncompatibilityReason::EditionAndFutureReleaseError(Edition::Edition2024),

tests/ui/editions/never-type-fallback-breaking.e2021.fixed

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
//@[e2021] edition: 2021
44
//@[e2024] edition: 2024
55
//
6-
//@[e2021] run-pass
76
//@[e2021] run-rustfix
8-
//@[e2024] check-fail
97

108
fn main() {
119
m();
@@ -16,8 +14,8 @@ fn main() {
1614
}
1715

1816
fn m() {
19-
//[e2021]~^ WARN this function depends on never type fallback being `()`
20-
//[e2021]~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
17+
//[e2021]~^ error: this function depends on never type fallback being `()`
18+
//[e2021]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
2119
let x: () = match true {
2220
true => Default::default(),
2321
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
@@ -28,8 +26,8 @@ fn m() {
2826
}
2927

3028
fn q() -> Option<()> {
31-
//[e2021]~^ WARN this function depends on never type fallback being `()`
32-
//[e2021]~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
29+
//[e2021]~^ error: this function depends on never type fallback being `()`
30+
//[e2021]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
3331
fn deserialize<T: Default>() -> Option<T> {
3432
Some(T::default())
3533
}
@@ -45,8 +43,8 @@ fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
4543
Err(())
4644
}
4745
fn meow() -> Result<(), ()> {
48-
//[e2021]~^ WARN this function depends on never type fallback being `()`
49-
//[e2021]~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
46+
//[e2021]~^ error: this function depends on never type fallback being `()`
47+
//[e2021]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
5048
help::<(), _>(1)?;
5149
//[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
5250
Ok(())
@@ -57,8 +55,8 @@ pub fn takes_apit<T>(_y: impl Fn() -> T) -> Result<T, ()> {
5755
}
5856

5957
pub fn fallback_return() -> Result<(), ()> {
60-
//[e2021]~^ WARN this function depends on never type fallback being `()`
61-
//[e2021]~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
58+
//[e2021]~^ error: this function depends on never type fallback being `()`
59+
//[e2021]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
6260
takes_apit::<()>(|| Default::default())?;
6361
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
6462
Ok(())
@@ -71,8 +69,8 @@ fn mk<T>() -> Result<T, ()> {
7169
fn takes_apit2(_x: impl Default) {}
7270

7371
fn fully_apit() -> Result<(), ()> {
74-
//[e2021]~^ WARN this function depends on never type fallback being `()`
75-
//[e2021]~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
72+
//[e2021]~^ error: this function depends on never type fallback being `()`
73+
//[e2021]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
7674
takes_apit2(mk::<()>()?);
7775
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
7876
Ok(())

0 commit comments

Comments
 (0)