diff options
| author | Michael Goulet <michael@errs.io> | 2025-04-22 23:31:22 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-04-23 15:09:25 +0000 |
| commit | f943f73db4791d64ff83d72986da8d6250c42933 (patch) | |
| tree | 4474dcc7ba139e0d9f70a7754c31694fcf7186ee | |
| parent | 7c1661f9457825df6e6bbf4869be3cad59b608a9 (diff) | |
| download | rust-f943f73db4791d64ff83d72986da8d6250c42933.tar.gz rust-f943f73db4791d64ff83d72986da8d6250c42933.zip | |
More
19 files changed, 189 insertions, 187 deletions
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 3b0e8560159..c4698e5cbb4 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -967,7 +967,9 @@ impl<'tcx> InferCtxt<'tcx> { pub fn can_define_opaque_ty(&self, id: impl Into<DefId>) -> bool { debug_assert!(!self.next_trait_solver()); match self.typing_mode() { - TypingMode::Analysis { defining_opaque_types, stalled_generators: _ } + TypingMode::Analysis { + defining_opaque_types_and_generators: defining_opaque_types, + } | TypingMode::Borrowck { defining_opaque_types } => { id.into().as_local().is_some_and(|def_id| defining_opaque_types.contains(&def_id)) } @@ -1262,7 +1264,7 @@ impl<'tcx> InferCtxt<'tcx> { // to handle them without proper canonicalization. This means we may cause cycle // errors and fail to reveal opaques while inside of bodies. We should rename this // function and require explicit comments on all use-sites in the future. - ty::TypingMode::Analysis { defining_opaque_types: _, stalled_generators: _ } + ty::TypingMode::Analysis { defining_opaque_types_and_generators: _ } | ty::TypingMode::Borrowck { defining_opaque_types: _ } => { TypingMode::non_body_analysis() } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 4d4096b0225..3432648feab 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -391,7 +391,7 @@ rustc_queries! { key: LocalDefId ) -> &'tcx ty::List<LocalDefId> { desc { - |tcx| "computing the opaque types defined by `{}`", + |tcx| "computing the coroutines defined within `{}`", tcx.def_path_str(key.to_def_id()) } } diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index c16adef63ea..69b6f88d72b 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -366,11 +366,11 @@ macro_rules! define_callbacks { pub type Storage<'tcx> = <$($K)* as keys::Key>::Cache<Erase<$V>>; - // Ensure that keys grow no larger than 96 bytes by accident. + // Ensure that keys grow no larger than 88 bytes by accident. // Increase this limit if necessary, but do try to keep the size low if possible #[cfg(target_pointer_width = "64")] const _: () = { - if size_of::<Key<'static>>() > 96 { + if size_of::<Key<'static>>() > 88 { panic!("{}", concat!( "the query `", stringify!($name), diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index f5872f0269e..98057a25f04 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -678,11 +678,18 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.opaque_types_defined_by(defining_anchor) } - fn stalled_generators_within(self, defining_anchor: Self::LocalDefId) -> Self::LocalDefIds { + fn opaque_types_and_generators_defined_by( + self, + defining_anchor: Self::LocalDefId, + ) -> Self::LocalDefIds { if self.next_trait_solver_globally() { - self.stalled_generators_within(defining_anchor) + self.mk_local_def_ids_from_iter( + self.opaque_types_defined_by(defining_anchor) + .iter() + .chain(self.stalled_generators_within(defining_anchor)), + ) } else { - ty::List::empty() + self.opaque_types_defined_by(defining_anchor) } } } @@ -2914,11 +2921,11 @@ impl<'tcx> TyCtxt<'tcx> { self.interners.intern_clauses(clauses) } - pub fn mk_local_def_ids(self, clauses: &[LocalDefId]) -> &'tcx List<LocalDefId> { + pub fn mk_local_def_ids(self, def_ids: &[LocalDefId]) -> &'tcx List<LocalDefId> { // FIXME consider asking the input slice to be sorted to avoid // re-interning permutations, in which case that would be asserted // here. - self.intern_local_def_ids(clauses) + self.intern_local_def_ids(def_ids) } pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 8868769906d..0695c5acdca 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -329,10 +329,7 @@ where TypingMode::Coherence | TypingMode::PostAnalysis => false, // During analysis, opaques are rigid unless they may be defined by // the current body. - TypingMode::Analysis { - defining_opaque_types: non_rigid_opaques, - stalled_generators: _, - } + TypingMode::Analysis { defining_opaque_types_and_generators: non_rigid_opaques } | TypingMode::Borrowck { defining_opaque_types: non_rigid_opaques } | TypingMode::PostBorrowckAnalysis { defined_opaque_types: non_rigid_opaques } => { !def_id.as_local().is_some_and(|def_id| non_rigid_opaques.contains(&def_id)) 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 dcfc3b3a701..ee439f1b3d0 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 @@ -33,11 +33,11 @@ where ); self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } - TypingMode::Analysis { defining_opaque_types, stalled_generators: _ } => { + TypingMode::Analysis { defining_opaque_types_and_generators } => { let Some(def_id) = opaque_ty .def_id .as_local() - .filter(|&def_id| defining_opaque_types.contains(&def_id)) + .filter(|&def_id| defining_opaque_types_and_generators.contains(&def_id)) else { self.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias); return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); 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 13132d60dfa..827853be280 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -208,20 +208,9 @@ where } } - // TODO: - if let ty::CoroutineWitness(def_id, _) = goal.predicate.self_ty().kind() { - match ecx.typing_mode() { - TypingMode::Analysis { stalled_generators, defining_opaque_types: _ } => { - if def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id)) - { - return ecx.forced_ambiguity(MaybeCause::Ambiguity); - } - } - TypingMode::Coherence - | TypingMode::PostAnalysis - | TypingMode::Borrowck { defining_opaque_types: _ } - | TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => {} - } + // We need to make sure to stall any coroutines we are inferring to avoid query cycles. + if let Some(cand) = ecx.try_stall_coroutine_witness(goal.predicate.self_ty()) { + return cand; } ecx.probe_and_evaluate_goal_for_constituent_tys( @@ -275,20 +264,9 @@ where return Err(NoSolution); } - // TODO: - if let ty::CoroutineWitness(def_id, _) = goal.predicate.self_ty().kind() { - match ecx.typing_mode() { - TypingMode::Analysis { stalled_generators, defining_opaque_types: _ } => { - if def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id)) - { - return ecx.forced_ambiguity(MaybeCause::Ambiguity); - } - } - TypingMode::Coherence - | TypingMode::PostAnalysis - | TypingMode::Borrowck { defining_opaque_types: _ } - | TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => {} - } + // We need to make sure to stall any coroutines we are inferring to avoid query cycles. + if let Some(cand) = ecx.try_stall_coroutine_witness(goal.predicate.self_ty()) { + return cand; } ecx.probe_and_evaluate_goal_for_constituent_tys( @@ -1400,4 +1378,28 @@ where let candidates = self.assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::All); self.merge_trait_candidates(goal, candidates) } + + fn try_stall_coroutine_witness( + &mut self, + self_ty: I::Ty, + ) -> Option<Result<Candidate<I>, NoSolution>> { + if let ty::CoroutineWitness(def_id, _) = self_ty.kind() { + match self.typing_mode() { + TypingMode::Analysis { + defining_opaque_types_and_generators: stalled_generators, + } => { + if def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id)) + { + return Some(self.forced_ambiguity(MaybeCause::Ambiguity)); + } + } + TypingMode::Coherence + | TypingMode::PostAnalysis + | TypingMode::Borrowck { defining_opaque_types: _ } + | TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => {} + } + } + + None + } } diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index abee5ac52c1..848d0646d00 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -14,6 +14,7 @@ use rustc_middle::ty::{ }; use rustc_next_trait_solver::solve::{GenerateProofTree, HasChanged, SolverDelegateEvalExt as _}; use rustc_span::Span; +use rustc_type_ir::data_structures::DelayedSet; use tracing::instrument; use self::derive_errors::*; @@ -217,26 +218,30 @@ where &mut self, infcx: &InferCtxt<'tcx>, ) -> PredicateObligations<'tcx> { - self.obligations.drain_pending(|obl| { - let stalled_generators = match infcx.typing_mode() { - TypingMode::Analysis { defining_opaque_types: _, stalled_generators } => { - stalled_generators - } - TypingMode::Coherence - | TypingMode::Borrowck { defining_opaque_types: _ } - | TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } - | TypingMode::PostAnalysis => return false, - }; - - if stalled_generators.is_empty() { - return false; + let stalled_generators = match infcx.typing_mode() { + TypingMode::Analysis { defining_opaque_types_and_generators } => { + defining_opaque_types_and_generators } + TypingMode::Coherence + | TypingMode::Borrowck { defining_opaque_types: _ } + | TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } + | TypingMode::PostAnalysis => return Default::default(), + }; + + if stalled_generators.is_empty() { + return Default::default(); + } + self.obligations.drain_pending(|obl| { infcx.probe(|_| { infcx .visit_proof_tree( obl.as_goal(), - &mut StalledOnCoroutines { stalled_generators, span: obl.cause.span }, + &mut StalledOnCoroutines { + stalled_generators, + span: obl.cause.span, + cache: Default::default(), + }, ) .is_break() }) @@ -244,10 +249,18 @@ where } } +/// Detect if a goal is stalled on a coroutine that is owned by the current typeck root. +/// +/// This function can (erroneously) fail to detect a predicate, i.e. it doesn't need to +/// be complete. However, this will lead to ambiguity errors, so we want to make it +/// accurate. +/// +/// This function can be also return false positives, which will lead to poor diagnostics +/// so we want to keep this visitor *precise* too. struct StalledOnCoroutines<'tcx> { stalled_generators: &'tcx ty::List<LocalDefId>, span: Span, - // TODO: Cache + cache: DelayedSet<Ty<'tcx>>, } impl<'tcx> inspect::ProofTreeVisitor<'tcx> for StalledOnCoroutines<'tcx> { @@ -272,6 +285,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for StalledOnCoroutines<'tcx> { type Result = ControlFlow<()>; fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { + if !self.cache.insert(ty) { + return ControlFlow::Continue(()); + } + if let ty::CoroutineWitness(def_id, _) = *ty.kind() && def_id.as_local().is_some_and(|def_id| self.stalled_generators.contains(&def_id)) { diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 65ab14ae07c..5f1e63ab225 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -1,6 +1,5 @@ use std::assert_matches::assert_matches; use std::fmt::Debug; -use std::marker::PhantomData; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::infer::InferCtxt; @@ -60,7 +59,8 @@ where /// entered before passing `value` to the function. This is currently needed for /// `normalize_erasing_regions`, which skips binders as it walks through a type. /// -/// TODO: doc +/// This returns a set of stalled obligations if the typing mode of the underlying infcx +/// has any stalled coroutine def ids. pub fn deeply_normalize_with_skipped_universes_and_ambiguous_goals<'tcx, T, E>( at: At<'_, 'tcx>, value: T, @@ -72,16 +72,10 @@ where { let fulfill_cx = FulfillmentCtxt::new(at.infcx); let mut folder = - NormalizationFolder { at, fulfill_cx, depth: 0, universes, _errors: PhantomData }; + NormalizationFolder { at, fulfill_cx, depth: 0, universes, stalled_goals: vec![] }; let value = value.try_fold_with(&mut folder)?; - let goals = folder - .fulfill_cx - .drain_stalled_obligations_for_coroutines(at.infcx) - .into_iter() - .map(|obl| obl.as_goal()) - .collect(); let errors = folder.fulfill_cx.select_all_or_error(at.infcx); - if errors.is_empty() { Ok((value, goals)) } else { Err(errors) } + if errors.is_empty() { Ok((value, folder.stalled_goals)) } else { Err(errors) } } struct NormalizationFolder<'me, 'tcx, E> { @@ -89,7 +83,7 @@ struct NormalizationFolder<'me, 'tcx, E> { fulfill_cx: FulfillmentCtxt<'tcx, E>, depth: usize, universes: Vec<Option<UniverseIndex>>, - _errors: PhantomData<E>, + stalled_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>, } impl<'tcx, E> NormalizationFolder<'_, 'tcx, E> @@ -130,10 +124,7 @@ where ); self.fulfill_cx.register_predicate_obligation(infcx, obligation); - let errors = self.fulfill_cx.select_where_possible(infcx); - if !errors.is_empty() { - return Err(errors); - } + self.select_all_and_stall_coroutine_predicates()?; // Alias is guaranteed to be fully structurally resolved, // so we can super fold here. @@ -184,6 +175,27 @@ where self.depth -= 1; Ok(result) } + + fn select_all_and_stall_coroutine_predicates(&mut self) -> Result<(), Vec<E>> { + let errors = self.fulfill_cx.select_where_possible(self.at.infcx); + if !errors.is_empty() { + return Err(errors); + } + + self.stalled_goals.extend( + self.fulfill_cx + .drain_stalled_obligations_for_coroutines(self.at.infcx) + .into_iter() + .map(|obl| obl.as_goal()), + ); + + let errors = self.fulfill_cx.collect_remaining_errors(self.at.infcx); + if !errors.is_empty() { + return Err(errors); + } + + Ok(()) + } } impl<'tcx, E> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx, E> diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 5255b57c791..c7ce13c8014 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1498,7 +1498,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // However, if we disqualify *all* goals from being cached, perf suffers. // This is likely fixed by better caching in general in the new solver. // See: <https://github.com/rust-lang/rust/issues/132064>. - TypingMode::Analysis { defining_opaque_types, stalled_generators: _ } + TypingMode::Analysis { + defining_opaque_types_and_generators: defining_opaque_types, + } | TypingMode::Borrowck { defining_opaque_types } => { defining_opaque_types.is_empty() || !pred.has_opaque_types() } diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 35cc6f39856..57051e0df55 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -32,6 +32,7 @@ mod needs_drop; mod opaque_types; mod representability; pub mod sig_types; +mod stalled_generators; mod structural_match; mod ty; @@ -50,4 +51,5 @@ pub fn provide(providers: &mut Providers) { ty::provide(providers); instance::provide(providers); structural_match::provide(providers); + stalled_generators::provide(providers); } diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index b6e19b9901c..cd730aeeea9 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -1,7 +1,6 @@ use rustc_data_structures::fx::FxHashSet; -use rustc_hir as hir; use rustc_hir::def::DefKind; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit; use rustc_hir::intravisit::Visitor; use rustc_middle::query::Providers; @@ -356,51 +355,6 @@ fn opaque_types_defined_by<'tcx>( tcx.mk_local_def_ids(&collector.opaques) } -// TODO: Move this out of `opaque_types` -fn stalled_generators_within<'tcx>( - tcx: TyCtxt<'tcx>, - item: LocalDefId, -) -> &'tcx ty::List<LocalDefId> { - if !tcx.next_trait_solver_globally() { - return ty::List::empty(); - } - - let body = tcx.hir_body_owned_by(item); - let mut collector = - StalledGeneratorVisitor { tcx, root_def_id: item.to_def_id(), stalled_coroutines: vec![] }; - collector.visit_body(body); - tcx.mk_local_def_ids(&collector.stalled_coroutines) -} - -struct StalledGeneratorVisitor<'tcx> { - tcx: TyCtxt<'tcx>, - root_def_id: DefId, - stalled_coroutines: Vec<LocalDefId>, -} - -impl<'tcx> Visitor<'tcx> for StalledGeneratorVisitor<'tcx> { - fn visit_nested_body(&mut self, id: hir::BodyId) { - if self.tcx.typeck_root_def_id(self.tcx.hir_body_owner_def_id(id).to_def_id()) - == self.root_def_id - { - let body = self.tcx.hir_body(id); - self.visit_body(body); - } - } - - fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { - if let hir::ExprKind::Closure(&hir::Closure { - def_id, - kind: hir::ClosureKind::Coroutine(_), - .. - }) = ex.kind - { - self.stalled_coroutines.push(def_id); - } - intravisit::walk_expr(self, ex); - } -} - pub(super) fn provide(providers: &mut Providers) { - *providers = Providers { opaque_types_defined_by, stalled_generators_within, ..*providers }; + *providers = Providers { opaque_types_defined_by, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/stalled_generators.rs b/compiler/rustc_ty_utils/src/stalled_generators.rs new file mode 100644 index 00000000000..8b45e8b0f6f --- /dev/null +++ b/compiler/rustc_ty_utils/src/stalled_generators.rs @@ -0,0 +1,54 @@ +use rustc_hir as hir; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::intravisit; +use rustc_hir::intravisit::Visitor; +use rustc_middle::query::Providers; +use rustc_middle::ty::{self, TyCtxt}; + +fn stalled_generators_within<'tcx>( + tcx: TyCtxt<'tcx>, + item: LocalDefId, +) -> &'tcx ty::List<LocalDefId> { + if !tcx.next_trait_solver_globally() { + return ty::List::empty(); + } + + let body = tcx.hir_body_owned_by(item); + let mut collector = + StalledGeneratorVisitor { tcx, root_def_id: item.to_def_id(), stalled_coroutines: vec![] }; + collector.visit_body(body); + tcx.mk_local_def_ids(&collector.stalled_coroutines) +} + +struct StalledGeneratorVisitor<'tcx> { + tcx: TyCtxt<'tcx>, + root_def_id: DefId, + stalled_coroutines: Vec<LocalDefId>, +} + +impl<'tcx> Visitor<'tcx> for StalledGeneratorVisitor<'tcx> { + fn visit_nested_body(&mut self, id: hir::BodyId) { + if self.tcx.typeck_root_def_id(self.tcx.hir_body_owner_def_id(id).to_def_id()) + == self.root_def_id + { + let body = self.tcx.hir_body(id); + self.visit_body(body); + } + } + + fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { + if let hir::ExprKind::Closure(&hir::Closure { + def_id, + kind: hir::ClosureKind::Coroutine(_), + .. + }) = ex.kind + { + self.stalled_coroutines.push(def_id); + } + intravisit::walk_expr(self, ex); + } +} + +pub(super) fn provide(providers: &mut Providers) { + *providers = Providers { stalled_generators_within, ..*providers }; +} diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index 3570de064cb..8fa56c35999 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -65,7 +65,7 @@ pub enum TypingMode<I: Interner> { /// let x: <() as Assoc>::Output = true; /// } /// ``` - Analysis { defining_opaque_types: I::LocalDefIds, stalled_generators: I::LocalDefIds }, + Analysis { defining_opaque_types_and_generators: I::LocalDefIds }, /// The behavior during MIR borrowck is identical to `TypingMode::Analysis` /// except that the initial value for opaque types is the type computed during /// HIR typeck with unique unconstrained region inference variables. @@ -94,25 +94,24 @@ pub enum TypingMode<I: Interner> { impl<I: Interner> TypingMode<I> { /// Analysis outside of a body does not define any opaque types. pub fn non_body_analysis() -> TypingMode<I> { - TypingMode::Analysis { - defining_opaque_types: Default::default(), - stalled_generators: Default::default(), - } + TypingMode::Analysis { defining_opaque_types_and_generators: Default::default() } } pub fn typeck_for_body(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> { TypingMode::Analysis { - defining_opaque_types: cx.opaque_types_defined_by(body_def_id), - stalled_generators: cx.stalled_generators_within(body_def_id), + defining_opaque_types_and_generators: cx + .opaque_types_and_generators_defined_by(body_def_id), } } /// While typechecking a body, we need to be able to define the opaque /// types defined by that body. + /// + /// FIXME: This will be removed because it's generally not correct to define + /// opaques outside of HIR typeck. pub fn analysis_in_body(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> { TypingMode::Analysis { - defining_opaque_types: cx.opaque_types_defined_by(body_def_id), - stalled_generators: Default::default(), + defining_opaque_types_and_generators: cx.opaque_types_defined_by(body_def_id), } } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index afd7b88c256..ab38556589e 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -332,7 +332,10 @@ pub trait Interner: fn opaque_types_defined_by(self, defining_anchor: Self::LocalDefId) -> Self::LocalDefIds; - fn stalled_generators_within(self, defining_anchor: Self::LocalDefId) -> Self::LocalDefIds; + fn opaque_types_and_generators_defined_by( + self, + defining_anchor: Self::LocalDefId, + ) -> Self::LocalDefIds; } /// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter` diff --git a/tests/ui/async-await/async-closures/is-not-fn.next.stderr b/tests/ui/async-await/async-closures/is-not-fn.next.stderr index 0fab1c15f27..970970a9151 100644 --- a/tests/ui/async-await/async-closures/is-not-fn.next.stderr +++ b/tests/ui/async-await/async-closures/is-not-fn.next.stderr @@ -1,13 +1,11 @@ -error[E0271]: expected `{async closure@is-not-fn.rs:8:14}` to return `()`, but it returns `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25}` +error[E0271]: type mismatch resolving `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25} == ()` --> $DIR/is-not-fn.rs:8:14 | LL | needs_fn(async || {}); - | -------- ^^^^^^^^^^^ expected `()`, found `async` closure body + | -------- ^^^^^^^^^^^ types differ | | | required by a bound introduced by this call | - = note: expected unit type `()` - found `async` closure body `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25}` note: required by a bound in `needs_fn` --> $DIR/is-not-fn.rs:7:25 | diff --git a/tests/ui/async-await/async-closures/is-not-fn.rs b/tests/ui/async-await/async-closures/is-not-fn.rs index e5ab4742dab..c09ccb3fc2b 100644 --- a/tests/ui/async-await/async-closures/is-not-fn.rs +++ b/tests/ui/async-await/async-closures/is-not-fn.rs @@ -6,5 +6,6 @@ fn main() { fn needs_fn(x: impl FnOnce()) {} needs_fn(async || {}); - //~^ ERROR expected `{async closure@is-not-fn.rs:8:14}` to return `()` + //[current]~^ ERROR expected `{async closure@is-not-fn.rs:8:14}` to return `()` + //[next]~^^ ERROR type mismatch resolving `{async closure body@$DIR/is-not-fn.rs:8:23: 8:25} == ()` } diff --git a/tests/ui/coroutine/clone-rpit.next.stderr b/tests/ui/coroutine/clone-rpit.next.stderr deleted file mode 100644 index 213e9e908f5..00000000000 --- a/tests/ui/coroutine/clone-rpit.next.stderr +++ /dev/null @@ -1,47 +0,0 @@ -error[E0391]: cycle detected when type-checking `foo` - --> $DIR/clone-rpit.rs:13:1 - | -LL | pub fn foo<'a, 'b>() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: ...which requires coroutine witness types for `foo::{closure#0}`... - --> $DIR/clone-rpit.rs:15:5 - | -LL | move |_: ()| { - | ^^^^^^^^^^^^ -note: ...which requires promoting constants in MIR for `foo::{closure#0}`... - --> $DIR/clone-rpit.rs:15:5 - | -LL | move |_: ()| { - | ^^^^^^^^^^^^ -note: ...which requires checking if `foo::{closure#0}` contains FFI-unwind calls... - --> $DIR/clone-rpit.rs:15:5 - | -LL | move |_: ()| { - | ^^^^^^^^^^^^ -note: ...which requires building MIR for `foo::{closure#0}`... - --> $DIR/clone-rpit.rs:15:5 - | -LL | move |_: ()| { - | ^^^^^^^^^^^^ -note: ...which requires match-checking `foo::{closure#0}`... - --> $DIR/clone-rpit.rs:15:5 - | -LL | move |_: ()| { - | ^^^^^^^^^^^^ -note: ...which requires type-checking `foo::{closure#0}`... - --> $DIR/clone-rpit.rs:15:5 - | -LL | move |_: ()| { - | ^^^^^^^^^^^^ - = note: ...which again requires type-checking `foo`, completing the cycle -note: cycle used when match-checking `foo` - --> $DIR/clone-rpit.rs:13:1 - | -LL | pub fn foo<'a, 'b>() -> impl Clone { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = 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 - -For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/coroutine/clone-rpit.rs b/tests/ui/coroutine/clone-rpit.rs index 66569b4f427..3882564639b 100644 --- a/tests/ui/coroutine/clone-rpit.rs +++ b/tests/ui/coroutine/clone-rpit.rs @@ -1,8 +1,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[current] check-pass -//@[next] known-bug: trait-system-refactor-initiative#82 +//@ check-pass #![feature(coroutines, coroutine_trait, coroutine_clone)] |
