Skip to content

Commit bf41c00

Browse files
committed
Auto merge of rust-lang#127597 - jhpratt:rollup-yuypa59, r=jhpratt
Rollup of 3 pull requests Successful merges: - rust-lang#127097 (Implement simple, unstable lint to suggest turning closure-of-async-block into async-closure) - rust-lang#127153 (Initial implementation of anonymous_pipe API) - rust-lang#127572 (Don't mark `DEBUG_EVENT` struct as `repr(packed)`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 8c39ac9 + 0acaa2b commit bf41c00

File tree

21 files changed

+656
-23
lines changed

21 files changed

+656
-23
lines changed

compiler/rustc_lint/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ lint_cfg_attr_no_attributes =
185185
186186
lint_check_name_unknown_tool = unknown lint tool: `{$tool_name}`
187187
188+
lint_closure_returning_async_block = closure returning async block can be made into an async closure
189+
.label = this async block can be removed, and the closure can be turned into an async closure
190+
.suggestion = turn this into an async closure
191+
188192
lint_command_line_source = `forbid` lint level was set on command line
189193
190194
lint_confusable_identifier_pair = found both `{$existing_sym}` and `{$sym}` as identifiers, which look alike
+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
use rustc_hir as hir;
2+
use rustc_macros::{LintDiagnostic, Subdiagnostic};
3+
use rustc_session::{declare_lint, declare_lint_pass};
4+
use rustc_span::Span;
5+
6+
use crate::{LateContext, LateLintPass};
7+
8+
declare_lint! {
9+
/// The `closure_returning_async_block` lint detects cases where users
10+
/// write a closure that returns an async block.
11+
///
12+
/// ### Example
13+
///
14+
/// ```rust
15+
/// #![warn(closure_returning_async_block)]
16+
/// let c = |x: &str| async {};
17+
/// ```
18+
///
19+
/// {{produces}}
20+
///
21+
/// ### Explanation
22+
///
23+
/// Using an async closure is preferable over a closure that returns an
24+
/// async block, since async closures are less restrictive in how its
25+
/// captures are allowed to be used.
26+
///
27+
/// For example, this code does not work with a closure returning an async
28+
/// block:
29+
///
30+
/// ```rust,compile_fail
31+
/// async fn callback(x: &str) {}
32+
///
33+
/// let captured_str = String::new();
34+
/// let c = move || async {
35+
/// callback(&captured_str).await;
36+
/// };
37+
/// ```
38+
///
39+
/// But it does work with async closures:
40+
///
41+
/// ```rust
42+
/// #![feature(async_closure)]
43+
///
44+
/// async fn callback(x: &str) {}
45+
///
46+
/// let captured_str = String::new();
47+
/// let c = async move || {
48+
/// callback(&captured_str).await;
49+
/// };
50+
/// ```
51+
pub CLOSURE_RETURNING_ASYNC_BLOCK,
52+
Allow,
53+
"closure that returns `async {}` could be rewritten as an async closure",
54+
@feature_gate = async_closure;
55+
}
56+
57+
declare_lint_pass!(
58+
/// Lint for potential usages of async closures and async fn trait bounds.
59+
AsyncClosureUsage => [CLOSURE_RETURNING_ASYNC_BLOCK]
60+
);
61+
62+
impl<'tcx> LateLintPass<'tcx> for AsyncClosureUsage {
63+
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
64+
let hir::ExprKind::Closure(&hir::Closure {
65+
body,
66+
kind: hir::ClosureKind::Closure,
67+
fn_decl_span,
68+
..
69+
}) = expr.kind
70+
else {
71+
return;
72+
};
73+
74+
let mut body = cx.tcx.hir().body(body).value;
75+
76+
// Only peel blocks that have no expressions.
77+
while let hir::ExprKind::Block(&hir::Block { stmts: [], expr: Some(tail), .. }, None) =
78+
body.kind
79+
{
80+
body = tail;
81+
}
82+
83+
let hir::ExprKind::Closure(&hir::Closure {
84+
kind:
85+
hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
86+
hir::CoroutineDesugaring::Async,
87+
hir::CoroutineSource::Block,
88+
)),
89+
fn_decl_span: async_decl_span,
90+
..
91+
}) = body.kind
92+
else {
93+
return;
94+
};
95+
96+
let deletion_span = cx.tcx.sess.source_map().span_extend_while_whitespace(async_decl_span);
97+
98+
cx.tcx.emit_node_span_lint(
99+
CLOSURE_RETURNING_ASYNC_BLOCK,
100+
expr.hir_id,
101+
fn_decl_span,
102+
ClosureReturningAsyncBlock {
103+
async_decl_span,
104+
sugg: AsyncClosureSugg {
105+
deletion_span,
106+
insertion_span: fn_decl_span.shrink_to_lo(),
107+
},
108+
},
109+
);
110+
}
111+
}
112+
113+
#[derive(LintDiagnostic)]
114+
#[diag(lint_closure_returning_async_block)]
115+
struct ClosureReturningAsyncBlock {
116+
#[label]
117+
async_decl_span: Span,
118+
#[subdiagnostic]
119+
sugg: AsyncClosureSugg,
120+
}
121+
122+
#[derive(Subdiagnostic)]
123+
#[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")]
124+
struct AsyncClosureSugg {
125+
#[suggestion_part(code = "")]
126+
deletion_span: Span,
127+
#[suggestion_part(code = "async ")]
128+
insertion_span: Span,
129+
}

