Skip to content

Commit b0437bb

Browse files
open up coroutines
1 parent b1b968c commit b0437bb

File tree

6 files changed

+125
-23
lines changed

6 files changed

+125
-23
lines changed

compiler/rustc_mir_transform/messages.ftl

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ mir_transform_operation_will_panic = this operation will panic at runtime
2727
2828
mir_transform_tail_expr_drop_order = this value has significant drop implementation that will have a different drop order from that of Edition 2021, whose type `{$ty}` drops `{$ty_drop_components}` while dropping
2929
.label = this local binding may observe changes in drop order under Edition 2024, whose type `{$observer_ty}` drops `{$observer_ty_drop_components}` while dropping
30-
.note_ty = these are the types with significant drop implementation
31-
.note_observer_ty = these are the types with significant drop implementation that may be sensitive the the change in the drop order
30+
.note_ty = these are the types and values with significant drop implementation
31+
.note_observer_ty = these are the types and values with significant drop implementation that are from Edition 2024 dropped earlier rather than later
3232
3333
mir_transform_unaligned_packed_ref = reference to packed field is unaligned
3434
.note = packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses

compiler/rustc_mir_transform/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,6 @@ fn mir_promoted(
359359
&[&promote_pass, &simplify::SimplifyCfg::PromoteConsts, &coverage::InstrumentCoverage],
360360
Some(MirPhase::Analysis(AnalysisPhase::Initial)),
361361
);
362-
lint_tail_expr_drop_order::run_lint(tcx, def, &body);
363362

364363
let promoted = promote_pass.promoted_fragments.into_inner();
365364
(tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted))
@@ -416,6 +415,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
416415
}
417416

418417
let (body, _) = tcx.mir_promoted(def);
418+
lint_tail_expr_drop_order::run_lint(tcx, def, &body.borrow());
419419
let mut body = body.steal();
420420

421421
if let Some(error_reported) = tainted_by_errors {

compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs

+39-14
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_mir_dataflow::move_paths::{MoveData, MovePathIndex};
1313
use rustc_mir_dataflow::{Analysis, MaybeReachable};
1414
use rustc_session::lint;
1515
use rustc_span::Span;
16+
use smallvec::{SmallVec, smallvec};
1617
use tracing::{debug, instrument};
1718

1819
fn place_has_common_prefix<'tcx>(left: &Place<'tcx>, right: &Place<'tcx>) -> bool {
@@ -68,6 +69,41 @@ fn print_ty_without_trimming(ty: Ty<'_>) -> String {
6869
ty::print::with_no_trimmed_paths!(format!("{}", ty))
6970
}
7071

72+
#[instrument(level = "debug", skip(tcx, param_env))]
73+
fn extract_component_raw<'tcx>(
74+
tcx: TyCtxt<'tcx>,
75+
param_env: ty::ParamEnv<'tcx>,
76+
ty: Ty<'tcx>,
77+
) -> (SmallVec<[Ty<'tcx>; 4]>, SmallVec<[Span; 4]>) {
78+
// Droppiness does not depend on regions, so let us erase them.
79+
let ty = tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty);
80+
81+
let Ok(tys) = tcx.list_significant_drop_tys(param_env.and(ty)) else {
82+
return (smallvec![ty], smallvec![]);
83+
};
84+
debug!(?ty, "components");
85+
let mut out_tys = smallvec![];
86+
let mut out_spans = smallvec![];
87+
for ty in tys {
88+
if let ty::Coroutine(did, args) = ty.kind()
89+
&& let Some(witness) = tcx.mir_coroutine_witnesses(did)
90+
{
91+
for field in &witness.field_tys {
92+
let (tys, spans) = extract_component_raw(
93+
tcx,
94+
param_env,
95+
ty::EarlyBinder::bind(field.ty).instantiate(tcx, args),
96+
);
97+
out_tys.extend(tys);
98+
out_spans.extend([field.source_info.span].into_iter().chain(spans));
99+
}
100+
} else {
101+
out_tys.push(ty);
102+
}
103+
}
104+
(out_tys, out_spans)
105+
}
106+
71107
#[instrument(level = "debug", skip(tcx, param_env))]
72108
fn extract_component_with_significant_dtor<'tcx>(
73109
tcx: TyCtxt<'tcx>,
@@ -105,20 +141,9 @@ fn extract_component_with_significant_dtor<'tcx>(
105141
// I honestly don't know how to extract the span reliably from a param arbitrarily nested
106142
ty::Param(_) => None,
107143
};
108-
let Ok(tys) = tcx.list_significant_drop_tys(param_env.and(ty)) else {
109-
return (print_ty_without_trimming(ty), vec![]);
110-
};
111-
debug!(?ty, "components");
112-
for ty in tys {
113-
match ty.kind() {
114-
ty::Coroutine(def_id, _) => debug!(?def_id, "coroutine"),
115-
ty::CoroutineWitness(def_id, _) => debug!(?def_id, "coroutine witness"),
116-
ty::Adt(def_id, _) => debug!(?def_id, "adt"),
117-
_ => {}
118-
}
119-
}
120-
let ty_names = tys.iter().map(print_ty_without_trimming).join(", ");
121-
let ty_spans = tys.iter().flat_map(ty_def_span).collect();
144+
let (tys, spans) = extract_component_raw(tcx, param_env, ty);
145+
let ty_names = tys.iter().copied().map(print_ty_without_trimming).join(", ");
146+
let ty_spans = tys.iter().copied().flat_map(ty_def_span).chain(spans).collect();
122147
(ty_names, ty_spans)
123148
}
124149

