From 85efae7302e9249bb29a6098f342ab176d0d63aa Mon Sep 17 00:00:00 2001 From: ismailarilik Date: Mon, 5 May 2025 19:06:15 +0300 Subject: [PATCH 1/7] Handle `rustc_query_system` cases of `rustc::potential_query_instability` lint --- compiler/rustc_query_system/src/dep_graph/graph.rs | 2 ++ compiler/rustc_query_system/src/dep_graph/serialized.rs | 2 ++ compiler/rustc_query_system/src/lib.rs | 2 +- compiler/rustc_query_system/src/query/job.rs | 4 ++++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 3ae56cef2c421..d4217e0aa5499 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -1433,6 +1433,8 @@ fn panic_on_forbidden_read(data: &DepGraphData, dep_node_index: DepN && let Some(nodes) = &data.current.nodes_in_current_session { // Try to find it among the nodes allocated so far in this session + // This is OK, there's only ever one node result possible so this is deterministic. + #[allow(rustc::potential_query_instability)] if let Some((node, _)) = nodes.lock().iter().find(|&(_, index)| *index == dep_node_index) { dep_node = Some(*node); } diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index f1b609a3ca906..79b99c52d0c01 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -784,6 +784,8 @@ impl EncoderState { ) { if let Some(record_stats) = &self.stats { let record_stats = record_stats.lock(); + // `stats` is sorted below so we can allow this lint here. + #[allow(rustc::potential_query_instability)] let mut stats: Vec<_> = record_stats.values().collect(); stats.sort_by_key(|s| -(s.node_counter as i64)); diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index eba7378b475ef..d36cb6f0e5b17 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -1,5 +1,5 @@ // tidy-alphabetical-start -#![allow(rustc::potential_query_instability, internal_features)] +#![allow(internal_features)] #![feature(assert_matches)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 6321abc5087f5..1e79bd461d2a4 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -510,6 +510,10 @@ pub fn break_query_cycles( registry: &rayon_core::Registry, ) { let mut wakelist = Vec::new(); + // It is OK per the comments: + // - https://github.com/rust-lang/rust/pull/131200#issuecomment-2798854932 + // - https://github.com/rust-lang/rust/pull/131200#issuecomment-2798866392 + #[allow(rustc::potential_query_instability)] let mut jobs: Vec = query_map.keys().cloned().collect(); let mut found_cycle = false; From 9da637a578dfc70da2d38e5a1a86263ae2f5da09 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Mon, 19 May 2025 15:37:31 +0300 Subject: [PATCH 2/7] skip compiler tools sanity checks on certain commands Signed-off-by: onur-ozkan --- src/bootstrap/src/core/sanity.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index eb7e3799a688d..af4ec679d080d 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -13,7 +13,6 @@ use std::ffi::{OsStr, OsString}; use std::path::PathBuf; use std::{env, fs}; -use crate::Build; #[cfg(not(test))] use crate::builder::Builder; use crate::builder::Kind; @@ -21,6 +20,7 @@ use crate::builder::Kind; use crate::core::build_steps::tool; use crate::core::config::Target; use crate::utils::exec::command; +use crate::{Build, Subcommand}; pub struct Finder { cache: HashMap>, @@ -205,6 +205,20 @@ than building it. .map(|s| s.to_string()) .collect(); + // Compiler tools like `cc` and `ar` are not configured for cross-targets on certain subcommands + // because they are not needed. + // + // See `cc_detect::find` for more details. + let skip_tools_checks = build.config.dry_run() + || matches!( + build.config.cmd, + Subcommand::Clean { .. } + | Subcommand::Check { .. } + | Subcommand::Suggest { .. } + | Subcommand::Format { .. } + | Subcommand::Setup { .. } + ); + // We're gonna build some custom C code here and there, host triples // also build some C++ shims for LLVM so we need a C++ compiler. for target in &build.targets { @@ -278,7 +292,7 @@ than building it. } } - if !build.config.dry_run() { + if !skip_tools_checks { cmd_finder.must_have(build.cc(*target)); if let Some(ar) = build.ar(*target) { cmd_finder.must_have(ar); @@ -286,7 +300,7 @@ than building it. } } - if !build.config.dry_run() { + if !skip_tools_checks { for host in &build.hosts { cmd_finder.must_have(build.cxx(*host).unwrap()); From c5bab6e9aa89e8596079dcec8c5a5e5365aa5440 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 19 May 2025 21:11:51 +0800 Subject: [PATCH 3/7] introduce common macro for `MutVisitor` and `Visitor` to dedup code --- compiler/rustc_ast/src/lib.rs | 1 + compiler/rustc_ast/src/mut_visit.rs | 37 ++----------- compiler/rustc_ast/src/visit.rs | 84 +++++++++++++++++++++++------ 3 files changed, 73 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 89a5a67eb5342..4fc7c7475d757 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -15,6 +15,7 @@ #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(if_let_guard)] +#![feature(macro_metavar_expr)] #![feature(negative_impls)] #![feature(never_type)] #![feature(rustdoc_internals)] diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index e49886721e364..a90349f318c09 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -20,7 +20,7 @@ use thin_vec::ThinVec; use crate::ast::*; use crate::ptr::P; use crate::tokenstream::*; -use crate::visit::{AssocCtxt, BoundKind, FnCtxt}; +use crate::visit::{AssocCtxt, BoundKind, FnCtxt, try_visit}; pub trait ExpectOne { fn expect_one(self, err: &'static str) -> A::Item; @@ -388,6 +388,8 @@ pub trait MutVisitor: Sized { } } +super::common_visitor_and_walkers!((mut) MutVisitor); + /// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful /// when using a `flat_map_*` or `filter_map_*` method within a `visit_` /// method. @@ -777,15 +779,6 @@ fn visit_defaultness(vis: &mut T, defaultness: &mut Defaultness) } } -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -fn visit_safety(vis: &mut T, safety: &mut Safety) { - match safety { - Safety::Unsafe(span) => vis.visit_span(span), - Safety::Safe(span) => vis.visit_span(span), - Safety::Default => {} - } -} - // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. fn visit_polarity(vis: &mut T, polarity: &mut ImplPolarity) { match polarity { @@ -794,14 +787,6 @@ fn visit_polarity(vis: &mut T, polarity: &mut ImplPolarity) { } } -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -fn visit_constness(vis: &mut T, constness: &mut Const) { - match constness { - Const::Yes(span) => vis.visit_span(span), - Const::No => {} - } -} - fn walk_closure_binder(vis: &mut T, binder: &mut ClosureBinder) { match binder { ClosureBinder::NotPresent => {} @@ -940,15 +925,6 @@ pub fn walk_flat_map_generic_param( smallvec![param] } -fn walk_label(vis: &mut T, Label { ident }: &mut Label) { - vis.visit_ident(ident); -} - -fn walk_lifetime(vis: &mut T, Lifetime { id, ident }: &mut Lifetime) { - vis.visit_id(id); - vis.visit_ident(ident); -} - fn walk_generics(vis: &mut T, generics: &mut Generics) { let Generics { params, where_clause, span } = generics; params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); @@ -1340,13 +1316,6 @@ fn walk_const_item(vis: &mut T, item: &mut ConstItem) { walk_define_opaques(vis, define_opaque); } -fn walk_fn_header(vis: &mut T, header: &mut FnHeader) { - let FnHeader { safety, coroutine_kind, constness, ext: _ } = header; - visit_constness(vis, constness); - coroutine_kind.as_mut().map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind)); - visit_safety(vis, safety); -} - pub fn walk_crate(vis: &mut T, krate: &mut Crate) { let Crate { attrs, items, spans, id, is_placeholder: _ } = krate; vis.visit_id(id); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 69a186c8cf1b7..e43d7ae065d9e 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -315,6 +315,75 @@ pub trait Visitor<'ast>: Sized { } } +#[macro_export] +macro_rules! common_visitor_and_walkers { + ($(($mut: ident))? $Visitor:ident$(<$lt:lifetime>)?) => { + // this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier + $(${ignore($lt)} + #[expect(unused, rustc::pass_by_value)] + #[inline] + )? + fn visit_span<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, span: &$($lt)? $($mut)? Span) $(-> >::Result)? { + $( + let _ = stringify!($mut); + visitor.visit_span(span); + )? + $(${ignore($lt)}V::Result::output())? + } + + // this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier + $(${ignore($lt)} + #[expect(unused, rustc::pass_by_value)] + #[inline] + )? + fn visit_id<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, id: &$($lt)? $($mut)? NodeId) $(-> >::Result)? { + $( + let _ = stringify!($mut); + visitor.visit_id(id); + )? + $(${ignore($lt)}V::Result::output())? + } + + // this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier + fn visit_safety<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, safety: &$($lt)? $($mut)? Safety) $(-> >::Result)? { + match safety { + Safety::Unsafe(span) => visit_span(vis, span), + Safety::Safe(span) => visit_span(vis, span), + Safety::Default => { $(${ignore($lt)}V::Result::output())? } + } + } + + fn visit_constness<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, constness: &$($lt)? $($mut)? Const) $(-> >::Result)? { + match constness { + Const::Yes(span) => visit_span(vis, span), + Const::No => { + $(>::Result::output())? + } + } + } + + pub fn walk_label<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, Label { ident }: &$($lt)? $($mut)? Label) $(-> >::Result)? { + visitor.visit_ident(ident) + } + + pub fn walk_fn_header<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, header: &$($lt)? $($mut)? FnHeader) $(-> >::Result)? { + let FnHeader { safety, coroutine_kind, constness, ext: _ } = header; + try_visit!(visit_constness(visitor, constness)); + if let Some(coroutine_kind) = coroutine_kind { + try_visit!(visitor.visit_coroutine_kind(coroutine_kind)); + } + visit_safety(visitor, safety) + } + + pub fn walk_lifetime<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, Lifetime { id, ident }: &$($lt)? $($mut)? Lifetime) $(-> >::Result)? { + try_visit!(visit_id(visitor, id)); + visitor.visit_ident(ident) + } + }; +} + +common_visitor_and_walkers!(Visitor<'a>); + pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) -> V::Result { let Crate { attrs, items, spans: _, id: _, is_placeholder: _ } = krate; walk_list!(visitor, visit_attribute, attrs); @@ -334,15 +403,6 @@ pub fn walk_local<'a, V: Visitor<'a>>(visitor: &mut V, local: &'a Local) -> V::R V::Result::output() } -pub fn walk_label<'a, V: Visitor<'a>>(visitor: &mut V, Label { ident }: &'a Label) -> V::Result { - visitor.visit_ident(ident) -} - -pub fn walk_lifetime<'a, V: Visitor<'a>>(visitor: &mut V, lifetime: &'a Lifetime) -> V::Result { - let Lifetime { id: _, ident } = lifetime; - visitor.visit_ident(ident) -} - pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef) -> V::Result where V: Visitor<'a>, @@ -926,12 +986,6 @@ pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FnRetTy) V::Result::output() } -pub fn walk_fn_header<'a, V: Visitor<'a>>(visitor: &mut V, fn_header: &'a FnHeader) -> V::Result { - let FnHeader { safety: _, coroutine_kind, constness: _, ext: _ } = fn_header; - visit_opt!(visitor, visit_coroutine_kind, coroutine_kind.as_ref()); - V::Result::output() -} - pub fn walk_fn_decl<'a, V: Visitor<'a>>( visitor: &mut V, FnDecl { inputs, output }: &'a FnDecl, From 8286487c0ceef102e162d39d0c75adc1e3068b6c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 19 May 2025 15:18:24 +0200 Subject: [PATCH 4/7] fix data race in ReentrantLock fallback for targets without 64bit atomics --- library/std/src/sync/reentrant_lock.rs | 8 ++++++-- .../miri/tests/many-seeds/reentrant-lock.rs | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 src/tools/miri/tests/many-seeds/reentrant-lock.rs diff --git a/library/std/src/sync/reentrant_lock.rs b/library/std/src/sync/reentrant_lock.rs index 24539d4e8303d..96a4cf12659cc 100644 --- a/library/std/src/sync/reentrant_lock.rs +++ b/library/std/src/sync/reentrant_lock.rs @@ -136,7 +136,7 @@ cfg_if!( // we only ever read from the tid if `tls_addr` matches the current // TLS address. In that case, either the tid has been set by // the current thread, or by a thread that has terminated before - // the current thread was created. In either case, no further + // the current thread's `tls_addr` was allocated. In either case, no further // synchronization is needed (as per ) tls_addr: Atomic, tid: UnsafeCell, @@ -154,8 +154,12 @@ cfg_if!( // NOTE: This assumes that `owner` is the ID of the current // thread, and may spuriously return `false` if that's not the case. fn contains(&self, owner: ThreadId) -> bool { + // We must call `tls_addr()` *before* doing the load to ensure that if we reuse an + // earlier thread's address, the `tls_addr.load()` below happens-after everything + // that thread did. + let tls_addr = tls_addr(); // SAFETY: See the comments in the struct definition. - self.tls_addr.load(Ordering::Relaxed) == tls_addr() + self.tls_addr.load(Ordering::Relaxed) == tls_addr && unsafe { *self.tid.get() } == owner.as_u64().get() } diff --git a/src/tools/miri/tests/many-seeds/reentrant-lock.rs b/src/tools/miri/tests/many-seeds/reentrant-lock.rs new file mode 100644 index 0000000000000..8a363179a9cc7 --- /dev/null +++ b/src/tools/miri/tests/many-seeds/reentrant-lock.rs @@ -0,0 +1,19 @@ +#![feature(reentrant_lock)] +//! This is a regression test for +//! . + +use std::cell::Cell; +use std::sync::ReentrantLock; +use std::thread; + +static LOCK: ReentrantLock> = ReentrantLock::new(Cell::new(0)); + +fn main() { + for _ in 0..20 { + thread::spawn(move || { + let val = LOCK.lock(); + val.set(val.get() + 1); + drop(val); + }); + } +} From 26ea763f24754cf79191ad9ae949ad285f51c363 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 19 May 2025 15:22:31 +0200 Subject: [PATCH 5/7] add this to Miri's trophy case --- src/tools/miri/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index b692ddab4ffc8..122438a2509b3 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -580,6 +580,7 @@ Definite bugs found: * [Weak-memory-induced memory leak in Windows thread-local storage](https://github.com/rust-lang/rust/pull/124281) * [A bug in the new `RwLock::downgrade` implementation](https://rust-lang.zulipchat.com/#narrow/channel/269128-miri/topic/Miri.20error.20library.20test) (caught by Miri before it landed in the Rust repo) * [Mockall reading unintialized memory when mocking `std::io::Read::read`, even if all expectations are satisfied](https://github.com/asomers/mockall/issues/647) (caught by Miri running Tokio's test suite) +* [`ReentrantLock` not correctly dealing with reuse of addresses for TLS storage of different threads](https://github.com/rust-lang/rust/pull/141248) Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows is currently just an experiment): From 61059282eb9ea1f37804790b182e5821337924b4 Mon Sep 17 00:00:00 2001 From: Andrew Zhogin Date: Mon, 19 May 2025 21:14:28 +0700 Subject: [PATCH 6/7] Warning added when dependency crate has async drop types, and the feature is disabled --- compiler/rustc_interface/src/passes.rs | 1 + compiler/rustc_metadata/messages.ftl | 4 ++++ compiler/rustc_metadata/src/creader.rs | 21 +++++++++++++++++++ compiler/rustc_metadata/src/errors.rs | 10 +++++++++ compiler/rustc_metadata/src/rmeta/decoder.rs | 4 ++++ .../async-drop/dependency-dropped.rs | 5 ++++- ...ependency-dropped.with_feature.run.stdout} | 0 ...endency-dropped.without_feature.run.stdout | 1 + .../dependency-dropped.without_feature.stderr | 10 +++++++++ 9 files changed, 55 insertions(+), 1 deletion(-) rename tests/ui/async-await/async-drop/{dependency-dropped.run.stdout => dependency-dropped.with_feature.run.stdout} (100%) create mode 100644 tests/ui/async-await/async-drop/dependency-dropped.without_feature.run.stdout create mode 100644 tests/ui/async-await/async-drop/dependency-dropped.without_feature.stderr diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index e28639576f031..8f6c5b47ee23d 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -282,6 +282,7 @@ fn configure_and_expand( resolver.resolve_crate(&krate); CStore::from_tcx(tcx).report_incompatible_target_modifiers(tcx, &krate); + CStore::from_tcx(tcx).report_incompatible_async_drop_feature(tcx, &krate); krate } diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index d997ba198aca8..cac8f34b0fa0d 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -1,6 +1,10 @@ metadata_as_needed_compatibility = linking modifier `as-needed` is only compatible with `dylib` and `framework` linking kinds +metadata_async_drop_types_in_dependency = + found async drop types in dependecy `{$extern_crate}`, but async_drop feature is disabled for `{$local_crate}` + .help = if async drop type will be dropped in a crate without `feature(async_drop)`, sync Drop will be used + metadata_bad_panic_strategy = the linked panic runtime `{$runtime}` is not compiled with this crate's panic strategy `{$strategy}` diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 07fb2de8a3e0c..c7e9a2936f5dd 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -473,6 +473,27 @@ impl CStore { } } + // Report about async drop types in dependency if async drop feature is disabled + pub fn report_incompatible_async_drop_feature(&self, tcx: TyCtxt<'_>, krate: &Crate) { + if tcx.features().async_drop() { + return; + } + for (_cnum, data) in self.iter_crate_data() { + if data.is_proc_macro_crate() { + continue; + } + if data.has_async_drops() { + let extern_crate = data.name(); + let local_crate = tcx.crate_name(LOCAL_CRATE); + tcx.dcx().emit_warn(errors::AsyncDropTypesInDependency { + span: krate.spans.inner_span.shrink_to_lo(), + extern_crate, + local_crate, + }); + } + } + } + pub fn new(metadata_loader: Box) -> CStore { CStore { metadata_loader, diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index c45daeda85dbc..16f59793e6326 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -811,3 +811,13 @@ pub struct UnknownTargetModifierUnsafeAllowed { pub span: Span, pub flag_name: String, } + +#[derive(Diagnostic)] +#[diag(metadata_async_drop_types_in_dependency)] +#[help] +pub struct AsyncDropTypesInDependency { + #[primary_span] + pub span: Span, + pub extern_crate: Symbol, + pub local_crate: Symbol, +} diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index bd813cadedcd4..2e4352ca532aa 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1984,6 +1984,10 @@ impl CrateMetadata { self.root.header.hash } + pub(crate) fn has_async_drops(&self) -> bool { + self.root.tables.adt_async_destructor.len > 0 + } + fn num_def_ids(&self) -> usize { self.root.tables.def_keys.size() } diff --git a/tests/ui/async-await/async-drop/dependency-dropped.rs b/tests/ui/async-await/async-drop/dependency-dropped.rs index f763bb32b1733..c8670be4e8baa 100644 --- a/tests/ui/async-await/async-drop/dependency-dropped.rs +++ b/tests/ui/async-await/async-drop/dependency-dropped.rs @@ -1,9 +1,12 @@ //@ run-pass //@ check-run-results +//@ revisions: with_feature without_feature //@ aux-build:async-drop-dep.rs //@ edition:2021 -#![feature(async_drop)] +#![cfg_attr(with_feature, feature(async_drop))] +//[without_feature]~^ WARN found async drop types in dependecy `async_drop_dep`, but async_drop feature is disabled for `dependency_dropped` + #![allow(incomplete_features)] extern crate async_drop_dep; diff --git a/tests/ui/async-await/async-drop/dependency-dropped.run.stdout b/tests/ui/async-await/async-drop/dependency-dropped.with_feature.run.stdout similarity index 100% rename from tests/ui/async-await/async-drop/dependency-dropped.run.stdout rename to tests/ui/async-await/async-drop/dependency-dropped.with_feature.run.stdout diff --git a/tests/ui/async-await/async-drop/dependency-dropped.without_feature.run.stdout b/tests/ui/async-await/async-drop/dependency-dropped.without_feature.run.stdout new file mode 100644 index 0000000000000..80eeeefc2220f --- /dev/null +++ b/tests/ui/async-await/async-drop/dependency-dropped.without_feature.run.stdout @@ -0,0 +1 @@ +Sync drop diff --git a/tests/ui/async-await/async-drop/dependency-dropped.without_feature.stderr b/tests/ui/async-await/async-drop/dependency-dropped.without_feature.stderr new file mode 100644 index 0000000000000..56e49568e1004 --- /dev/null +++ b/tests/ui/async-await/async-drop/dependency-dropped.without_feature.stderr @@ -0,0 +1,10 @@ +warning: found async drop types in dependecy `async_drop_dep`, but async_drop feature is disabled for `dependency_dropped` + --> $DIR/dependency-dropped.rs:7:1 + | +LL | #![cfg_attr(with_feature, feature(async_drop))] + | ^ + | + = help: if async drop type will be dropped in a crate without `feature(async_drop)`, sync Drop will be used + +warning: 1 warning emitted + From a14e25c76832b16e48f293e8dcdd6c889e4f6402 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 19 May 2025 13:27:49 +0200 Subject: [PATCH 7/7] windows: document that we rely on an undocumented property of GetUserProfileDirectoryW --- library/std/src/sys/pal/windows/os.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/std/src/sys/pal/windows/os.rs b/library/std/src/sys/pal/windows/os.rs index f331282d2d72a..1ebbbec9e914f 100644 --- a/library/std/src/sys/pal/windows/os.rs +++ b/library/std/src/sys/pal/windows/os.rs @@ -202,6 +202,8 @@ fn home_dir_crt() -> Option { |buf, mut sz| { // GetUserProfileDirectoryW does not quite use the usual protocol for // negotiating the buffer size, so we have to translate. + // FIXME(#141254): We rely on the *undocumented* property that this function will + // always set the size, not just on failure. match c::GetUserProfileDirectoryW( ptr::without_provenance_mut(CURRENT_PROCESS_TOKEN), buf,