diff options
| author | Michael Goulet <michael@errs.io> | 2025-05-29 12:34:50 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-07-17 17:42:28 +0000 |
| commit | 216cdb7b22b637cef75b7225c642cb7587192643 (patch) | |
| tree | b6394c00088fafc75e45f3907d6553b1b4835858 /compiler | |
| parent | 72bc11d14688599fbcaedf2be9175aa374e1c0d9 (diff) | |
| download | rust-216cdb7b22b637cef75b7225c642cb7587192643.tar.gz rust-216cdb7b22b637cef75b7225c642cb7587192643.zip | |
Eagerly unify coroutine witness in old solver
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_hir_typeck/src/closure.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/infer.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/fulfill.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs | 33 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/mod.rs | 15 |
8 files changed, 51 insertions, 36 deletions
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 459c0498d50..a413f805873 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -161,16 +161,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Resume type defaults to `()` if the coroutine has no argument. let resume_ty = liberated_sig.inputs().get(0).copied().unwrap_or(tcx.types.unit); - // In the new solver, we can just instantiate this eagerly - // with the witness. This will ensure that goals that don't need - // to stall on interior types will get processed eagerly. - let interior = if self.next_trait_solver() { - Ty::new_coroutine_witness(tcx, expr_def_id.to_def_id(), parent_args) - } else { - self.next_ty_var(expr_span) - }; - - self.deferred_coroutine_interiors.borrow_mut().push((expr_def_id, interior)); + let interior = Ty::new_coroutine_witness(tcx, expr_def_id.to_def_id(), parent_args); // Coroutines that come from coroutine closures have not yet determined // their kind ty, so make a fresh infer var which will be constrained diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs index 26be5fc6d19..9f4ab8ca5d4 100644 --- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs +++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs @@ -63,8 +63,6 @@ pub(crate) struct TypeckRootCtxt<'tcx> { pub(super) deferred_asm_checks: RefCell<Vec<(&'tcx hir::InlineAsm<'tcx>, HirId)>>, - pub(super) deferred_coroutine_interiors: RefCell<Vec<(LocalDefId, Ty<'tcx>)>>, - pub(super) deferred_repeat_expr_checks: RefCell<Vec<(&'tcx hir::Expr<'tcx>, Ty<'tcx>, ty::Const<'tcx>)>>, @@ -103,7 +101,6 @@ impl<'tcx> TypeckRootCtxt<'tcx> { deferred_cast_checks: RefCell::new(Vec::new()), deferred_transmute_checks: RefCell::new(Vec::new()), deferred_asm_checks: RefCell::new(Vec::new()), - deferred_coroutine_interiors: RefCell::new(Vec::new()), deferred_repeat_expr_checks: RefCell::new(Vec::new()), diverging_type_vars: RefCell::new(Default::default()), infer_var_info: RefCell::new(Default::default()), diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 915b062417f..684d13e147e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -714,17 +714,13 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self, defining_anchor: Self::LocalDefId, ) -> Self::LocalDefIds { - if self.next_trait_solver_globally() { - let coroutines_defined_by = self - .nested_bodies_within(defining_anchor) - .iter() - .filter(|def_id| self.is_coroutine(def_id.to_def_id())); - self.mk_local_def_ids_from_iter( - self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by), - ) - } else { - self.opaque_types_defined_by(defining_anchor) - } + let coroutines_defined_by = self + .nested_bodies_within(defining_anchor) + .iter() + .filter(|def_id| self.is_coroutine(def_id.to_def_id())); + self.mk_local_def_ids_from_iter( + self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by), + ) } } diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 0118321befb..7c6b7b14ecb 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -33,8 +33,8 @@ impl<'tcx> InferCtxt<'tcx> { let ty = self.resolve_vars_if_possible(ty); // FIXME(#132279): This should be removed as it causes us to incorrectly - // handle opaques in their defining scope. - if !self.next_trait_solver() && !(param_env, ty).has_infer() { + // handle opaques in their defining scope, and stalled coroutines. + if !self.next_trait_solver() && !(param_env, ty).has_infer() && !ty.has_coroutines() { return self.tcx.type_is_copy_modulo_regions(self.typing_env(param_env), ty); } diff --git a/compiler/rustc_trait_selection/src/solve.rs b/compiler/rustc_trait_selection/src/solve.rs index 5a5d16167d2..f58961683a9 100644 --- a/compiler/rustc_trait_selection/src/solve.rs +++ b/compiler/rustc_trait_selection/src/solve.rs @@ -7,7 +7,7 @@ mod normalize; mod select; pub(crate) use delegate::SolverDelegate; -pub use fulfill::{FulfillmentCtxt, NextSolverError}; +pub use fulfill::{FulfillmentCtxt, NextSolverError, StalledOnCoroutines}; pub(crate) use normalize::deeply_normalize_for_diagnostics; pub use normalize::{ deeply_normalize, deeply_normalize_with_skipped_universes, diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index c6c68b1c401..e35f89358e9 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -14,6 +14,7 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ self, Binder, Const, GenericArgsRef, TypeVisitable, TypeVisitableExt, TypingMode, + may_use_unstable_feature, }; use rustc_span::DUMMY_SP; use thin_vec::{ThinVec, thin_vec}; diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index cc188a280aa..2c7089507a8 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -842,6 +842,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } + ty::CoroutineWitness(def_id, _) => { + if self.should_stall_coroutine_witness(def_id) { + candidates.ambiguous = true; + } else { + candidates.vec.push(AutoImplCandidate); + } + } + ty::Bool | ty::Char | ty::Int(_) @@ -861,7 +869,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Coroutine(..) | ty::Never | ty::Tuple(_) - | ty::CoroutineWitness(..) | ty::UnsafeBinder(_) => { // Only consider auto impls of unsafe traits when there are // no unsafe fields. @@ -1119,12 +1126,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match *self_ty.kind() { // These impls are built-in because we cannot express sufficiently // generic impls in libcore. - ty::FnDef(..) - | ty::FnPtr(..) - | ty::Error(_) - | ty::Tuple(..) - | ty::CoroutineWitness(..) - | ty::Pat(..) => { + ty::FnDef(..) | ty::FnPtr(..) | ty::Error(_) | ty::Tuple(..) | ty::Pat(..) => { candidates.vec.push(BuiltinCandidate); } @@ -1192,6 +1194,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } + ty::CoroutineWitness(coroutine_def_id, _) => { + if self.should_stall_coroutine_witness(coroutine_def_id) { + candidates.ambiguous = true; + } else { + candidates.vec.push(SizedCandidate); + } + } + // Fallback to whatever user-defined impls or param-env clauses exist in this case. ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {} @@ -1229,7 +1239,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Char | ty::Ref(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) | ty::Array(..) | ty::Closure(..) | ty::CoroutineClosure(..) @@ -1238,6 +1247,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidates.vec.push(SizedCandidate); } + ty::CoroutineWitness(coroutine_def_id, _) => { + if self.should_stall_coroutine_witness(coroutine_def_id) { + candidates.ambiguous = true; + } else { + candidates.vec.push(SizedCandidate); + } + } + // Conditionally `Sized`. ty::Tuple(..) | ty::Pat(..) | ty::Adt(..) | ty::UnsafeBinder(_) => { candidates.vec.push(SizedCandidate); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 10bcf861d35..d0b88d2fb18 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1512,7 +1512,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { defining_opaque_types_and_generators: defining_opaque_types, } | TypingMode::Borrowck { defining_opaque_types } => { - defining_opaque_types.is_empty() || !pred.has_opaque_types() + defining_opaque_types.is_empty() + || (!pred.has_opaque_types() && !pred.has_coroutines()) } // The hidden types of `defined_opaque_types` is not local to the current // inference context, so we can freely move this to the global cache. @@ -2811,6 +2812,18 @@ impl<'tcx> SelectionContext<'_, 'tcx> { obligations } + + fn should_stall_coroutine_witness(&self, def_id: DefId) -> bool { + match self.infcx.typing_mode() { + TypingMode::Analysis { defining_opaque_types_and_generators: stalled_generators } => { + def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id)) + } + TypingMode::Coherence + | TypingMode::PostAnalysis + | TypingMode::Borrowck { defining_opaque_types: _ } + | TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => false, + } + } } impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> { |
