Skip to content

Commit

Permalink
open up coroutines
Browse files Browse the repository at this point in the history
  • Loading branch information
dingxiangfei2009 committed Oct 12, 2024
1 parent b1b968c commit b0437bb
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 23 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ mir_transform_operation_will_panic = this operation will panic at runtime
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
.label = this local binding may observe changes in drop order under Edition 2024, whose type `{$observer_ty}` drops `{$observer_ty_drop_components}` while dropping
.note_ty = these are the types with significant drop implementation
.note_observer_ty = these are the types with significant drop implementation that may be sensitive the the change in the drop order
.note_ty = these are the types and values with significant drop implementation
.note_observer_ty = these are the types and values with significant drop implementation that are from Edition 2024 dropped earlier rather than later
mir_transform_unaligned_packed_ref = reference to packed field is unaligned
.note = packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,6 @@ fn mir_promoted(
&[&promote_pass, &simplify::SimplifyCfg::PromoteConsts, &coverage::InstrumentCoverage],
Some(MirPhase::Analysis(AnalysisPhase::Initial)),
);
lint_tail_expr_drop_order::run_lint(tcx, def, &body);

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

let (body, _) = tcx.mir_promoted(def);
lint_tail_expr_drop_order::run_lint(tcx, def, &body.borrow());
let mut body = body.steal();

if let Some(error_reported) = tainted_by_errors {
Expand Down
53 changes: 39 additions & 14 deletions compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use rustc_mir_dataflow::move_paths::{MoveData, MovePathIndex};
use rustc_mir_dataflow::{Analysis, MaybeReachable};
use rustc_session::lint;
use rustc_span::Span;
use smallvec::{SmallVec, smallvec};
use tracing::{debug, instrument};

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

#[instrument(level = "debug", skip(tcx, param_env))]
fn extract_component_raw<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
ty: Ty<'tcx>,
) -> (SmallVec<[Ty<'tcx>; 4]>, SmallVec<[Span; 4]>) {
// Droppiness does not depend on regions, so let us erase them.
let ty = tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty);

let Ok(tys) = tcx.list_significant_drop_tys(param_env.and(ty)) else {
return (smallvec![ty], smallvec![]);
};
debug!(?ty, "components");
let mut out_tys = smallvec![];
let mut out_spans = smallvec![];
for ty in tys {
if let ty::Coroutine(did, args) = ty.kind()
&& let Some(witness) = tcx.mir_coroutine_witnesses(did)
{
for field in &witness.field_tys {
let (tys, spans) = extract_component_raw(
tcx,
param_env,
ty::EarlyBinder::bind(field.ty).instantiate(tcx, args),
);
out_tys.extend(tys);
out_spans.extend([field.source_info.span].into_iter().chain(spans));
}
} else {
out_tys.push(ty);
}
}
(out_tys, out_spans)
}

#[instrument(level = "debug", skip(tcx, param_env))]
fn extract_component_with_significant_dtor<'tcx>(
tcx: TyCtxt<'tcx>,
Expand Down Expand Up @@ -105,20 +141,9 @@ fn extract_component_with_significant_dtor<'tcx>(
// I honestly don't know how to extract the span reliably from a param arbitrarily nested
ty::Param(_) => None,
};
let Ok(tys) = tcx.list_significant_drop_tys(param_env.and(ty)) else {
return (print_ty_without_trimming(ty), vec![]);
};
debug!(?ty, "components");
for ty in tys {
match ty.kind() {
ty::Coroutine(def_id, _) => debug!(?def_id, "coroutine"),
ty::CoroutineWitness(def_id, _) => debug!(?def_id, "coroutine witness"),
ty::Adt(def_id, _) => debug!(?def_id, "adt"),
_ => {}
}
}
let ty_names = tys.iter().map(print_ty_without_trimming).join(", ");
let ty_spans = tys.iter().flat_map(ty_def_span).collect();
let (tys, spans) = extract_component_raw(tcx, param_env, ty);
let ty_names = tys.iter().copied().map(print_ty_without_trimming).join(", ");
let ty_spans = tys.iter().copied().flat_map(ty_def_span).chain(spans).collect();
(ty_names, ty_spans)
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ty_utils/src/needs_drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ where
}
}

_ if component.is_copy_modulo_regions(tcx, self.param_env) => (),
_ if component.is_copy_modulo_regions(tcx, self.param_env) => {}

