From 2b2eba8ffbaad4c63ee57db2f7a7247df39d8956 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 18 Apr 2026 01:37:17 +0000 Subject: [PATCH 1/4] Introduce TypingMode::Codegen. --- .../src/const_eval/eval_queries.rs | 38 +++++++++++++------ .../src/const_eval/valtrees.rs | 4 +- .../src/interpret/eval_context.rs | 4 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 3 +- compiler/rustc_hir_typeck/src/opaque_types.rs | 3 +- compiler/rustc_infer/src/infer/mod.rs | 9 +++-- .../rustc_infer/src/infer/opaque_types/mod.rs | 4 +- compiler/rustc_middle/src/ty/mod.rs | 8 ++-- .../rustc_mir_transform/src/elaborate_drop.rs | 2 +- .../src/solve/assembly/mod.rs | 4 +- .../src/solve/eval_ctxt/mod.rs | 8 +++- .../rustc_next_trait_solver/src/solve/mod.rs | 2 +- .../src/solve/normalizes_to/mod.rs | 3 +- .../src/solve/normalizes_to/opaque_types.rs | 5 ++- .../src/solve/search_graph.rs | 1 + .../src/solve/trait_goals.rs | 1 + .../src/solve/delegate.rs | 2 +- .../src/solve/fulfill.rs | 3 +- .../src/traits/fulfill.rs | 3 +- .../src/traits/normalize.rs | 4 +- .../src/traits/project.rs | 2 +- .../src/traits/query/normalize.rs | 2 +- .../src/traits/select/mod.rs | 6 ++- compiler/rustc_ty_utils/src/instance.rs | 4 +- compiler/rustc_type_ir/src/infer_ctxt.rs | 26 ++++++++----- .../rustc_type_ir/src/region_constraint.rs | 3 +- compiler/rustc_type_ir/src/relate/combine.rs | 3 +- ...-assoc-const-static-recursion-trait.stderr | 22 ++++++----- .../const-eval/const-eval-query-stack.stderr | 5 ++- tests/ui/consts/const-size_of-cycle.stderr | 5 +++ tests/ui/consts/issue-44415.stderr | 5 +++ 31 files changed, 129 insertions(+), 65 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 62ec0d2ef8bf4..09d9ccab4b359 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -369,33 +369,49 @@ pub fn eval_to_allocation_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>, ) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> { + let ty::PseudoCanonicalInput { typing_env, value } = key; + // This shouldn't be used for statics, since statics are conceptually places, // not values -- so what we do here could break pointer identity. assert!(key.value.promoted.is_some() || !tcx.is_static(key.value.instance.def_id())); - if cfg!(debug_assertions) { - match key.typing_env.typing_mode().assert_not_erased() { - ty::TypingMode::PostAnalysis => {} - ty::TypingMode::Coherence - | ty::TypingMode::Analysis { .. } - | ty::TypingMode::Borrowck { .. } - | ty::TypingMode::PostBorrowckAnalysis { .. } => { + match key.typing_env.typing_mode().assert_not_erased() { + ty::TypingMode::PostAnalysis => {} + // We are in codegen. It's very likely this constant has been evaluated in PostAnalysis before. + // Try to reuse this evaluation, and only re-run if we hit a `TooGeneric` error. + ty::TypingMode::Codegen => { + let with_postanalysis = + ty::TypingEnv::new(typing_env.param_env, ty::TypingMode::PostAnalysis); + let with_postanalysis = + tcx.eval_to_allocation_raw(with_postanalysis.as_query_input(value)); + match with_postanalysis { + Ok(_) | Err(ErrorHandled::Reported(..)) => return with_postanalysis, + Err(ErrorHandled::TooGeneric(_)) => {} + } + } + ty::TypingMode::Coherence + | ty::TypingMode::Analysis { .. } + | ty::TypingMode::Borrowck { .. } + | ty::TypingMode::PostBorrowckAnalysis { .. } => { + if cfg!(debug_assertions) { bug!( - "Const eval should always happens in PostAnalysis mode. See the comment in `InterpCx::new` for more details." + "Const eval should always happens in PostAnalysis or Codegen mode. See the comment in `InterpCx::new` for more details." ) } } + } + if cfg!(debug_assertions) { // Make sure we format the instance even if we do not print it. // This serves as a regression test against an ICE on printing. // The next two lines concatenated contain some discussion: // https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/ // subject/anon_const_instance_printing/near/135980032 - let instance = with_no_trimmed_paths!(key.value.instance.to_string()); - trace!("const eval: {:?} ({})", key, instance); + let instance = with_no_trimmed_paths!(value.instance.to_string()); + trace!("const eval: {:?} ({}) inside {:?}", value, instance, typing_env); } - eval_in_interpreter(tcx, key.value, key.typing_env) + eval_in_interpreter(tcx, value, typing_env) } fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>( diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 1e65496926e84..f5bd476bdf332 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -243,13 +243,13 @@ pub(crate) fn eval_to_valtree<'tcx>( ) -> EvalToValTreeResult<'tcx> { if cfg!(debug_assertions) { match typing_env.typing_mode().assert_not_erased() { - ty::TypingMode::PostAnalysis => {} + ty::TypingMode::PostAnalysis | ty::TypingMode::Codegen => {} ty::TypingMode::Coherence | ty::TypingMode::Analysis { .. } | ty::TypingMode::Borrowck { .. } | ty::TypingMode::PostBorrowckAnalysis { .. } => { bug!( - "Const eval should always happens in PostAnalysis mode. See the comment in `InterpCx::new` for more details." + "Const eval should always happens in PostAnalysis or Codegen mode. See the comment in `InterpCx::new` for more details." ) } } diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 7dc6d292a94af..a06a306ab5593 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -244,12 +244,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // already been revealed, so we'd be able to at least partially observe the hidden types anyways. if cfg!(debug_assertions) { match typing_env.typing_mode().assert_not_erased() { - TypingMode::PostAnalysis => {} + TypingMode::PostAnalysis | TypingMode::Codegen => {} TypingMode::Coherence | TypingMode::Analysis { .. } | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => { - bug!("Const eval should always happens in PostAnalysis mode."); + bug!("Const eval should always happens in PostAnalysis or Codegen mode."); } } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index db5994bca3d3d..9530ff4ca9a3d 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -663,7 +663,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::TypingMode::Coherence | ty::TypingMode::Borrowck { .. } | ty::TypingMode::PostBorrowckAnalysis { .. } - | ty::TypingMode::PostAnalysis => { + | ty::TypingMode::PostAnalysis + | ty::TypingMode::Codegen => { bug!() } }; diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs index b7936ea47944c..3229ad161783b 100644 --- a/compiler/rustc_hir_typeck/src/opaque_types.rs +++ b/compiler/rustc_hir_typeck/src/opaque_types.rs @@ -105,7 +105,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> { ty::TypingMode::Coherence | ty::TypingMode::Borrowck { .. } | ty::TypingMode::PostBorrowckAnalysis { .. } - | ty::TypingMode::PostAnalysis => { + | ty::TypingMode::PostAnalysis + | ty::TypingMode::Codegen => { bug!() } }; diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index c0029719c6e12..4e45bfe0e54c6 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -350,7 +350,8 @@ impl<'tcx> Drop for InferCtxt<'tcx> { TypingMode::Coherence | TypingMode::Analysis { .. } | TypingMode::PostBorrowckAnalysis { .. } - | TypingMode::PostAnalysis => {} + | TypingMode::PostAnalysis + | TypingMode::Codegen => {} // In erased mode, the opaque type storage is always empty TypingMode::ErasedNotCoherence(..) => {} TypingMode::Borrowck { .. } => { @@ -1156,7 +1157,8 @@ impl<'tcx> InferCtxt<'tcx> { // to support PostBorrowckAnalysis in the old solver as well. TypingMode::Coherence | TypingMode::PostBorrowckAnalysis { .. } - | TypingMode::PostAnalysis => false, + | TypingMode::PostAnalysis + | TypingMode::Codegen => false, } } @@ -1486,7 +1488,8 @@ impl<'tcx> InferCtxt<'tcx> { } mode @ (ty::TypingMode::Coherence | ty::TypingMode::PostBorrowckAnalysis { .. } - | ty::TypingMode::PostAnalysis) => mode, + | ty::TypingMode::PostAnalysis + | ty::TypingMode::Codegen) => mode, ty::TypingMode::ErasedNotCoherence(MayBeErased) => unreachable!(), }; ty::TypingEnv::new(param_env, typing_mode) diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 6b051f42421b0..c3194e4d8acd3 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -283,7 +283,9 @@ impl<'tcx> InferCtxt<'tcx> { .map(|obligation| obligation.as_goal()), ); } - mode @ (ty::TypingMode::PostBorrowckAnalysis { .. } | ty::TypingMode::PostAnalysis) => { + mode @ (ty::TypingMode::PostBorrowckAnalysis { .. } + | ty::TypingMode::PostAnalysis + | ty::TypingMode::Codegen) => { bug!("insert hidden type in {mode:?}") } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 74f9e75fb48c0..5180601684f3b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1071,7 +1071,7 @@ impl<'tcx> TypingEnv<'tcx> { /// use `TypingMode::PostAnalysis`, they may still have where-clauses /// in scope. pub fn fully_monomorphized() -> TypingEnv<'tcx> { - Self::new(ParamEnv::empty(), TypingMode::PostAnalysis) + Self::new(ParamEnv::empty(), TypingMode::Codegen) } /// Create a typing environment for use during analysis outside of a body. @@ -1092,8 +1092,8 @@ impl<'tcx> TypingEnv<'tcx> { tcx.typing_env_normalized_for_post_analysis(def_id) } - /// Modify the `typing_mode` to `PostAnalysis` and eagerly reveal all - /// opaque types in the `param_env`. + /// Modify the `typing_mode` to `PostAnalysis` or `Codegen` and eagerly reveal all opaque types + /// in the `param_env`. pub fn with_post_analysis_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> { let TypingEnv { typing_mode, param_env } = self; @@ -1107,7 +1107,7 @@ impl<'tcx> TypingEnv<'tcx> { | TypingMode::Analysis { .. } | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => {} - TypingMode::PostAnalysis => return self, + TypingMode::PostAnalysis | TypingMode::Codegen => return self, } ParamEnv::new(tcx.reveal_opaque_types_in_bounds(param_env.caller_bounds())) diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index c835ff7dbe070..268851bdbe73f 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -539,7 +539,7 @@ where let tcx = self.tcx(); match self.elaborator.typing_env().typing_mode().assert_not_erased() { - ty::TypingMode::PostAnalysis => {} + ty::TypingMode::PostAnalysis | ty::TypingMode::Codegen => {} ty::TypingMode::Coherence | ty::TypingMode::Analysis { .. } | ty::TypingMode::Borrowck { .. } diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 7f3627c6db54e..16f2134684889 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -484,6 +484,7 @@ where | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } | TypingMode::PostAnalysis + | TypingMode::Codegen | TypingMode::ErasedNotCoherence(MayBeErased) => !candidates.iter().any(|c| { matches!( c.source, @@ -1056,7 +1057,8 @@ where TypingMode::Coherence | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } - | TypingMode::PostAnalysis => vec![], + | TypingMode::PostAnalysis + | TypingMode::Codegen => vec![], TypingMode::ErasedNotCoherence(MayBeErased) => { self.opaque_accesses .rerun_if_any_opaque_has_infer_as_hidden_type(RerunReason::SelfTyInfer)?; diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 54d306466cf5b..23fcfc2788656 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -771,7 +771,10 @@ where // ============================= (RerunCondition::Always, _) => RerunDecision::Yes, // ============================= - (RerunCondition::OpaqueInStorage(..), TypingMode::PostAnalysis) => RerunDecision::Yes, + ( + RerunCondition::OpaqueInStorage(..), + TypingMode::PostAnalysis | TypingMode::Codegen, + ) => RerunDecision::Yes, ( RerunCondition::OpaqueInStorage(defids), TypingMode::PostBorrowckAnalysis { defined_opaque_types: opaques } @@ -786,12 +789,13 @@ where RerunCondition::AnyOpaqueHasInferAsHidden, TypingMode::PostBorrowckAnalysis { .. } | TypingMode::PostAnalysis + | TypingMode::Codegen | TypingMode::Borrowck { .. }, ) => RerunDecision::No, // ============================= ( RerunCondition::OpaqueInStorageOrAnyOpaqueHasInferAsHidden(_), - TypingMode::PostAnalysis, + TypingMode::PostAnalysis | TypingMode::Codegen, ) => RerunDecision::No, ( RerunCondition::OpaqueInStorageOrAnyOpaqueHasInferAsHidden(defids), diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index fbd6bdfa0a989..aed42c3179aa2 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -396,7 +396,7 @@ where .assert_not_erased() { // Opaques are never rigid outside of analysis mode. - TypingMode::Coherence | TypingMode::PostAnalysis => false, + TypingMode::Coherence | TypingMode::PostAnalysis | TypingMode::Codegen => false, // During analysis, opaques are rigid unless they may be defined by // the current body. TypingMode::Analysis { defining_opaque_types_and_generators: non_rigid_opaques } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index e9a4d7e5919ad..45390e8b804ac 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -325,7 +325,8 @@ where ty::TypingMode::Analysis { .. } | ty::TypingMode::Borrowck { .. } | ty::TypingMode::PostBorrowckAnalysis { .. } - | ty::TypingMode::PostAnalysis => { + | ty::TypingMode::PostAnalysis + | ty::TypingMode::Codegen => { ecx.structurally_instantiate_normalizes_to_term( goal, goal.predicate.alias, diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs index 57d10b4ac1fe1..ddac4faeb49d8 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs @@ -100,7 +100,8 @@ where } TypingMode::Coherence | TypingMode::PostBorrowckAnalysis { .. } - | TypingMode::PostAnalysis => unreachable!(), + | TypingMode::PostAnalysis + | TypingMode::Codegen => unreachable!(), } } @@ -138,7 +139,7 @@ where self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) .map_err(Into::into) } - TypingMode::PostAnalysis => { + TypingMode::PostAnalysis | TypingMode::Codegen => { // FIXME: Add an assertion that opaque type storage is empty. let actual = cx.type_of(def_id.into()).instantiate(cx, opaque_ty.args).skip_norm_wip(); diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs index a46261fcf7271..38b21bfea432a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs +++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs @@ -72,6 +72,7 @@ where | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } | TypingMode::PostAnalysis + | TypingMode::Codegen | TypingMode::ErasedNotCoherence(MayBeErased) => { (Err(NoSolution), AccessedOpaques::default()) } diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index f3ace5a70c69c..b652466407d70 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -1609,6 +1609,7 @@ where } TypingMode::Coherence | TypingMode::PostAnalysis + | TypingMode::Codegen | TypingMode::Borrowck { defining_opaque_types: _ } | TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => {} } diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 49d8d0845d86b..bd22ba6b6bf6d 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -338,7 +338,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< | TypingMode::Analysis { .. } | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => false, - TypingMode::PostAnalysis => { + TypingMode::PostAnalysis | TypingMode::Codegen => { let poly_trait_ref = self.resolve_vars_if_possible(goal_trait_ref); !poly_trait_ref.still_further_specializable() } diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index ed345d98b5392..78220d4d426b7 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -283,7 +283,8 @@ where TypingMode::Coherence | TypingMode::Borrowck { defining_opaque_types: _ } | TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } - | TypingMode::PostAnalysis => return Default::default(), + | TypingMode::PostAnalysis + | TypingMode::Codegen => return Default::default(), }; if stalled_coroutines.is_empty() { diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 914e103afded3..463e8fdeb5017 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -178,7 +178,8 @@ where TypingMode::Coherence | TypingMode::Borrowck { defining_opaque_types: _ } | TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } - | TypingMode::PostAnalysis => return Default::default(), + | TypingMode::PostAnalysis + | TypingMode::Codegen => return Default::default(), }; if stalled_coroutines.is_empty() { diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 84dbd53de83f2..d51ef0eaee58c 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -144,7 +144,7 @@ pub(super) fn needs_normalization<'tcx, T: TypeVisitable>>( | TypingMode::Analysis { .. } | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE), - TypingMode::PostAnalysis => {} + TypingMode::PostAnalysis | TypingMode::Codegen => {} } value.has_type_flags(flags) @@ -416,7 +416,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx | TypingMode::Analysis { .. } | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => ty.super_fold_with(self), - TypingMode::PostAnalysis => { + TypingMode::PostAnalysis | TypingMode::Codegen => { let recursion_limit = self.cx().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.selcx.infcx.err_ctxt().report_overflow_error( diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 900d55cc556fc..15a69770d2bbe 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -962,7 +962,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( ); false } - TypingMode::PostAnalysis => { + TypingMode::PostAnalysis | TypingMode::Codegen => { // NOTE(eddyb) inference variables can resolve to parameters, so // assume `poly_trait_ref` isn't monomorphic, if it contains any. let poly_trait_ref = diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index e8c5d10c78ce3..1f65f05bcd1a9 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -221,7 +221,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } => ty.try_super_fold_with(self)?, - TypingMode::PostAnalysis => { + TypingMode::PostAnalysis | TypingMode::Codegen => { let args = data.args.try_fold_with(self)?; let recursion_limit = self.cx().recursion_limit(); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index eadc937639f20..c6720309feaff 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1488,7 +1488,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { TypingMode::Analysis { .. } | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } - | TypingMode::PostAnalysis => return Ok(()), + | TypingMode::PostAnalysis + | TypingMode::Codegen => return Ok(()), } debug!("is_knowable()"); @@ -1547,7 +1548,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // // FIXME(#132279): This is still incorrect as we treat opaque types // and default associated items differently between these two modes. - TypingMode::PostAnalysis => true, + TypingMode::PostAnalysis | TypingMode::Codegen => true, } } @@ -2914,6 +2915,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } TypingMode::Coherence | TypingMode::PostAnalysis + | TypingMode::Codegen | TypingMode::Borrowck { defining_opaque_types: _ } | TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => false, } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index f5ff24af85b91..3aaa3fee61a16 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -160,7 +160,9 @@ fn resolve_associated_item<'tcx>( | ty::TypingMode::Analysis { .. } | ty::TypingMode::Borrowck { .. } | ty::TypingMode::PostBorrowckAnalysis { .. } => false, - ty::TypingMode::PostAnalysis => !trait_ref.still_further_specializable(), + ty::TypingMode::PostAnalysis | ty::TypingMode::Codegen => { + !trait_ref.still_further_specializable() + } } }; if !eligible { diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index 7957bacda5677..99ce842295167 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -119,16 +119,19 @@ pub enum TypingMode { /// This is currently only used by the new solver, but should be implemented in /// the old solver as well. PostBorrowckAnalysis { defined_opaque_types: I::LocalDefIds }, - /// After analysis, mostly during codegen and MIR optimizations, we're able to + /// After analysis, mostly during MIR optimizations, we're able to /// reveal all opaque types. As the hidden type should *never* be observable /// directly by the user, this should not be used by checks which may expose /// such details to the user. /// - /// There are some exceptions to this as for example `layout_of` and const-evaluation - /// always run in `PostAnalysis` mode, even when used during analysis. This exposes - /// some information about the underlying type to users, but not the type itself. + /// However, we restrict `layout_of` and const-evaluation from exposing some information like + /// coroutine layout which requires optimized MIR. PostAnalysis, + /// During codegen and MIR optimizations, we're able to reveal all opaque types and compute all + /// layouts. + Codegen, + /// The typing modes above (except coherence) only differ in how they handle /// /// - Generators @@ -179,6 +182,7 @@ impl PartialEq for TypingModeEqWrapper { TypingMode::PostBorrowckAnalysis { defined_opaque_types: r }, ) => l == r, (TypingMode::PostAnalysis, TypingMode::PostAnalysis) => true, + (TypingMode::Codegen, TypingMode::Codegen) => true, ( TypingMode::ErasedNotCoherence(MayBeErased), TypingMode::ErasedNotCoherence(MayBeErased), @@ -189,6 +193,7 @@ impl PartialEq for TypingModeEqWrapper { | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } | TypingMode::PostAnalysis + | TypingMode::Codegen | TypingMode::ErasedNotCoherence(MayBeErased), _, ) => false, @@ -211,6 +216,7 @@ impl TypingMode { | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } | TypingMode::PostAnalysis + | TypingMode::Codegen | TypingMode::ErasedNotCoherence(_) => false, } } @@ -227,7 +233,8 @@ impl TypingMode { | TypingMode::Analysis { .. } | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } - | TypingMode::PostAnalysis => false, + | TypingMode::PostAnalysis + | TypingMode::Codegen => false, } } } @@ -250,6 +257,7 @@ impl TypingMode { TypingMode::PostBorrowckAnalysis { defined_opaque_types } } TypingMode::PostAnalysis => TypingMode::PostAnalysis, + TypingMode::Codegen => TypingMode::Codegen, TypingMode::ErasedNotCoherence(MayBeErased) => panic!( "Called `assert_not_erased` from a place that can be called by the trait solver in `TypingMode::ErasedNotCoherence`. `TypingMode` is `ErasedNotCoherence` in a place where that should be impossible" ), @@ -314,6 +322,7 @@ impl From> for TypingMode TypingMode::PostAnalysis, + TypingMode::Codegen => TypingMode::Codegen, } } } @@ -535,9 +544,8 @@ where TypingMode::Coherence | TypingMode::Analysis { .. } | TypingMode::Borrowck { .. } - | TypingMode::PostBorrowckAnalysis { .. } => { - infcx.cx().features().feature_bound_holds_in_crate(symbol) - } - TypingMode::PostAnalysis => true, + | TypingMode::PostBorrowckAnalysis { .. } + | TypingMode::PostAnalysis => infcx.cx().features().feature_bound_holds_in_crate(symbol), + TypingMode::Codegen => true, } } diff --git a/compiler/rustc_type_ir/src/region_constraint.rs b/compiler/rustc_type_ir/src/region_constraint.rs index ab9553da42f89..43b1535d16809 100644 --- a/compiler/rustc_type_ir/src/region_constraint.rs +++ b/compiler/rustc_type_ir/src/region_constraint.rs @@ -902,7 +902,8 @@ fn rewrite_type_outlives_constraints_in_universe_for_eager_placeholder_handling< | TypingMode::ErasedNotCoherence { .. } | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } - | TypingMode::PostAnalysis => (), + | TypingMode::PostAnalysis + | TypingMode::Codegen => (), }; RegionConstraint::Or(candidates.into_boxed_slice()) diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs index 77dfed9c3313a..5fd572f8724cd 100644 --- a/compiler/rustc_type_ir/src/relate/combine.rs +++ b/compiler/rustc_type_ir/src/relate/combine.rs @@ -143,7 +143,8 @@ where TypingMode::Analysis { .. } | TypingMode::Borrowck { .. } | TypingMode::PostBorrowckAnalysis { .. } - | TypingMode::PostAnalysis => structurally_relate_tys(relation, a, b), + | TypingMode::PostAnalysis + | TypingMode::Codegen => structurally_relate_tys(relation, a, b), } } diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr index 8197cfcba5025..d9394868aece2 100644 --- a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr +++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr @@ -1,14 +1,9 @@ -error[E0391]: cycle detected when simplifying constant for the type system `TRAIT_REF_BAR` - --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 - | -LL | const TRAIT_REF_BAR: u32 = ::BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`... +error[E0391]: cycle detected when const-evaluating + checking `TRAIT_REF_BAR` --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:28 | LL | const TRAIT_REF_BAR: u32 = ::BAR; | ^^^^^^^^^^^^^^^^^^^^^ + | note: ...which requires simplifying constant for the type system `::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5 | @@ -29,8 +24,17 @@ note: ...which requires elaborating drops for ` $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 + | +LL | const TRAIT_REF_BAR: u32 = ::BAR; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which again requires const-evaluating + checking `TRAIT_REF_BAR`, completing the cycle +note: cycle used when const-evaluating + checking `TRAIT_REF_BAR` + --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 + | +LL | const TRAIT_REF_BAR: u32 = ::BAR; + | ^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-eval/const-eval-query-stack.stderr b/tests/ui/consts/const-eval/const-eval-query-stack.stderr index 89f9c1e36920d..8d472a21fe253 100644 --- a/tests/ui/consts/const-eval/const-eval-query-stack.stderr +++ b/tests/ui/consts/const-eval/const-eval-query-stack.stderr @@ -9,6 +9,7 @@ note: please make sure that you have updated to the latest nightly query stack during panic: #0 [eval_to_allocation_raw] const-evaluating + checking `X` -#1 [eval_to_const_value_raw] simplifying constant for the type system `X` -#2 [analysis] running analysis passes on crate `const_eval_query_stack` +#1 [eval_to_allocation_raw] const-evaluating + checking `X` +#2 [eval_to_const_value_raw] simplifying constant for the type system `X` +#3 [analysis] running analysis passes on crate `const_eval_query_stack` end of query stack diff --git a/tests/ui/consts/const-size_of-cycle.stderr b/tests/ui/consts/const-size_of-cycle.stderr index 6a7f44ed35893..493cb1804fea2 100644 --- a/tests/ui/consts/const-size_of-cycle.stderr +++ b/tests/ui/consts/const-size_of-cycle.stderr @@ -4,6 +4,11 @@ error[E0391]: cycle detected when evaluating type-level constant LL | bytes: [u8; std::mem::size_of::()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | +note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`... + --> $DIR/const-size_of-cycle.rs:2:17 + | +LL | bytes: [u8; std::mem::size_of::()] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`... --> $SRC_DIR/core/src/mem/mod.rs:LL:COL note: ...which requires simplifying constant for the type system `core::mem::SizedTypeProperties::SIZE`... diff --git a/tests/ui/consts/issue-44415.stderr b/tests/ui/consts/issue-44415.stderr index 28f6813717337..e9170aeba6555 100644 --- a/tests/ui/consts/issue-44415.stderr +++ b/tests/ui/consts/issue-44415.stderr @@ -9,6 +9,11 @@ note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`.. | LL | bytes: [u8; unsafe { intrinsics::size_of::() }], | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`... + --> $DIR/issue-44415.rs:6:17 + | +LL | bytes: [u8; unsafe { intrinsics::size_of::() }], + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires computing layout of `Foo`... --> $DIR/issue-44415.rs:5:1 | From 2897e52e5bb4ead327d4a0b0685db2aa223918c5 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 16 Aug 2025 14:23:49 +0000 Subject: [PATCH 2/4] Reuse result from eval_to_const_value_raw. --- .../src/const_eval/eval_queries.rs | 33 ++++++++++++++++++- ...-assoc-const-static-recursion-trait.stderr | 18 +++++----- .../const-eval/const-eval-query-stack.stderr | 2 +- tests/ui/consts/recursive-block.stderr | 2 +- 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 09d9ccab4b359..8b4ac3d9e7eed 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -327,9 +327,40 @@ pub fn eval_to_const_value_raw_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>, ) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> { - if let Some((value, _ty)) = tcx.trivial_const(key.value.instance.def_id()) { + let ty::PseudoCanonicalInput { typing_env, value } = key; + + if let Some((value, _ty)) = tcx.trivial_const(value.instance.def_id()) { return Ok(value); } + + match typing_env.typing_mode().assert_not_erased() { + ty::TypingMode::PostAnalysis => {} + // We are in codegen. It's very likely this constant has been evaluated in PostAnalysis before. + // Try to reuse this evaluation, and only re-run if we hit a `TooGeneric` error. + ty::TypingMode::Codegen => { + let with_postanalysis = + ty::TypingEnv::new(typing_env.param_env, ty::TypingMode::PostAnalysis); + let with_postanalysis = + tcx.eval_to_const_value_raw(with_postanalysis.as_query_input(value)); + match with_postanalysis { + Ok(_) | Err(ErrorHandled::Reported(..)) => return with_postanalysis, + Err(ErrorHandled::TooGeneric(_)) => {} + } + } + // Const eval always happens in PostAnalysis or Codegen mode. See the comment in + // `InterpCx::new` for more details. + ty::TypingMode::Coherence + | ty::TypingMode::Analysis { .. } + | ty::TypingMode::Borrowck { .. } + | ty::TypingMode::PostBorrowckAnalysis { .. } => { + if cfg!(debug_assertions) { + bug!( + "Const eval should always happens in PostAnalysis or Codegen mode. See the comment in `InterpCx::new` for more details." + ) + } + } + } + tcx.eval_to_allocation_raw(key).map(|val| turn_into_const_value(tcx, val, key)) } diff --git a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr index d9394868aece2..842b5328024b0 100644 --- a/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr +++ b/tests/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr @@ -1,9 +1,14 @@ -error[E0391]: cycle detected when const-evaluating + checking `TRAIT_REF_BAR` +error[E0391]: cycle detected when simplifying constant for the type system `TRAIT_REF_BAR` + --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 + | +LL | const TRAIT_REF_BAR: u32 = ::BAR; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:28 | LL | const TRAIT_REF_BAR: u32 = ::BAR; | ^^^^^^^^^^^^^^^^^^^^^ - | note: ...which requires simplifying constant for the type system `::BAR`... --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5 | @@ -24,13 +29,8 @@ note: ...which requires elaborating drops for ` $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 - | -LL | const TRAIT_REF_BAR: u32 = ::BAR; - | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which again requires const-evaluating + checking `TRAIT_REF_BAR`, completing the cycle -note: cycle used when const-evaluating + checking `TRAIT_REF_BAR` + = note: ...which again requires simplifying constant for the type system `TRAIT_REF_BAR`, completing the cycle +note: cycle used when simplifying constant for the type system `TRAIT_REF_BAR` --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1 | LL | const TRAIT_REF_BAR: u32 = ::BAR; diff --git a/tests/ui/consts/const-eval/const-eval-query-stack.stderr b/tests/ui/consts/const-eval/const-eval-query-stack.stderr index 8d472a21fe253..5e1179d3993af 100644 --- a/tests/ui/consts/const-eval/const-eval-query-stack.stderr +++ b/tests/ui/consts/const-eval/const-eval-query-stack.stderr @@ -9,7 +9,7 @@ note: please make sure that you have updated to the latest nightly query stack during panic: #0 [eval_to_allocation_raw] const-evaluating + checking `X` -#1 [eval_to_allocation_raw] const-evaluating + checking `X` +#1 [eval_to_const_value_raw] simplifying constant for the type system `X` #2 [eval_to_const_value_raw] simplifying constant for the type system `X` #3 [analysis] running analysis passes on crate `const_eval_query_stack` end of query stack diff --git a/tests/ui/consts/recursive-block.stderr b/tests/ui/consts/recursive-block.stderr index 90814e2e0002a..6294632e19864 100644 --- a/tests/ui/consts/recursive-block.stderr +++ b/tests/ui/consts/recursive-block.stderr @@ -5,7 +5,7 @@ LL | const { foo::<&T>() } | ^^^^^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_block`) - = note: query depth increased by 1 when computing layout of `foo<&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&i32>` + = note: query depth increased by 1 when computing layout of `foo<&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&i32>` error: aborting due to 1 previous error From c50a49495db493b038fc865ac70d855f829a6173 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 16 Aug 2025 17:39:51 +0000 Subject: [PATCH 3/4] Reuse cached layout from PostAnalysis when possible. --- compiler/rustc_ty_utils/src/layout.rs | 18 ++++++++++++++++++ .../recursion/recursion_limit/zero-overflow.rs | 2 +- .../recursion_limit/zero-overflow.stderr | 4 ++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 9cc15a374ff70..04fc732aa9d97 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -66,6 +66,24 @@ fn layout_of<'tcx>( return tcx.layout_of(typing_env.as_query_input(ty)); } + match typing_env.typing_mode() { + ty::TypingMode::Codegen => { + let with_postanalysis = + ty::TypingEnv::new(typing_env.param_env, ty::TypingMode::PostAnalysis); + let res = tcx.layout_of(with_postanalysis.as_query_input(ty)); + match res { + Err(LayoutError::TooGeneric(_)) => {} + _ => return res, + }; + } + ty::TypingMode::Coherence + | ty::TypingMode::Analysis { .. } + | ty::TypingMode::Borrowck { .. } + | ty::TypingMode::PostBorrowckAnalysis { .. } + | ty::TypingMode::ErasedNotCoherence(_) + | ty::TypingMode::PostAnalysis => {} + } + let cx = LayoutCx::new(tcx, typing_env); let layout = layout_of_uncached(&cx, ty)?; diff --git a/tests/ui/recursion/recursion_limit/zero-overflow.rs b/tests/ui/recursion/recursion_limit/zero-overflow.rs index 3887972a51623..718b8550c26c6 100644 --- a/tests/ui/recursion/recursion_limit/zero-overflow.rs +++ b/tests/ui/recursion/recursion_limit/zero-overflow.rs @@ -1,4 +1,4 @@ -//~ ERROR overflow evaluating the requirement `&mut Self: DispatchFromDyn<&mut RustaceansAreAwesome> +//~ ERROR queries overflow the depth limit! //~| HELP consider increasing the recursion limit //@ build-fail diff --git a/tests/ui/recursion/recursion_limit/zero-overflow.stderr b/tests/ui/recursion/recursion_limit/zero-overflow.stderr index fc03cc5b604b7..ca100c7c81a0c 100644 --- a/tests/ui/recursion/recursion_limit/zero-overflow.stderr +++ b/tests/ui/recursion/recursion_limit/zero-overflow.stderr @@ -1,7 +1,7 @@ -error[E0275]: overflow evaluating the requirement `&mut Self: DispatchFromDyn<&mut RustaceansAreAwesome>` +error: queries overflow the depth limit! | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`zero_overflow`) + = note: query depth increased by 2 when computing layout of `isize` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. From 0c715313d1fd444d9584f22fa838ecef4b979993 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Thu, 14 Aug 2025 01:40:01 +0000 Subject: [PATCH 4/4] Do not compute coroutine layout in non-Codegen typing mode. --- compiler/rustc_hir_typeck/src/intrinsicck.rs | 2 +- compiler/rustc_interface/src/passes.rs | 8 +-- compiler/rustc_middle/src/queries.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 58 +++++++++++++------ .../src/thir/pattern/const_to_pat.rs | 6 +- compiler/rustc_ty_utils/src/layout.rs | 17 +++++- compiler/rustc_ty_utils/src/ty.rs | 6 +- .../clippy/clippy_lints/src/large_futures.rs | 2 +- 8 files changed, 69 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 72283a6065580..5d03ef19c6b13 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -144,7 +144,7 @@ pub(crate) fn check_transmutes(tcx: TyCtxt<'_>, owner: LocalDefId) { let typeck_results = tcx.typeck(owner); let None = typeck_results.tainted_by_errors else { return }; - let typing_env = ty::TypingEnv::post_analysis(tcx, owner); + let typing_env = ty::TypingEnv::codegen(tcx, owner); for &(from, to, hir_id) in &typeck_results.transmutes_to_check { check_transmute(tcx, typing_env, from, to, hir_id); } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index bcd1a52ce9dcd..3d60ec9713700 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -1180,10 +1180,10 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { && (!tcx.is_async_drop_in_place_coroutine(def_id.to_def_id())) { // Eagerly check the unsubstituted layout for cycles. - tcx.ensure_ok().layout_of( - ty::TypingEnv::post_analysis(tcx, def_id.to_def_id()) - .as_query_input(tcx.type_of(def_id).instantiate_identity().skip_norm_wip()), - ); + tcx.ensure_ok() + .layout_of(ty::TypingEnv::codegen(tcx, def_id.to_def_id()).as_query_input( + tcx.type_of(def_id).instantiate_identity().skip_norm_wip(), + )); } }); }); diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index d62e4ec941d21..853e1a58da0f9 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -1649,7 +1649,7 @@ rustc_queries! { /// Like `param_env`, but returns the `ParamEnv` after all opaque types have been /// replaced with their hidden type. This is used in the old trait solver /// when in `PostAnalysis` mode and should not be called directly. - query typing_env_normalized_for_post_analysis(def_id: DefId) -> ty::TypingEnv<'tcx> { + query param_env_normalized_for_post_analysis(def_id: DefId) -> ty::ParamEnv<'tcx> { desc { "computing revealed normalized predicates of `{}`", tcx.def_path_str(def_id) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 5180601684f3b..6e3f4db8d1132 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1026,6 +1026,17 @@ impl<'tcx> ParamEnv<'tcx> { pub fn and>>(self, value: T) -> ParamEnvAnd<'tcx, T> { ParamEnvAnd { param_env: self, value } } + + /// Eagerly reveal all opaque types in the `param_env`. + pub fn with_normalized(self, tcx: TyCtxt<'tcx>) -> ParamEnv<'tcx> { + // No need to reveal opaques with the new solver enabled, + // since we have lazy norm. + if tcx.next_trait_solver_globally() { + self + } else { + ParamEnv::new(tcx.reveal_opaque_types_in_bounds(self.caller_bounds)) + } + } } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)] @@ -1088,31 +1099,44 @@ impl<'tcx> TypingEnv<'tcx> { } pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryKey) -> TypingEnv<'tcx> { - let def_id = def_id.into_query_key(); - tcx.typing_env_normalized_for_post_analysis(def_id) + TypingEnv::new(tcx.param_env_normalized_for_post_analysis(def_id), TypingMode::PostAnalysis) + } + + pub fn codegen(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryKey) -> TypingEnv<'tcx> { + TypingEnv::new(tcx.param_env_normalized_for_post_analysis(def_id), TypingMode::Codegen) } /// Modify the `typing_mode` to `PostAnalysis` or `Codegen` and eagerly reveal all opaque types /// in the `param_env`. pub fn with_post_analysis_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> { let TypingEnv { typing_mode, param_env } = self; + match typing_mode.0.assert_not_erased() { + TypingMode::Coherence + | TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } + | TypingMode::PostBorrowckAnalysis { .. } => {} + TypingMode::PostAnalysis | TypingMode::Codegen => return self, + } - // No need to reveal opaques with the new solver enabled, - // since we have lazy norm. - let param_env = if tcx.next_trait_solver_globally() { - param_env - } else { - match typing_mode.0.assert_not_erased() { - TypingMode::Coherence - | TypingMode::Analysis { .. } - | TypingMode::Borrowck { .. } - | TypingMode::PostBorrowckAnalysis { .. } => {} - TypingMode::PostAnalysis | TypingMode::Codegen => return self, - } + let param_env = param_env.with_normalized(tcx); + TypingEnv::new(param_env, TypingMode::PostAnalysis) + } - ParamEnv::new(tcx.reveal_opaque_types_in_bounds(param_env.caller_bounds())) - }; - TypingEnv { typing_mode: TypingModeEqWrapper(TypingMode::PostAnalysis), param_env } + /// Modify the `typing_mode` to `PostAnalysis` or `Codegen` and eagerly reveal all opaque types + /// in the `param_env`. + pub fn with_codegen_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> { + let TypingEnv { typing_mode, param_env } = self; + match typing_mode.0.assert_not_erased() { + TypingMode::Coherence + | TypingMode::Analysis { .. } + | TypingMode::Borrowck { .. } + | TypingMode::PostBorrowckAnalysis { .. } + | TypingMode::PostAnalysis => {} + TypingMode::Codegen => return self, + } + + let param_env = param_env.with_normalized(tcx); + TypingEnv::new(param_env, TypingMode::Codegen) } /// Combine this typing environment with the given `value` to be used by diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 0c6e1b83c9535..60d656aeb86b4 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -100,10 +100,8 @@ impl<'tcx> ConstToPat<'tcx> { // // FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself // instead of having this logic here - let typing_env = self - .tcx - .erase_and_anonymize_regions(self.typing_env) - .with_post_analysis_normalized(self.tcx); + let typing_env = + self.tcx.erase_and_anonymize_regions(self.typing_env).with_codegen_normalized(self.tcx); let uv = self.tcx.erase_and_anonymize_regions(uv); // try to resolve e.g. associated constants to their definition on an impl, and then diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 04fc732aa9d97..519541614cbf0 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -537,6 +537,18 @@ fn layout_of_uncached<'tcx>( } ty::Coroutine(def_id, args) => { + match cx.typing_env.typing_mode() { + ty::TypingMode::Codegen => {} + ty::TypingMode::Coherence + | ty::TypingMode::Analysis { .. } + | ty::TypingMode::Borrowck { .. } + | ty::TypingMode::PostBorrowckAnalysis { .. } + | ty::TypingMode::ErasedNotCoherence(_) + | ty::TypingMode::PostAnalysis => { + return Err(error(cx, LayoutError::TooGeneric(ty))); + } + } + use rustc_middle::ty::layout::PrimitiveExt as _; let info = tcx.coroutine_layout(def_id, args)?; @@ -704,7 +716,10 @@ fn layout_of_uncached<'tcx>( let maybe_unsized = def.is_struct() && def.non_enum_variant().tail_opt().is_some_and(|last_field| { - let typing_env = ty::TypingEnv::post_analysis(tcx, def.did()); + let typing_env = ty::TypingEnv::new( + tcx.param_env_normalized_for_post_analysis(def.did()), + cx.typing_env.typing_mode(), + ); !tcx.type_of(last_field.did) .instantiate_identity() .skip_norm_wip() diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 1459fb5077e65..367e2e1b97059 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -292,8 +292,8 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { } } -fn typing_env_normalized_for_post_analysis(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TypingEnv<'_> { - ty::TypingEnv::non_body_analysis(tcx, def_id).with_post_analysis_normalized(tcx) +fn param_env_normalized_for_post_analysis(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { + tcx.param_env(def_id).with_normalized(tcx) } /// Check if a function is async. @@ -405,7 +405,7 @@ pub(crate) fn provide(providers: &mut Providers) { asyncness, adt_sizedness_constraint, param_env, - typing_env_normalized_for_post_analysis, + param_env_normalized_for_post_analysis, defaultness, unsizing_params_for_adt, impl_self_is_guaranteed_unsized, diff --git a/src/tools/clippy/clippy_lints/src/large_futures.rs b/src/tools/clippy/clippy_lints/src/large_futures.rs index 382d1c1ae3ef9..56ae1d04827e8 100644 --- a/src/tools/clippy/clippy_lints/src/large_futures.rs +++ b/src/tools/clippy/clippy_lints/src/large_futures.rs @@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeFuture { && let ty = cx.typeck_results().expr_ty(arg) && let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() && implements_trait(cx, ty, future_trait_def_id, &[]) - && let Ok(layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(ty)) + && let Ok(layout) = cx.tcx.layout_of(cx.typing_env().with_codegen_normalized(cx.tcx).as_query_input(ty)) && let size = layout.layout.size() && size >= Size::from_bytes(self.future_size_threshold) {