diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 4dfbbc6c6350c..ed8081ea887f7 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -147,6 +147,14 @@ impl<'tcx> FnCtxt<'_, 'tcx> { /// foo(1.0); /// ``` fn calculate_fallback_to_f32(&self, unresolved_variables: &[Ty<'tcx>]) -> UnordSet { + // Short-circuit: if no unresolved variable is a float, no f32 fallback can apply, + // so we can skip the (potentially very expensive) work in `from_float_for_f32_root_vids`. + // Under the new solver, that function walks `visit_proof_tree` for every pending + // obligation, which is O(N × proof_tree_size) and can dominate type-checking on crates + // with many large pending obligations and no f32 involvement. + if unresolved_variables.iter().all(|ty| ty.float_vid().is_none()) { + return UnordSet::new(); + } let roots: UnordSet = self.from_float_for_f32_root_vids(); if roots.is_empty() { // Most functions have no `f32: From<{float}>` predicates, so short-circuit and return