Skip to content

Commit 484ef97

Browse files
committed
Do not compute coroutine layout in non-Codegen typing mode.
1 parent 87c1566 commit 484ef97

File tree

10 files changed

+84
-19
lines changed

10 files changed

+84
-19
lines changed

compiler/rustc_hir_typeck/src/intrinsicck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ pub(crate) fn check_transmutes(tcx: TyCtxt<'_>, owner: LocalDefId) {
147147
let typeck_results = tcx.typeck(owner);
148148
let None = typeck_results.tainted_by_errors else { return };
149149

150-
let typing_env = ty::TypingEnv::post_analysis(tcx, owner);
150+
let typing_env = ty::TypingEnv::codegen(tcx, owner);
151151
for &(from, to, hir_id) in &typeck_results.transmutes_to_check {
152152
check_transmute(tcx, typing_env, from, to, hir_id);
153153
}

compiler/rustc_interface/src/passes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1102,7 +1102,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
11021102
if !tcx.is_async_drop_in_place_coroutine(def_id.to_def_id()) {
11031103
// Eagerly check the unsubstituted layout for cycles.
11041104
tcx.ensure_ok().layout_of(
1105-
ty::TypingEnv::post_analysis(tcx, def_id.to_def_id())
1105+
ty::TypingEnv::codegen(tcx, def_id.to_def_id())
11061106
.as_query_input(tcx.type_of(def_id).instantiate_identity()),
11071107
);
11081108
}

compiler/rustc_middle/src/query/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1645,7 +1645,7 @@ rustc_queries! {
16451645
/// Like `param_env`, but returns the `ParamEnv` after all opaque types have been
16461646
/// replaced with their hidden type. This is used in the old trait solver
16471647
/// when in `PostAnalysis` mode and should not be called directly.
1648-
query typing_env_normalized_for_post_analysis(def_id: DefId) -> ty::TypingEnv<'tcx> {
1648+
query param_env_normalized_for_post_analysis(def_id: DefId) -> ty::ParamEnv<'tcx> {
16491649
desc { |tcx| "computing revealed normalized predicates of `{}`", tcx.def_path_str(def_id) }
16501650
}
16511651

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,17 @@ impl<'tcx> ParamEnv<'tcx> {
10091009
pub fn and<T: TypeVisitable<TyCtxt<'tcx>>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
10101010
ParamEnvAnd { param_env: self, value }
10111011
}
1012+
1013+
/// Eagerly reveal all opaque types in the `param_env`.
1014+
pub fn with_normalized(self, tcx: TyCtxt<'tcx>) -> ParamEnv<'tcx> {
1015+
// No need to reveal opaques with the new solver enabled,
1016+
// since we have lazy norm.
1017+
if tcx.next_trait_solver_globally() {
1018+
self
1019+
} else {
1020+
ParamEnv::new(tcx.reveal_opaque_types_in_bounds(self.caller_bounds))
1021+
}
1022+
}
10121023
}
10131024

10141025
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
@@ -1062,7 +1073,17 @@ impl<'tcx> TypingEnv<'tcx> {
10621073
}
10631074

10641075
pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryParam<DefId>) -> TypingEnv<'tcx> {
1065-
tcx.typing_env_normalized_for_post_analysis(def_id)
1076+
TypingEnv {
1077+
typing_mode: TypingMode::PostAnalysis,
1078+
param_env: tcx.param_env_normalized_for_post_analysis(def_id),
1079+
}
1080+
}
1081+
1082+
pub fn codegen(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryParam<DefId>) -> TypingEnv<'tcx> {
1083+
TypingEnv {
1084+
typing_mode: TypingMode::Codegen,
1085+
param_env: tcx.param_env_normalized_for_post_analysis(def_id),
1086+
}
10661087
}
10671088

10681089
/// Modify the `typing_mode` to `PostAnalysis` or `Codegen` and eagerly reveal all opaque types
@@ -1073,16 +1094,22 @@ impl<'tcx> TypingEnv<'tcx> {
10731094
return self;
10741095
}
10751096

1076-
// No need to reveal opaques with the new solver enabled,
1077-
// since we have lazy norm.
1078-
let param_env = if tcx.next_trait_solver_globally() {
1079-
param_env
1080-
} else {
1081-
ParamEnv::new(tcx.reveal_opaque_types_in_bounds(param_env.caller_bounds()))
1082-
};
1097+
let param_env = param_env.with_normalized(tcx);
10831098
TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env }
10841099
}
10851100

1101+
/// Modify the `typing_mode` to `PostAnalysis` or `Codegen` and eagerly reveal all opaque types
1102+
/// in the `param_env`.
1103+
pub fn with_codegen_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> {
1104+
let TypingEnv { typing_mode, param_env } = self;
1105+
if let TypingMode::Codegen = typing_mode {
1106+
return self;
1107+
}
1108+
1109+
let param_env = param_env.with_normalized(tcx);
1110+
TypingEnv { typing_mode: TypingMode::Codegen, param_env }
1111+
}
1112+
10861113
/// Combine this typing environment with the given `value` to be used by
10871114
/// not (yet) canonicalized queries. This only works if the value does not
10881115
/// contain anything local to some `InferCtxt`, i.e. inference variables or

compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,7 @@ impl<'tcx> ConstToPat<'tcx> {
105105
//
106106
// FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself
107107
// instead of having this logic here
108-
let typing_env =
109-
self.tcx.erase_regions(self.typing_env).with_post_analysis_normalized(self.tcx);
108+
let typing_env = self.tcx.erase_regions(self.typing_env).with_codegen_normalized(self.tcx);
110109
let uv = self.tcx.erase_regions(uv);
111110

112111
// try to resolve e.g. associated constants to their definition on an impl, and then

compiler/rustc_ty_utils/src/layout.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,17 @@ fn layout_of_uncached<'tcx>(
482482
}
483483

484484
ty::Coroutine(def_id, args) => {
485+
match cx.typing_env.typing_mode {
486+
ty::TypingMode::Codegen => {}
487+
ty::TypingMode::Coherence
488+
| ty::TypingMode::Analysis { .. }
489+
| ty::TypingMode::Borrowck { .. }
490+
| ty::TypingMode::PostBorrowckAnalysis { .. }
491+
| ty::TypingMode::PostAnalysis => {
492+
return Err(error(cx, LayoutError::TooGeneric(ty)));
493+
}
494+
}
495+
485496
use rustc_middle::ty::layout::PrimitiveExt as _;
486497

487498
let info = tcx.coroutine_layout(def_id, args)?;
@@ -605,7 +616,10 @@ fn layout_of_uncached<'tcx>(
605616

606617
let maybe_unsized = def.is_struct()
607618
&& def.non_enum_variant().tail_opt().is_some_and(|last_field| {
608-
let typing_env = ty::TypingEnv::post_analysis(tcx, def.did());
619+
let typing_env = ty::TypingEnv {
620+
typing_mode: cx.typing_env.typing_mode,
621+
param_env: tcx.param_env_normalized_for_post_analysis(def.did()),
622+
};
609623
!tcx.type_of(last_field.did).instantiate_identity().is_sized(tcx, typing_env)
610624
});
611625

compiler/rustc_ty_utils/src/ty.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
278278
}
279279
}
280280

281-
fn typing_env_normalized_for_post_analysis(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TypingEnv<'_> {
282-
ty::TypingEnv::non_body_analysis(tcx, def_id).with_post_analysis_normalized(tcx)
281+
fn param_env_normalized_for_post_analysis(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
282+
tcx.param_env(def_id).with_normalized(tcx)
283283
}
284284

285285
/// Check if a function is async.
@@ -394,7 +394,7 @@ pub(crate) fn provide(providers: &mut Providers) {
394394
asyncness,
395395
adt_sizedness_constraint,
396396
param_env,
397-
typing_env_normalized_for_post_analysis,
397+
param_env_normalized_for_post_analysis,
398398
defaultness,
399399
unsizing_params_for_adt,
400400
impl_self_is_guaranteed_unsized,

tests/crashes/120016.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//@ known-bug: #120016
2-
//@ compile-flags: -Zcrate-attr=feature(const_async_blocks)
32
//@ edition: 2021
43

54
#![feature(type_alias_impl_trait, const_async_blocks)]

tests/crashes/137916.rs renamed to tests/ui/async-await/box-dyn-non-send.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
//@ known-bug: #137916
1+
//! Regression test for ICE #137916.
22
//@ edition: 2021
3+
34
use std::ptr::null;
45

56
async fn a() -> Box<dyn Send> {
67
Box::new(async {
8+
//~^ ERROR future cannot be sent between threads safely
79
let non_send = null::<()>();
810
&non_send;
911
async {}.await
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error: future cannot be sent between threads safely
2+
--> $DIR/box-dyn-non-send.rs:7:5
3+
|
4+
LL | / Box::new(async {
5+
LL | |
6+
LL | | let non_send = null::<()>();
7+
LL | | &non_send;
8+
LL | | async {}.await
9+
LL | | })
10+
| |______^ future created by async block is not `Send`
11+
|
12+
= help: within `{async block@$DIR/box-dyn-non-send.rs:7:14: 7:19}`, the trait `Send` is not implemented for `*const ()`
13+
note: future is not `Send` as this value is used across an await
14+
--> $DIR/box-dyn-non-send.rs:11:18
15+
|
16+
LL | let non_send = null::<()>();
17+
| -------- has type `*const ()` which is not `Send`
18+
LL | &non_send;
19+
LL | async {}.await
20+
| ^^^^^ await occurs here, with `non_send` maybe used later
21+
= note: required for the cast from `Box<{async block@$DIR/box-dyn-non-send.rs:7:14: 7:19}>` to `Box<dyn Send>`
22+
23+
error: aborting due to 1 previous error
24+

0 commit comments

Comments
 (0)