compiler/rustc_lint/src/impl_trait_overcaptures.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_middle::ty::{
1111
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
1212
};
1313
use rustc_session::{declare_lint, declare_lint_pass};
14-
use rustc_span::{sym, Span};
14+
use rustc_span::Span;
1515

1616
use crate::fluent_generated as fluent;
1717
use crate::{LateContext, LateLintPass};
@@ -57,7 +57,7 @@ declare_lint! {
5757
pub IMPL_TRAIT_OVERCAPTURES,
5858
Allow,
5959
"`impl Trait` will capture more lifetimes than possibly intended in edition 2024",
60-
@feature_gate = sym::precise_capturing;
60+
@feature_gate = precise_capturing;
6161
//@future_incompatible = FutureIncompatibleInfo {
6262
// reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
6363
// reference: "<FIXME>",
@@ -91,7 +91,7 @@ declare_lint! {
9191
pub IMPL_TRAIT_REDUNDANT_CAPTURES,
9292
Warn,
9393
"redundant precise-capturing `use<...>` syntax on an `impl Trait`",
94-
@feature_gate = sym::precise_capturing;
94+
@feature_gate = precise_capturing;
9595
}
9696

9797
declare_lint_pass!(

compiler/rustc_lint/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#![feature(trait_upcasting)]
4242
// tidy-alphabetical-end
4343

44+
mod async_closures;
4445
mod async_fn_in_trait;
4546
pub mod builtin;
4647
mod context;
@@ -87,6 +88,7 @@ use rustc_hir::def_id::LocalModDefId;
8788
use rustc_middle::query::Providers;
8889
use rustc_middle::ty::TyCtxt;
8990

91+
use async_closures::AsyncClosureUsage;
9092
use async_fn_in_trait::AsyncFnInTrait;
9193
use builtin::*;
9294
use deref_into_dyn_supertrait::*;
@@ -229,6 +231,7 @@ late_lint_methods!(
229231
MapUnitFn: MapUnitFn,
230232
MissingDebugImplementations: MissingDebugImplementations,
231233
MissingDoc: MissingDoc,
234+
AsyncClosureUsage: AsyncClosureUsage,
232235
AsyncFnInTrait: AsyncFnInTrait,
233236
NonLocalDefinitions: NonLocalDefinitions::default(),
234237
ImplTraitOvercaptures: ImplTraitOvercaptures,

compiler/rustc_lint/src/multiple_supertrait_upcastable.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use crate::{LateContext, LateLintPass, LintContext};
22

33
use rustc_hir as hir;
44
use rustc_session::{declare_lint, declare_lint_pass};
5-
use rustc_span::sym;
65

76
declare_lint! {
87
/// The `multiple_supertrait_upcastable` lint detects when an object-safe trait has multiple
@@ -30,7 +29,7 @@ declare_lint! {
3029
pub MULTIPLE_SUPERTRAIT_UPCASTABLE,
3130
Allow,
3231
"detect when an object-safe trait has multiple supertraits",
33-
@feature_gate = sym::multiple_supertrait_upcastable;
32+
@feature_gate = multiple_supertrait_upcastable;
3433
}
3534

3635
declare_lint_pass!(MultipleSupertraitUpcastable => [MULTIPLE_SUPERTRAIT_UPCASTABLE]);

compiler/rustc_lint_defs/src/builtin.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
1010
use crate::{declare_lint, declare_lint_pass, FutureIncompatibilityReason};
1111
use rustc_span::edition::Edition;
12-
use rustc_span::symbol::sym;
1312

1413
declare_lint_pass! {
1514
/// Does nothing as a lint pass, but registers some `Lint`s
@@ -463,7 +462,7 @@ declare_lint! {
463462
pub MUST_NOT_SUSPEND,
464463
Allow,
465464
"use of a `#[must_not_suspend]` value across a yield point",
466-
@feature_gate = rustc_span::symbol::sym::must_not_suspend;
465+
@feature_gate = must_not_suspend;
467466
}
468467

469468
declare_lint! {
@@ -1647,7 +1646,7 @@ declare_lint! {
16471646
pub RUST_2024_INCOMPATIBLE_PAT,
16481647
Allow,
16491648
"detects patterns whose meaning will change in Rust 2024",
1650-
@feature_gate = sym::ref_pat_eat_one_layer_2024;
1649+
@feature_gate = ref_pat_eat_one_layer_2024;
16511650
// FIXME uncomment below upon stabilization
16521651
/*@future_incompatible = FutureIncompatibleInfo {
16531652
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
@@ -2695,7 +2694,7 @@ declare_lint! {
26952694
pub FUZZY_PROVENANCE_CASTS,
26962695
Allow,
26972696
"a fuzzy integer to pointer cast is used",
2698-
@feature_gate = sym::strict_provenance;
2697+
@feature_gate = strict_provenance;
26992698
}
27002699

27012700
declare_lint! {
@@ -2741,7 +2740,7 @@ declare_lint! {
27412740
pub LOSSY_PROVENANCE_CASTS,
27422741
Allow,
27432742
"a lossy pointer to integer cast is used",
2744-
@feature_gate = sym::strict_provenance;
2743+
@feature_gate = strict_provenance;
27452744
}
27462745

27472746
declare_lint! {
@@ -3925,7 +3924,7 @@ declare_lint! {
39253924
pub NON_EXHAUSTIVE_OMITTED_PATTERNS,
39263925
Allow,
39273926
"detect when patterns of types marked `non_exhaustive` are missed",
3928-
@feature_gate = sym::non_exhaustive_omitted_patterns_lint;
3927+
@feature_gate = non_exhaustive_omitted_patterns_lint;
39293928
}
39303929

39313930
declare_lint! {
@@ -4045,7 +4044,7 @@ declare_lint! {
40454044
pub TEST_UNSTABLE_LINT,
40464045
Deny,
40474046
"this unstable lint is only for testing",
4048-
@feature_gate = sym::test_unstable_lint;
4047+
@feature_gate = test_unstable_lint;
40494048
}
40504049

40514050
declare_lint! {

compiler/rustc_lint_defs/src/lib.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ macro_rules! declare_lint {
865865
);
866866
);
867867
($(#[$attr:meta])* $vis: vis $NAME: ident, $Level: ident, $desc: expr,
868-
$(@feature_gate = $gate:expr;)?
868+
$(@feature_gate = $gate:ident;)?
869869
$(@future_incompatible = FutureIncompatibleInfo {
870870
reason: $reason:expr,
871871
$($field:ident : $val:expr),* $(,)*
@@ -879,7 +879,7 @@ macro_rules! declare_lint {
879879
desc: $desc,
880880
is_externally_loaded: false,
881881
$($v: true,)*
882-
$(feature_gate: Some($gate),)?
882+
$(feature_gate: Some(rustc_span::symbol::sym::$gate),)?
883883
$(future_incompatible: Some($crate::FutureIncompatibleInfo {
884884
reason: $reason,
885885
$($field: $val,)*
@@ -895,21 +895,21 @@ macro_rules! declare_lint {
895895
macro_rules! declare_tool_lint {
896896
(
897897
$(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level: ident, $desc: expr
898-
$(, @feature_gate = $gate:expr;)?
898+
$(, @feature_gate = $gate:ident;)?
899899
) => (
900900
$crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, false $(, @feature_gate = $gate;)?}
901901
);
902902
(
903903
$(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr,
904904
report_in_external_macro: $rep:expr
905-
$(, @feature_gate = $gate:expr;)?
905+
$(, @feature_gate = $gate:ident;)?
906906
) => (
907907
$crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, $rep $(, @feature_gate = $gate;)?}
908908
);
909909
(
910910
$(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr,
911911
$external:expr
912-
$(, @feature_gate = $gate:expr;)?
912+
$(, @feature_gate = $gate:ident;)?
913913
) => (
914914
$(#[$attr])*
915915
$vis static $NAME: &$crate::Lint = &$crate::Lint {
@@ -920,7 +920,7 @@ macro_rules! declare_tool_lint {
920920
report_in_external_macro: $external,
921921
future_incompatible: None,
922922
is_externally_loaded: true,
923-
$(feature_gate: Some($gate),)?
923+
$(feature_gate: Some(rustc_span::symbol::sym::$gate),)?
924924
crate_level_only: false,
925925
..$crate::Lint::default_fields_for_macro()
926926
};

library/std/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,9 @@ pub use core::{
684684
module_path, option_env, stringify, trace_macros,
685685
};
686686

687+
#[unstable(feature = "anonymous_pipe", issue = "127154")]
688+
pub use crate::sys::anonymous_pipe as pipe;
689+
687690
#[unstable(
688691
feature = "concat_bytes",
689692
issue = "87555",

library/std/src/process/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ fn test_interior_nul_in_env_value_is_error() {
386386
fn test_creation_flags() {
387387
use crate::os::windows::process::CommandExt;
388388
use crate::sys::c::{BOOL, DWORD, INFINITE};
389-
#[repr(C, packed)]
389+
#[repr(C)]
390390
struct DEBUG_EVENT {
391391
pub event_code: DWORD,
392392
pub process_id: DWORD,

0 commit comments

Comments
 (0)