Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: will become in Rust 2024, the above code is using Rust 2021, so this should compile with no issue. Instead, this happened: <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<pNot needed </p</detailsI think the root cause is the lint , commenting it out would make the code compile: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
Thanks for the report! That should not happen. We did a so I don't know how this is even possible... any ideas? This seems to be some bad interaction with .
claim Hmmm, weird that crater run didn't catch this.
I posted a PR fixing this: . Does crater maybe restrict lints?
I don't think it does. Is this code part of the "nix" crate?
If you are asking if this problem originates from the nix crate, then yes, see
I am wondering whether the nix crate as published on fails to build with latest nightly due to this issue.
I think yes, the has been in Nix for a long time. One should be able to reproduce the build failure on a UNIX platform other than: I am currently on Linux, will try reproducing it on my mac tomorrow.
Looks like crater tested nix 0.26.4 and that failed already before the removevar/setvar change (). That's due to the which makes the build fail even when there are just warnings. I guess we can add this to the list of why having deny(warnings) in the code is considered bad practice.
I created an issue and a PR against nix-rust.
Yeah, we can reproduce this on macOS
The reason this was missed is a combination of and
WG-prioritization assigning priority (). label -I-prioritize +P-high
Fix already exists, just needs a review: .

Discussion:
} } <ins> fn emit_deprecated_safe_fn_call(&self, span: Span, kind: &UnsafeOpKind) -> bool { match kind { // Allow calls to deprecated-safe unsafe functions if the caller is // from an edition before 2024. &UnsafeOpKind::CallToUnsafeFunction(Some(id)) if !span.at_least_rust_2024() && self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) => { self.tcx.emit_node_span_lint( DEPRECATED_SAFE, self.hir_context, span, CallToDeprecatedSafeFnRequiresUnsafe { span, function: with_no_trimmed_paths!(self.tcx.def_path_str(id)), sub: CallToDeprecatedSafeFnRequiresUnsafeSub { left: span.shrink_to_lo(), right: span.shrink_to_hi(), }, }, ); true } _ => false, } } </ins> fn requires_unsafe(&mut self, span: Span, kind: UnsafeOpKind) { let unsafe_op_in_unsafe_fn_allowed = self.unsafe_op_in_unsafe_fn_allowed(); match self.safety_context {

} SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {} SafetyContext::UnsafeFn => { <del> // unsafe_op_in_unsafe_fn is disallowed kind.emit_unsafe_op_in_unsafe_fn_lint( self.tcx, self.hir_context, span, self.suggest_unsafe_block, ); self.suggest_unsafe_block = false; } SafetyContext::Safe => match kind { // Allow calls to deprecated-safe unsafe functions if the // caller is from an edition before 2024. UnsafeOpKind::CallToUnsafeFunction(Some(id)) if !span.at_least_rust_2024() && self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) => { self.tcx.emit_node_span_lint( DEPRECATED_SAFE, </del> <ins> let deprecated_safe_fn = self.emit_deprecated_safe_fn_call(span, &kind); if !deprecated_safe_fn { // unsafe_op_in_unsafe_fn is disallowed kind.emit_unsafe_op_in_unsafe_fn_lint( self.tcx, </ins> self.hir_context, span, <del> CallToDeprecatedSafeFnRequiresUnsafe { span, function: with_no_trimmed_paths!(self.tcx.def_path_str(id)), sub: CallToDeprecatedSafeFnRequiresUnsafeSub { left: span.shrink_to_lo(), right: span.shrink_to_hi(), }, }, ) </del> <ins> self.suggest_unsafe_block, ); self.suggest_unsafe_block = false; </ins> } <del> _ => kind.emit_requires_unsafe_err( self.tcx, span, self.hir_context, unsafe_op_in_unsafe_fn_allowed, ), }, </del> <ins> } SafetyContext::Safe => { let deprecated_safe_fn = self.emit_deprecated_safe_fn_call(span, &kind); if !deprecated_safe_fn { kind.emit_requires_unsafe_err( self.tcx, span, self.hir_context, unsafe_op_in_unsafe_fn_allowed, ); } } </ins> } }

<ins> error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block --> $DIR/unsafe-env.rs:15:9 | LL |         unsafe_fn(); |         ^^^^^^^^^^^ call to unsafe function | = note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668> = note: consult the function's documentation for information on how to avoid undefined behavior note: an unsafe function restricts its caller, but its body is safe by default --> $DIR/unsafe-env.rs:9:1 | LL | unsafe fn unsafe_fn() { | ^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here --> $DIR/unsafe-env.rs:8:8 | LL | #[deny(unsafe_op_in_unsafe_fn)] |        ^^^^^^^^^^^^^^^^^^^^^^ </ins> error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe function or block <del> --> $DIR/unsafe-env.rs:23:5 </del> <ins> --> $DIR/unsafe-env.rs:33:5 </ins> | LL |     unsafe_fn(); |     ^^^^^^^^^^^ call to unsafe function

= note: consult the function's documentation for information on how to avoid undefined behavior error: unnecessary `unsafe` block <del> --> $DIR/unsafe-env.rs:26:5 </del> <ins> --> $DIR/unsafe-env.rs:36:5 </ins> | LL |     unsafe { |     ^^^^^^ unnecessary `unsafe` block | note: the lint level is defined here <del> --> $DIR/unsafe-env.rs:11:8 </del> <ins> --> $DIR/unsafe-env.rs:21:8 </ins> | LL | #[deny(unused_unsafe)] |        ^^^^^^^^^^^^^ <del> error: aborting due to 2 previous errors </del> <ins> error: aborting due to 3 previous errors </ins> For more information about this error, try `rustc --explain E0133`.

<ins> error[E0133]: call to unsafe function `std::env::set_var` is unsafe and requires unsafe block --> $DIR/unsafe-env.rs:10:5 | LL |     env::set_var("FOO", "BAR"); |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function | = note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668> = note: consult the function's documentation for information on how to avoid undefined behavior note: an unsafe function restricts its caller, but its body is safe by default --> $DIR/unsafe-env.rs:9:1 | LL | unsafe fn unsafe_fn() { | ^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here --> $DIR/unsafe-env.rs:8:8 | LL | #[deny(unsafe_op_in_unsafe_fn)] |        ^^^^^^^^^^^^^^^^^^^^^^ error[E0133]: call to unsafe function `std::env::remove_var` is unsafe and requires unsafe block --> $DIR/unsafe-env.rs:12:5 | LL |     env::remove_var("FOO"); |     ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function | = note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668> = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block --> $DIR/unsafe-env.rs:15:9 | LL |         unsafe_fn(); |         ^^^^^^^^^^^ call to unsafe function | = note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668> = note: consult the function's documentation for information on how to avoid undefined behavior </ins> error[E0133]: call to unsafe function `set_var` is unsafe and requires unsafe block <del> --> $DIR/unsafe-env.rs:13:5 </del> <ins> --> $DIR/unsafe-env.rs:23:5 </ins> | LL |     env::set_var("FOO", "BAR"); |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function

= note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function `remove_var` is unsafe and requires unsafe block <del> --> $DIR/unsafe-env.rs:15:5 </del> <ins> --> $DIR/unsafe-env.rs:25:5 </ins> | LL |     env::remove_var("FOO"); |     ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function

= note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block <del> --> $DIR/unsafe-env.rs:23:5 </del> <ins> --> $DIR/unsafe-env.rs:33:5 </ins> | LL |     unsafe_fn(); |     ^^^^^^^^^^^ call to unsafe function

= note: consult the function's documentation for information on how to avoid undefined behavior error: unnecessary `unsafe` block <del> --> $DIR/unsafe-env.rs:26:5 </del> <ins> --> $DIR/unsafe-env.rs:36:5 </ins> | LL |     unsafe { |     ^^^^^^ unnecessary `unsafe` block | note: the lint level is defined here <del> --> $DIR/unsafe-env.rs:11:8 </del> <ins> --> $DIR/unsafe-env.rs:21:8 </ins> | LL | #[deny(unused_unsafe)] |        ^^^^^^^^^^^^^ <del> error: aborting due to 4 previous errors </del> <ins> error: aborting due to 7 previous errors </ins> For more information about this error, try `rustc --explain E0133`.

use std::env; <del> unsafe fn unsafe_fn() {} </del> <ins> #[deny(unsafe_op_in_unsafe_fn)] unsafe fn unsafe_fn() { env::set_var("FOO", "BAR"); //[e2024]~^ ERROR call to unsafe function `std::env::set_var` is unsafe env::remove_var("FOO"); //[e2024]~^ ERROR call to unsafe function `std::env::remove_var` is unsafe if false { unsafe_fn(); //~^ ERROR call to unsafe function `unsafe_fn` is unsafe } } </ins> fn safe_fn() {} #[deny(unused_unsafe)]