Skip to content

Commit 35579d1

Browse files
committed
Do not compute coroutine layout in non-Codegen typing mode.
1 parent 166c2a2 commit 35579d1

File tree

10 files changed

+85
-21
lines changed

10 files changed

+85
-21
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
@@ -1112,7 +1112,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
11121112
if !tcx.is_async_drop_in_place_coroutine(def_id.to_def_id()) {
11131113
// Eagerly check the unsubstituted layout for cycles.
11141114
tcx.ensure_ok().layout_of(
1115-
ty::TypingEnv::post_analysis(tcx, def_id.to_def_id())
1115+
ty::TypingEnv::codegen(tcx, def_id.to_def_id())
11161116
.as_query_input(tcx.type_of(def_id).instantiate_identity()),
11171117
);
11181118
}

compiler/rustc_middle/src/query/mod.rs

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

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,17 @@ impl<'tcx> ParamEnv<'tcx> {
10021002
pub fn and<T: TypeVisitable<TyCtxt<'tcx>>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
10031003
ParamEnvAnd { param_env: self, value }
10041004
}
1005+
1006+
/// Eagerly reveal all opaque types in the `param_env`.
1007+
pub fn with_normalized(self, tcx: TyCtxt<'tcx>) -> ParamEnv<'tcx> {
1008+
// No need to reveal opaques with the new solver enabled,
1009+
// since we have lazy norm.
1010+
if tcx.next_trait_solver_globally() {
1011+
self
1012+
} else {
1013+
ParamEnv::new(tcx.reveal_opaque_types_in_bounds(self.caller_bounds))
1014+
}
1015+
}
10051016
}
10061017

10071018
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
@@ -1055,7 +1066,17 @@ impl<'tcx> TypingEnv<'tcx> {
10551066
}
10561067

10571068
pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryParam<DefId>) -> TypingEnv<'tcx> {
1058-
tcx.typing_env_normalized_for_post_analysis(def_id)
1069+
TypingEnv {
1070+
typing_mode: TypingMode::PostAnalysis,
1071+
param_env: tcx.param_env_normalized_for_post_analysis(def_id),
1072+
}
1073+
}
1074+
1075+
pub fn codegen(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryParam<DefId>) -> TypingEnv<'tcx> {
1076+
TypingEnv {
1077+
typing_mode: TypingMode::Codegen,
1078+
param_env: tcx.param_env_normalized_for_post_analysis(def_id),
1079+
}
10591080
}
10601081

10611082
/// Modify the `typing_mode` to `PostAnalysis` or `Codegen` and eagerly reveal all opaque types
@@ -1066,16 +1087,22 @@ impl<'tcx> TypingEnv<'tcx> {
10661087
return self;
10671088
}
10681089

1069-
// No need to reveal opaques with the new solver enabled,
1070-
// since we have lazy norm.
1071-
let param_env = if tcx.next_trait_solver_globally() {
1072-
param_env
1073-
} else {
1074-
ParamEnv::new(tcx.reveal_opaque_types_in_bounds(param_env.caller_bounds()))
1075-
};
1090+
let param_env = param_env.with_normalized(tcx);
10761091
TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env }
10771092
}
10781093

1094+
/// Modify the `typing_mode` to `PostAnalysis` or `Codegen` and eagerly reveal all opaque types
1095+
/// in the `param_env`.
1096+
pub fn with_codegen_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> {
1097+
let TypingEnv { typing_mode, param_env } = self;
1098+
if let TypingMode::Codegen = typing_mode {
1099+
return self;
1100+
}
1101+
1102+
let param_env = param_env.with_normalized(tcx);
1103+
TypingEnv { typing_mode: TypingMode::Codegen, param_env }
1104+
}
1105+
10791106
/// Combine this typing environment with the given `value` to be used by
10801107
/// not (yet) canonicalized queries. This only works if the value does not
10811108
/// contain anything local to some `InferCtxt`, i.e. inference variables or

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,8 @@ 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 = self
109-
.tcx
110-
.erase_and_anonymize_regions(self.typing_env)
111-
.with_post_analysis_normalized(self.tcx);
108+
let typing_env =
109+
self.tcx.erase_and_anonymize_regions(self.typing_env).with_codegen_normalized(self.tcx);
112110
let uv = self.tcx.erase_and_anonymize_regions(uv);
113111

114112
// 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
@@ -498,6 +498,17 @@ fn layout_of_uncached<'tcx>(
498498
}
499499

500500
ty::Coroutine(def_id, args) => {
501+
match cx.typing_env.typing_mode {
502+
ty::TypingMode::Codegen => {}
503+
ty::TypingMode::Coherence
504+
| ty::TypingMode::Analysis { .. }
505+
| ty::TypingMode::Borrowck { .. }
506+
| ty::TypingMode::PostBorrowckAnalysis { .. }
507+
| ty::TypingMode::PostAnalysis => {
508+
return Err(error(cx, LayoutError::TooGeneric(ty)));
509+
}
510+
}
511+
501512
use rustc_middle::ty::layout::PrimitiveExt as _;
502513

503514
let info = tcx.coroutine_layout(def_id, args)?;
@@ -637,7 +648,10 @@ fn layout_of_uncached<'tcx>(
637648

638649
let maybe_unsized = def.is_struct()
639650
&& def.non_enum_variant().tail_opt().is_some_and(|last_field| {
640-
let typing_env = ty::TypingEnv::post_analysis(tcx, def.did());
651+
let typing_env = ty::TypingEnv {
652+
typing_mode: cx.typing_env.typing_mode,
653+
param_env: tcx.param_env_normalized_for_post_analysis(def.did()),
654+
};
641655
!tcx.type_of(last_field.did).instantiate_identity().is_sized(tcx, typing_env)
642656
});
643657

compiler/rustc_ty_utils/src/ty.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
285285
}
286286
}
287287

288-
fn typing_env_normalized_for_post_analysis(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TypingEnv<'_> {
289-
ty::TypingEnv::non_body_analysis(tcx, def_id).with_post_analysis_normalized(tcx)
288+
fn param_env_normalized_for_post_analysis(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
289+
tcx.param_env(def_id).with_normalized(tcx)
290290
}
291291

292292
/// Check if a function is async.
@@ -402,7 +402,7 @@ pub(crate) fn provide(providers: &mut Providers) {
402402
asyncness,
403403
adt_sizedness_constraint,
404404
param_env,
405-
typing_env_normalized_for_post_analysis,
405+
param_env_normalized_for_post_analysis,
406406
defaultness,
407407
unsizing_params_for_adt,
408408
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)