diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index dcf415e720fb5..9447ea06fddb4 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -471,6 +471,10 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> { { self.resolve_vars_if_possible(value) } + + fn probe(&self, probe: impl FnOnce() -> T) -> T { + self.probe(|_| probe()) + } } /// See the `error_reporting` module for more details. diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index 9c18366887beb..72cdfb5e57b19 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -1,21 +1,21 @@ //! Code shared by trait and projection goals for candidate assembly. +use derivative::Derivative; use rustc_hir::def_id::DefId; use rustc_hir::LangItem; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::query::NoSolution; use rustc_middle::bug; use rustc_middle::traits::solve::inspect::ProbeKind; -use rustc_middle::traits::solve::{ - CandidateSource, CanonicalResponse, Certainty, Goal, MaybeCause, QueryResult, -}; +use rustc_middle::traits::solve::{Certainty, Goal, MaybeCause, QueryResult}; use rustc_middle::traits::BuiltinImplSource; use rustc_middle::ty::fast_reject::{SimplifiedType, TreatParams}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{fast_reject, TypeFoldable}; use rustc_middle::ty::{TypeVisitableExt, Upcast}; use rustc_span::{ErrorGuaranteed, DUMMY_SP}; -use std::fmt::Debug; +use rustc_type_ir::solve::{CandidateSource, CanonicalResponse}; +use rustc_type_ir::Interner; use crate::solve::GoalSource; use crate::solve::{EvalCtxt, SolverMode}; @@ -26,10 +26,11 @@ pub(super) mod structural_traits; /// /// It consists of both the `source`, which describes how that goal would be proven, /// and the `result` when using the given `source`. -#[derive(Debug, Clone)] -pub(super) struct Candidate<'tcx> { - pub(super) source: CandidateSource<'tcx>, - pub(super) result: CanonicalResponse<'tcx>, +#[derive(Derivative)] +#[derivative(Debug(bound = ""), Clone(bound = ""))] +pub(super) struct Candidate { + pub(super) source: CandidateSource, + pub(super) result: CanonicalResponse, } /// Methods used to assemble candidates for either trait or projection goals. @@ -50,22 +51,22 @@ pub(super) trait GoalKind<'tcx>: /// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]). fn probe_and_match_goal_against_assumption( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, - source: CandidateSource<'tcx>, + source: CandidateSource>, goal: Goal<'tcx, Self>, assumption: ty::Clause<'tcx>, then: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>) -> QueryResult<'tcx>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// Consider a clause, which consists of a "assumption" and some "requirements", /// to satisfy a goal. If the requirements hold, then attempt to satisfy our /// goal by equating it with the assumption. fn probe_and_consider_implied_clause( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, - parent_source: CandidateSource<'tcx>, + parent_source: CandidateSource>, goal: Goal<'tcx, Self>, assumption: ty::Clause<'tcx>, requirements: impl IntoIterator>)>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { Self::probe_and_match_goal_against_assumption(ecx, parent_source, goal, assumption, |ecx| { for (nested_source, goal) in requirements { ecx.add_goal(nested_source, goal); @@ -79,10 +80,10 @@ pub(super) trait GoalKind<'tcx>: /// since they're not implied by the well-formedness of the object type. fn probe_and_consider_object_bound_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, - source: CandidateSource<'tcx>, + source: CandidateSource>, goal: Goal<'tcx, Self>, assumption: ty::Clause<'tcx>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| { let tcx = ecx.interner(); let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else { @@ -105,7 +106,7 @@ pub(super) trait GoalKind<'tcx>: ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, impl_def_id: DefId, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// If the predicate contained an error, we want to avoid emitting unnecessary trait /// errors but still want to emit errors for other trait goals. We have some special @@ -116,7 +117,7 @@ pub(super) trait GoalKind<'tcx>: fn consider_error_guaranteed_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, guar: ErrorGuaranteed, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// A type implements an `auto trait` if its components do as well. /// @@ -125,13 +126,13 @@ pub(super) trait GoalKind<'tcx>: fn consider_auto_trait_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// A trait alias holds if the RHS traits and `where` clauses hold. fn consider_trait_alias_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// A type is `Sized` if its tail component is `Sized`. /// @@ -140,7 +141,7 @@ pub(super) trait GoalKind<'tcx>: fn consider_builtin_sized_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// A type is `Copy` or `Clone` if its components are `Copy` or `Clone`. /// @@ -149,20 +150,20 @@ pub(super) trait GoalKind<'tcx>: fn consider_builtin_copy_clone_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// A type is `PointerLike` if we can compute its layout, and that layout /// matches the layout of `usize`. fn consider_builtin_pointer_like_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// A type is a `FnPtr` if it is of `FnPtr` type. fn consider_builtin_fn_ptr_trait_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// A callable type (a closure, fn def, or fn ptr) is known to implement the `Fn` /// family of traits where `A` is given by the signature of the type. @@ -170,7 +171,7 @@ pub(super) trait GoalKind<'tcx>: ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, kind: ty::ClosureKind, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// An async closure is known to implement the `AsyncFn` family of traits /// where `A` is given by the signature of the type. @@ -178,7 +179,7 @@ pub(super) trait GoalKind<'tcx>: ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, kind: ty::ClosureKind, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// Compute the built-in logic of the `AsyncFnKindHelper` helper trait, which /// is used internally to delay computation for async closures until after @@ -186,13 +187,13 @@ pub(super) trait GoalKind<'tcx>: fn consider_builtin_async_fn_kind_helper_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// `Tuple` is implemented if the `Self` type is a tuple. fn consider_builtin_tuple_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// `Pointee` is always implemented. /// @@ -202,7 +203,7 @@ pub(super) trait GoalKind<'tcx>: fn consider_builtin_pointee_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// A coroutine (that comes from an `async` desugaring) is known to implement /// `Future`, where `O` is given by the coroutine's return type @@ -210,7 +211,7 @@ pub(super) trait GoalKind<'tcx>: fn consider_builtin_future_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// A coroutine (that comes from a `gen` desugaring) is known to implement /// `Iterator`, where `O` is given by the generator's yield type @@ -218,19 +219,19 @@ pub(super) trait GoalKind<'tcx>: fn consider_builtin_iterator_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// A coroutine (that comes from a `gen` desugaring) is known to implement /// `FusedIterator` fn consider_builtin_fused_iterator_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; fn consider_builtin_async_iterator_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// A coroutine (that doesn't come from an `async` or `gen` desugaring) is known to /// implement `Coroutine`, given the resume, yield, @@ -238,27 +239,27 @@ pub(super) trait GoalKind<'tcx>: fn consider_builtin_coroutine_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; fn consider_builtin_discriminant_kind_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; fn consider_builtin_async_destruct_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; fn consider_builtin_destruct_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; fn consider_builtin_transmute_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution>; + ) -> Result>, NoSolution>; /// Consider (possibly several) candidates to upcast or unsize a type to another /// type, excluding the coercion of a sized type into a `dyn Trait`. @@ -270,14 +271,14 @@ pub(super) trait GoalKind<'tcx>: fn consider_structural_builtin_unsize_candidates( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Vec>; + ) -> Vec>>; } impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { pub(super) fn assemble_and_evaluate_candidates>( &mut self, goal: Goal<'tcx, G>, - ) -> Vec> { + ) -> Vec>> { let Ok(normalized_self_ty) = self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty()) else { @@ -324,7 +325,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { pub(super) fn forced_ambiguity( &mut self, cause: MaybeCause, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { // This may fail if `try_evaluate_added_goals` overflows because it // fails to reach a fixpoint but ends up getting an error after // running for some additional step. @@ -340,7 +341,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { fn assemble_non_blanket_impl_candidates>( &mut self, goal: Goal<'tcx, G>, - candidates: &mut Vec>, + candidates: &mut Vec>>, ) { let tcx = self.interner(); let self_ty = goal.predicate.self_ty(); @@ -456,7 +457,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { fn assemble_blanket_impl_candidates>( &mut self, goal: Goal<'tcx, G>, - candidates: &mut Vec>, + candidates: &mut Vec>>, ) { let tcx = self.interner(); let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx)); @@ -479,7 +480,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { fn assemble_builtin_impl_candidates>( &mut self, goal: Goal<'tcx, G>, - candidates: &mut Vec>, + candidates: &mut Vec>>, ) { let tcx = self.interner(); let trait_def_id = goal.predicate.trait_def_id(tcx); @@ -552,7 +553,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { fn assemble_param_env_candidates>( &mut self, goal: Goal<'tcx, G>, - candidates: &mut Vec>, + candidates: &mut Vec>>, ) { for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() { candidates.extend(G::probe_and_consider_implied_clause( @@ -569,7 +570,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { fn assemble_alias_bound_candidates>( &mut self, goal: Goal<'tcx, G>, - candidates: &mut Vec>, + candidates: &mut Vec>>, ) { let () = self.probe(|_| ProbeKind::NormalizedSelfTyAssembly).enter(|ecx| { ecx.assemble_alias_bound_candidates_recur(goal.predicate.self_ty(), goal, candidates); @@ -589,7 +590,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { &mut self, self_ty: Ty<'tcx>, goal: Goal<'tcx, G>, - candidates: &mut Vec>, + candidates: &mut Vec>>, ) { let (kind, alias_ty) = match *self_ty.kind() { ty::Bool @@ -673,7 +674,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { fn assemble_object_bound_candidates>( &mut self, goal: Goal<'tcx, G>, - candidates: &mut Vec>, + candidates: &mut Vec>>, ) { let tcx = self.interner(); if !tcx.trait_def(goal.predicate.trait_def_id(tcx)).implement_via_object { @@ -764,7 +765,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { fn assemble_coherence_unknowable_candidates>( &mut self, goal: Goal<'tcx, G>, - candidates: &mut Vec>, + candidates: &mut Vec>>, ) { let tcx = self.interner(); @@ -793,7 +794,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { fn discard_impls_shadowed_by_env>( &mut self, goal: Goal<'tcx, G>, - candidates: &mut Vec>, + candidates: &mut Vec>>, ) { let tcx = self.interner(); let trait_goal: Goal<'tcx, ty::TraitPredicate<'tcx>> = @@ -841,7 +842,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { #[instrument(level = "debug", skip(self), ret)] pub(super) fn merge_candidates( &mut self, - candidates: Vec>, + candidates: Vec>>, ) -> QueryResult<'tcx> { // First try merging all candidates. This is complete and fully sound. let responses = candidates.iter().map(|c| c.result).collect::>(); diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs index 1748c9be9275e..ad6fdd2707de2 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs @@ -1,27 +1,29 @@ use crate::solve::assembly::Candidate; use super::EvalCtxt; -use rustc_infer::infer::InferCtxt; -use rustc_infer::traits::BuiltinImplSource; -use rustc_middle::traits::query::NoSolution; -use rustc_middle::traits::solve::{inspect, CandidateSource, QueryResult}; -use rustc_middle::ty::TyCtxt; +use rustc_next_trait_solver::solve::{ + inspect, BuiltinImplSource, CandidateSource, NoSolution, QueryResult, +}; +use rustc_type_ir::{InferCtxtLike, Interner}; use std::marker::PhantomData; -pub(in crate::solve) struct ProbeCtxt<'me, 'a, 'tcx, F, T> { - ecx: &'me mut EvalCtxt<'a, InferCtxt<'tcx>>, +pub(in crate::solve) struct ProbeCtxt<'me, 'a, Infcx, I, F, T> +where + Infcx: InferCtxtLike, + I: Interner, +{ + ecx: &'me mut EvalCtxt<'a, Infcx, I>, probe_kind: F, _result: PhantomData, } -impl<'tcx, F, T> ProbeCtxt<'_, '_, 'tcx, F, T> +impl ProbeCtxt<'_, '_, Infcx, I, F, T> where - F: FnOnce(&T) -> inspect::ProbeKind>, + F: FnOnce(&T) -> inspect::ProbeKind, + Infcx: InferCtxtLike, + I: Interner, { - pub(in crate::solve) fn enter( - self, - f: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>) -> T, - ) -> T { + pub(in crate::solve) fn enter(self, f: impl FnOnce(&mut EvalCtxt<'_, Infcx>) -> T) -> T { let ProbeCtxt { ecx: outer_ecx, probe_kind, _result } = self; let infcx = outer_ecx.infcx; @@ -38,7 +40,7 @@ where tainted: outer_ecx.tainted, inspect: outer_ecx.inspect.take_and_enter_probe(), }; - let r = nested_ecx.infcx.probe(|_| { + let r = nested_ecx.infcx.probe(|| { let r = f(&mut nested_ecx); nested_ecx.inspect.probe_final_state(infcx, max_input_universe); r @@ -52,30 +54,43 @@ where } } -pub(in crate::solve) struct TraitProbeCtxt<'me, 'a, 'tcx, F> { - cx: ProbeCtxt<'me, 'a, 'tcx, F, QueryResult<'tcx>>, - source: CandidateSource<'tcx>, +pub(in crate::solve) struct TraitProbeCtxt<'me, 'a, Infcx, I, F> +where + Infcx: InferCtxtLike, + I: Interner, +{ + cx: ProbeCtxt<'me, 'a, Infcx, I, F, QueryResult>, + source: CandidateSource, } -impl<'tcx, F> TraitProbeCtxt<'_, '_, 'tcx, F> +impl TraitProbeCtxt<'_, '_, Infcx, I, F> where - F: FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind>, + Infcx: InferCtxtLike, + I: Interner, + F: FnOnce(&QueryResult) -> inspect::ProbeKind, { #[instrument(level = "debug", skip_all, fields(source = ?self.source))] pub(in crate::solve) fn enter( self, - f: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>) -> QueryResult<'tcx>, - ) -> Result, NoSolution> { + f: impl FnOnce(&mut EvalCtxt<'_, Infcx>) -> QueryResult, + ) -> Result, NoSolution> { self.cx.enter(|ecx| f(ecx)).map(|result| Candidate { source: self.source, result }) } } -impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { +impl<'a, Infcx, I> EvalCtxt<'a, Infcx, I> +where + Infcx: InferCtxtLike, + I: Interner, +{ /// `probe_kind` is only called when proof tree building is enabled so it can be /// as expensive as necessary to output the desired information. - pub(in crate::solve) fn probe(&mut self, probe_kind: F) -> ProbeCtxt<'_, 'a, 'tcx, F, T> + pub(in crate::solve) fn probe( + &mut self, + probe_kind: F, + ) -> ProbeCtxt<'_, 'a, Infcx, I, F, T> where - F: FnOnce(&T) -> inspect::ProbeKind>, + F: FnOnce(&T) -> inspect::ProbeKind, { ProbeCtxt { ecx: self, probe_kind, _result: PhantomData } } @@ -83,28 +98,20 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { pub(in crate::solve) fn probe_builtin_trait_candidate( &mut self, source: BuiltinImplSource, - ) -> TraitProbeCtxt< - '_, - 'a, - 'tcx, - impl FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind>, - > { + ) -> TraitProbeCtxt<'_, 'a, Infcx, I, impl FnOnce(&QueryResult) -> inspect::ProbeKind> + { self.probe_trait_candidate(CandidateSource::BuiltinImpl(source)) } pub(in crate::solve) fn probe_trait_candidate( &mut self, - source: CandidateSource<'tcx>, - ) -> TraitProbeCtxt< - '_, - 'a, - 'tcx, - impl FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind>, - > { + source: CandidateSource, + ) -> TraitProbeCtxt<'_, 'a, Infcx, I, impl FnOnce(&QueryResult) -> inspect::ProbeKind> + { TraitProbeCtxt { cx: ProbeCtxt { ecx: self, - probe_kind: move |result: &QueryResult<'tcx>| inspect::ProbeKind::TraitCandidate { + probe_kind: move |result: &QueryResult| inspect::ProbeKind::TraitCandidate { source, result: *result, }, diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index c3e4057f5e096..60a15392e0bee 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -103,7 +103,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { goal: Goal<'tcx, Self>, assumption: ty::Clause<'tcx>, then: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>) -> QueryResult<'tcx>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if let Some(projection_pred) = assumption.as_projection_clause() { if projection_pred.projection_def_id() == goal.predicate.def_id() { let tcx = ecx.interner(); @@ -140,7 +140,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, NormalizesTo<'tcx>>, impl_def_id: DefId, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let tcx = ecx.interner(); let goal_trait_ref = goal.predicate.alias.trait_ref(tcx); @@ -267,14 +267,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_error_guaranteed_candidate( _ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, _guar: ErrorGuaranteed, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { Err(NoSolution) } fn consider_auto_trait_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { ecx.interner().dcx().span_delayed_bug( ecx.interner().def_span(goal.predicate.def_id()), "associated types not allowed on auto traits", @@ -285,35 +285,35 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_trait_alias_candidate( _ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { bug!("trait aliases do not have associated types: {:?}", goal); } fn consider_builtin_sized_candidate( _ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { bug!("`Sized` does not have an associated type: {:?}", goal); } fn consider_builtin_copy_clone_candidate( _ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { bug!("`Copy`/`Clone` does not have an associated type: {:?}", goal); } fn consider_builtin_pointer_like_candidate( _ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { bug!("`PointerLike` does not have an associated type: {:?}", goal); } fn consider_builtin_fn_ptr_trait_candidate( _ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { bug!("`FnPtr` does not have an associated type: {:?}", goal); } @@ -321,7 +321,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, goal_kind: ty::ClosureKind, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let tcx = ecx.interner(); let tupled_inputs_and_output = match structural_traits::extract_tupled_inputs_and_output_from_callable( @@ -364,7 +364,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, goal_kind: ty::ClosureKind, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let tcx = ecx.interner(); let env_region = match goal_kind { @@ -454,7 +454,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_builtin_async_fn_kind_helper_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let [ closure_fn_kind_ty, goal_kind_ty, @@ -501,14 +501,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_builtin_tuple_candidate( _ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { bug!("`Tuple` does not have an associated type: {:?}", goal); } fn consider_builtin_pointee_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let tcx = ecx.interner(); let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); assert_eq!(metadata_def_id, goal.predicate.def_id()); @@ -590,7 +590,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_builtin_future_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let self_ty = goal.predicate.self_ty(); let ty::Coroutine(def_id, args) = *self_ty.kind() else { return Err(NoSolution); @@ -626,7 +626,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_builtin_iterator_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let self_ty = goal.predicate.self_ty(); let ty::Coroutine(def_id, args) = *self_ty.kind() else { return Err(NoSolution); @@ -662,14 +662,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_builtin_fused_iterator_candidate( _ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { bug!("`FusedIterator` does not have an associated type: {:?}", goal); } fn consider_builtin_async_iterator_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let self_ty = goal.predicate.self_ty(); let ty::Coroutine(def_id, args) = *self_ty.kind() else { return Err(NoSolution); @@ -705,7 +705,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_builtin_coroutine_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let self_ty = goal.predicate.self_ty(); let ty::Coroutine(def_id, args) = *self_ty.kind() else { return Err(NoSolution); @@ -752,14 +752,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_structural_builtin_unsize_candidates( _ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Vec> { + ) -> Vec>> { bug!("`Unsize` does not have an associated type: {:?}", goal); } fn consider_builtin_discriminant_kind_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let self_ty = goal.predicate.self_ty(); let discriminant_ty = match *self_ty.kind() { ty::Bool @@ -811,7 +811,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_builtin_async_destruct_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let self_ty = goal.predicate.self_ty(); let async_destructor_ty = match *self_ty.kind() { ty::Bool @@ -864,14 +864,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { fn consider_builtin_destruct_candidate( _ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { bug!("`Destruct` does not have an associated type: {:?}", goal); } fn consider_builtin_transmute_candidate( _ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { bug!("`BikeshedIntrinsicFrom` does not have an associated type: {:?}", goal) } } diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index f631a21a82c20..3fdc11ade5f39 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -39,7 +39,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, TraitPredicate<'tcx>>, impl_def_id: DefId, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let tcx = ecx.interner(); let impl_trait_header = tcx.impl_trait_header(impl_def_id).unwrap(); @@ -94,7 +94,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_error_guaranteed_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, _guar: ErrorGuaranteed, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { // FIXME: don't need to enter a probe here. ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) @@ -106,7 +106,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { goal: Goal<'tcx, Self>, assumption: ty::Clause<'tcx>, then: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>) -> QueryResult<'tcx>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if let Some(trait_clause) = assumption.as_trait_clause() { if trait_clause.def_id() == goal.predicate.def_id() && trait_clause.polarity() == goal.predicate.polarity @@ -131,7 +131,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_auto_trait_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -174,7 +174,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_trait_alias_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -197,7 +197,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_sized_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -212,7 +212,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_copy_clone_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -227,7 +227,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_pointer_like_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -257,7 +257,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_fn_ptr_trait_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let self_ty = goal.predicate.self_ty(); match goal.predicate.polarity { // impl FnPtr for FnPtr {} @@ -289,7 +289,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, goal_kind: ty::ClosureKind, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -330,7 +330,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, goal_kind: ty::ClosureKind, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -380,7 +380,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_async_fn_kind_helper_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let [closure_fn_kind_ty, goal_kind_ty] = **goal.predicate.trait_ref.args else { bug!(); }; @@ -407,7 +407,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_tuple_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -423,7 +423,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_pointee_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -435,7 +435,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_future_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -461,7 +461,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_iterator_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -487,7 +487,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_fused_iterator_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -511,7 +511,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_async_iterator_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -537,7 +537,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_coroutine_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -569,7 +569,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_discriminant_kind_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -582,7 +582,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_async_destruct_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -595,7 +595,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_destruct_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -611,7 +611,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_transmute_candidate( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -652,7 +652,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_structural_builtin_unsize_candidates( ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, - ) -> Vec> { + ) -> Vec>> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return vec![]; } @@ -738,7 +738,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { a_region: ty::Region<'tcx>, b_data: &'tcx ty::List>, b_region: ty::Region<'tcx>, - ) -> Vec> { + ) -> Vec>> { let tcx = self.interner(); let Goal { predicate: (a_ty, _b_ty), .. } = goal; @@ -784,7 +784,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>, b_data: &'tcx ty::List>, b_region: ty::Region<'tcx>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let tcx = self.interner(); let Goal { predicate: (a_ty, _), .. } = goal; @@ -825,7 +825,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { b_data: &'tcx ty::List>, b_region: ty::Region<'tcx>, upcast_principal: Option>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let param_env = goal.param_env; // We may upcast to auto traits that are either explicitly listed in @@ -928,7 +928,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>, a_elem_ty: Ty<'tcx>, b_elem_ty: Ty<'tcx>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { self.eq(goal.param_env, a_elem_ty, b_elem_ty)?; self.probe_builtin_trait_candidate(BuiltinImplSource::Misc) .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) @@ -953,7 +953,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { def: ty::AdtDef<'tcx>, a_args: ty::GenericArgsRef<'tcx>, b_args: ty::GenericArgsRef<'tcx>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let tcx = self.interner(); let Goal { predicate: (_a_ty, b_ty), .. } = goal; @@ -1014,7 +1014,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>, a_tys: &'tcx ty::List>, b_tys: &'tcx ty::List>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { let tcx = self.interner(); let Goal { predicate: (_a_ty, b_ty), .. } = goal; @@ -1049,7 +1049,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { fn disqualify_auto_trait_candidate_due_to_possible_impl( &mut self, goal: Goal<'tcx, TraitPredicate<'tcx>>, - ) -> Option, NoSolution>> { + ) -> Option>, NoSolution>> { let self_ty = goal.predicate.self_ty(); match *self_ty.kind() { // Stall int and float vars until they are resolved to a concrete @@ -1154,7 +1154,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { &EvalCtxt<'_, InferCtxt<'tcx>>, Ty<'tcx>, ) -> Result>>, NoSolution>, - ) -> Result, NoSolution> { + ) -> Result>, NoSolution> { self.probe_trait_candidate(source).enter(|ecx| { ecx.add_goals( GoalSource::ImplWhereBound, diff --git a/compiler/rustc_type_ir/src/infcx.rs b/compiler/rustc_type_ir/src/infcx.rs index 92a717a0d9efb..4a5f34e354208 100644 --- a/compiler/rustc_type_ir/src/infcx.rs +++ b/compiler/rustc_type_ir/src/infcx.rs @@ -72,4 +72,6 @@ pub trait InferCtxtLike: Sized { fn resolve_vars_if_possible(&self, value: T) -> T where T: TypeFoldable; + + fn probe(&self, probe: impl FnOnce() -> T) -> T; }