compiler/rustc_ty_utils/src/needs_drop.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ where
195195
}
196196
}
197197

198-
_ if component.is_copy_modulo_regions(tcx, self.param_env) => (),
198+
_ if component.is_copy_modulo_regions(tcx, self.param_env) => {}
199199

200200
ty::Closure(_, args) => {
201201
for upvar in args.as_closure().upvar_tys() {

tests/ui/drop/lint-tail-expr-drop-order.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Edition 2024 lint for change in drop order at tail expression
22
// This lint is to capture potential change in program semantics
33
// due to implementation of RFC 3606 <https://github.com/rust-lang/rfcs/pull/3606>
4+
//@ edition: 2021
5+
//@ build-fail
46

57
#![deny(tail_expr_drop_order)]
68
#![feature(shorter_tail_lifetimes)]
@@ -98,4 +100,18 @@ fn should_not_lint_when_moved() -> i32 {
98100
LoudDropper.get()
99101
}
100102

103+
fn should_lint_into_async_body() -> i32 {
104+
async fn f() {
105+
async fn f() {}
106+
let x = LoudDropper;
107+
f().await;
108+
drop(x);
109+
}
110+
111+
let future = f();
112+
LoudDropper.get()
113+
//~^ ERROR: this value has significant drop implementation that will have a different drop order from that of Edition 2021
114+
//~| WARN: this changes meaning in Rust 2024
115+
}
116+
101117
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: this value has significant drop implementation that will have a different drop order from that of Edition 2021, whose type `LoudDropper` drops `LoudDropper` while dropping
2-
--> $DIR/lint-tail-expr-drop-order.rs:26:15
2+
--> $DIR/lint-tail-expr-drop-order.rs:28:15
33
|
44
LL | let x = LoudDropper;
55
| - this local binding may observe changes in drop order under Edition 2024, whose type `LoudDropper` drops `LoudDropper` while dropping
@@ -9,14 +9,24 @@ LL | x.get() + LoudDropper.get()
99
|
1010
= warning: this changes meaning in Rust 2024
1111
= note: for more information, see issue #123739 <https://github.com/rust-lang/rust/issues/123739>
12+
note: these are the types and values with significant drop implementation
13+
--> $DIR/lint-tail-expr-drop-order.rs:10:1
14+
|
15+
LL | struct LoudDropper;
16+
| ^^^^^^^^^^^^^^^^^^
17+
note: these are the types and values with significant drop implementation that are from Edition 2024 dropped earlier rather than later
18+
--> $DIR/lint-tail-expr-drop-order.rs:10:1
19+
|
20+
LL | struct LoudDropper;
21+
| ^^^^^^^^^^^^^^^^^^
1222
note: the lint level is defined here
13-
--> $DIR/lint-tail-expr-drop-order.rs:5:9
23+
--> $DIR/lint-tail-expr-drop-order.rs:7:9
1424
|
1525
LL | #![deny(tail_expr_drop_order)]
1626
| ^^^^^^^^^^^^^^^^^^^^
1727

1828
error: this value has significant drop implementation that will have a different drop order from that of Edition 2021, whose type `LoudDropper` drops `LoudDropper` while dropping
19-
--> $DIR/lint-tail-expr-drop-order.rs:44:19
29+
--> $DIR/lint-tail-expr-drop-order.rs:46:19
2030
|
2131
LL | let x = LoudDropper;
2232
| - this local binding may observe changes in drop order under Edition 2024, whose type `LoudDropper` drops `LoudDropper` while dropping
@@ -26,9 +36,19 @@ LL | x.get() + LoudDropper.get()
2636
|
2737
= warning: this changes meaning in Rust 2024
2838
= note: for more information, see issue #123739 <https://github.com/rust-lang/rust/issues/123739>
39+
note: these are the types and values with significant drop implementation
40+
--> $DIR/lint-tail-expr-drop-order.rs:10:1
41+
|
42+
LL | struct LoudDropper;
43+
| ^^^^^^^^^^^^^^^^^^
44+
note: these are the types and values with significant drop implementation that are from Edition 2024 dropped earlier rather than later
45+
--> $DIR/lint-tail-expr-drop-order.rs:10:1
46+
|
47+
LL | struct LoudDropper;
48+
| ^^^^^^^^^^^^^^^^^^
2949

3050
error: this value has significant drop implementation that will have a different drop order from that of Edition 2021, whose type `LoudDropper` drops `LoudDropper` while dropping
31-
--> $DIR/lint-tail-expr-drop-order.rs:64:7
51+
--> $DIR/lint-tail-expr-drop-order.rs:66:7
3252
|
3353
LL | let x = LoudDropper;
3454
| - this local binding may observe changes in drop order under Edition 2024, whose type `LoudDropper` drops `LoudDropper` while dropping
@@ -37,6 +57,47 @@ LL | { LoudDropper.get() }
3757
|
3858
= warning: this changes meaning in Rust 2024
3959
= note: for more information, see issue #123739 <https://github.com/rust-lang/rust/issues/123739>
60+
note: these are the types and values with significant drop implementation
61+
--> $DIR/lint-tail-expr-drop-order.rs:10:1
62+
|
63+
LL | struct LoudDropper;
64+
| ^^^^^^^^^^^^^^^^^^
65+
note: these are the types and values with significant drop implementation that are from Edition 2024 dropped earlier rather than later
66+
--> $DIR/lint-tail-expr-drop-order.rs:10:1
67+
|
68+
LL | struct LoudDropper;
69+
| ^^^^^^^^^^^^^^^^^^
70+
71+
error: this value has significant drop implementation that will have a different drop order from that of Edition 2021, whose type `LoudDropper` drops `LoudDropper` while dropping
72+
--> $DIR/lint-tail-expr-drop-order.rs:112:5
73+
|
74+
LL | let future = f();
75+
| ------ this local binding may observe changes in drop order under Edition 2024, whose type `impl std::future::Future<Output = ()>` drops `LoudDropper` while dropping
76+
LL | LoudDropper.get()
77+
| ^^^^^^^^^^^
78+
|
79+
= warning: this changes meaning in Rust 2024
80+
= note: for more information, see issue #123739 <https://github.com/rust-lang/rust/issues/123739>
81+
note: these are the types and values with significant drop implementation
82+
--> $DIR/lint-tail-expr-drop-order.rs:10:1
83+
|
84+
LL | struct LoudDropper;
85+
| ^^^^^^^^^^^^^^^^^^
86+
note: these are the types and values with significant drop implementation that are from Edition 2024 dropped earlier rather than later
87+
--> $DIR/lint-tail-expr-drop-order.rs:10:1
88+
|
89+
LL | struct LoudDropper;
90+
| ^^^^^^^^^^^^^^^^^^
91+
note: these are the types and values with significant drop implementation that are from Edition 2024 dropped earlier rather than later
92+
--> $DIR/lint-tail-expr-drop-order.rs:106:13
93+
|
94+
LL | let x = LoudDropper;
95+
| ^
96+
note: these are the types and values with significant drop implementation that are from Edition 2024 dropped earlier rather than later
97+
--> $DIR/lint-tail-expr-drop-order.rs:107:9
98+
|
99+
LL | f().await;
100+
| ^^^^^^^^^
40101

41-
error: aborting due to 3 previous errors
102+
error: aborting due to 4 previous errors
42103

0 commit comments

Comments
 (0)