ty::Closure(_, args) => {
for upvar in args.as_closure().upvar_tys() {
Expand Down
16 changes: 16 additions & 0 deletions tests/ui/drop/lint-tail-expr-drop-order.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Edition 2024 lint for change in drop order at tail expression
// This lint is to capture potential change in program semantics
// due to implementation of RFC 3606 <https://github.com/rust-lang/rfcs/pull/3606>
//@ edition: 2021
//@ build-fail

#![deny(tail_expr_drop_order)]
#![feature(shorter_tail_lifetimes)]
Expand Down Expand Up @@ -98,4 +100,18 @@ fn should_not_lint_when_moved() -> i32 {
LoudDropper.get()
}

fn should_lint_into_async_body() -> i32 {
async fn f() {
async fn f() {}
let x = LoudDropper;
f().await;
drop(x);
}

let future = f();
LoudDropper.get()
//~^ ERROR: this value has significant drop implementation that will have a different drop order from that of Edition 2021
//~| WARN: this changes meaning in Rust 2024
}

fn main() {}
71 changes: 66 additions & 5 deletions tests/ui/drop/lint-tail-expr-drop-order.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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
--> $DIR/lint-tail-expr-drop-order.rs:26:15
--> $DIR/lint-tail-expr-drop-order.rs:28:15
|
LL | let x = LoudDropper;
| - this local binding may observe changes in drop order under Edition 2024, whose type `LoudDropper` drops `LoudDropper` while dropping
Expand All @@ -9,14 +9,24 @@ LL | x.get() + LoudDropper.get()
|
= warning: this changes meaning in Rust 2024
= note: for more information, see issue #123739 <https://github.com/rust-lang/rust/issues/123739>
note: these are the types and values with significant drop implementation
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
LL | struct LoudDropper;
| ^^^^^^^^^^^^^^^^^^
note: these are the types and values with significant drop implementation that are from Edition 2024 dropped earlier rather than later
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
LL | struct LoudDropper;
| ^^^^^^^^^^^^^^^^^^
note: the lint level is defined here
--> $DIR/lint-tail-expr-drop-order.rs:5:9
--> $DIR/lint-tail-expr-drop-order.rs:7:9
|
LL | #![deny(tail_expr_drop_order)]
| ^^^^^^^^^^^^^^^^^^^^

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
--> $DIR/lint-tail-expr-drop-order.rs:44:19
--> $DIR/lint-tail-expr-drop-order.rs:46:19
|
LL | let x = LoudDropper;
| - this local binding may observe changes in drop order under Edition 2024, whose type `LoudDropper` drops `LoudDropper` while dropping
Expand All @@ -26,9 +36,19 @@ LL | x.get() + LoudDropper.get()
|
= warning: this changes meaning in Rust 2024
= note: for more information, see issue #123739 <https://github.com/rust-lang/rust/issues/123739>
note: these are the types and values with significant drop implementation
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
LL | struct LoudDropper;
| ^^^^^^^^^^^^^^^^^^
note: these are the types and values with significant drop implementation that are from Edition 2024 dropped earlier rather than later
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
LL | struct LoudDropper;
| ^^^^^^^^^^^^^^^^^^

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
--> $DIR/lint-tail-expr-drop-order.rs:64:7
--> $DIR/lint-tail-expr-drop-order.rs:66:7
|
LL | let x = LoudDropper;
| - this local binding may observe changes in drop order under Edition 2024, whose type `LoudDropper` drops `LoudDropper` while dropping
Expand All @@ -37,6 +57,47 @@ LL | { LoudDropper.get() }
|
= warning: this changes meaning in Rust 2024
= note: for more information, see issue #123739 <https://github.com/rust-lang/rust/issues/123739>
note: these are the types and values with significant drop implementation
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
LL | struct LoudDropper;
| ^^^^^^^^^^^^^^^^^^
note: these are the types and values with significant drop implementation that are from Edition 2024 dropped earlier rather than later
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
LL | struct LoudDropper;
| ^^^^^^^^^^^^^^^^^^

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
--> $DIR/lint-tail-expr-drop-order.rs:112:5
|
LL | let future = f();
| ------ this local binding may observe changes in drop order under Edition 2024, whose type `impl std::future::Future<Output = ()>` drops `LoudDropper` while dropping
LL | LoudDropper.get()
| ^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
= note: for more information, see issue #123739 <https://github.com/rust-lang/rust/issues/123739>
note: these are the types and values with significant drop implementation
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
LL | struct LoudDropper;
| ^^^^^^^^^^^^^^^^^^
note: these are the types and values with significant drop implementation that are from Edition 2024 dropped earlier rather than later
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
LL | struct LoudDropper;
| ^^^^^^^^^^^^^^^^^^
note: these are the types and values with significant drop implementation that are from Edition 2024 dropped earlier rather than later
--> $DIR/lint-tail-expr-drop-order.rs:106:13
|
LL | let x = LoudDropper;
| ^
note: these are the types and values with significant drop implementation that are from Edition 2024 dropped earlier rather than later
--> $DIR/lint-tail-expr-drop-order.rs:107:9
|
LL | f().await;
| ^^^^^^^^^

error: aborting due to 3 previous errors
error: aborting due to 4 previous errors

0 comments on commit b0437bb

Please sign in to comment.