Skip to main content

rustc_next_trait_solver/solve/
effect_goals.rs

1//! Dealing with host effect goals, i.e. enforcing the constness in
2//! `T: const Trait` or `T: [const] Trait`.
3
4use rustc_type_ir::fast_reject::DeepRejectCtxt;
5use rustc_type_ir::inherent::*;
6use rustc_type_ir::lang_items::SolverTraitLangItem;
7use rustc_type_ir::solve::inspect::ProbeKind;
8use rustc_type_ir::solve::{
9    AliasBoundKind, NoSolutionOrRerunNonErased, QueryResultOrRerunNonErased, RerunNonErased,
10    SizedTraitKind,
11};
12use rustc_type_ir::{self as ty, Interner, Unnormalized, elaborate};
13use tracing::instrument;
14
15use super::assembly::{Candidate, structural_traits};
16use crate::delegate::SolverDelegate;
17use crate::solve::{
18    BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, NoSolution, assembly,
19};
20
21impl<D, I> assembly::GoalKind<D> for ty::HostEffectClause<I>
22where
23    D: SolverDelegate<Interner = I>,
24    I: Interner,
25{
26    fn self_ty(self) -> I::Ty {
27        self.self_ty()
28    }
29
30    fn trait_ref(self, _: I) -> ty::TraitRef<I> {
31        self.trait_ref
32    }
33
34    fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
35        self.with_replaced_self_ty(cx, self_ty)
36    }
37
38    fn trait_def_id(self, _: I) -> I::TraitId {
39        self.def_id()
40    }
41
42    fn fast_reject_assumption(
43        ecx: &mut EvalCtxt<'_, D>,
44        goal: Goal<I, Self>,
45        assumption: I::Clause,
46    ) -> Result<(), NoSolution> {
47        if let Some(host_clause) = assumption.as_host_effect_clause()
48            && host_clause.def_id() == goal.predicate.def_id()
49            && host_clause.constness().satisfies(goal.predicate.constness)
50            && DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
51                goal.predicate.trait_ref.args,
52                host_clause.skip_binder().trait_ref.args,
53            )
54        {
55            Ok(())
56        } else {
57            Err(NoSolution)
58        }
59    }
60
61    fn match_assumption(
62        ecx: &mut EvalCtxt<'_, D>,
63        goal: Goal<I, Self>,
64        assumption: I::Clause,
65        then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResultOrRerunNonErased<I>,
66    ) -> QueryResultOrRerunNonErased<I> {
67        let host_clause = assumption.as_host_effect_clause().unwrap();
68
69        let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause);
70        ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;
71
72        then(ecx)
73    }
74
75    /// Register additional assumptions for aliases corresponding to `[const]` item bounds.
76    ///
77    /// Unlike item bounds, they are not simply implied by the well-formedness of the alias.
78    /// Instead, they only hold if the const conditions on the alias also hold. This is why
79    /// we also register the const conditions of the alias after matching the goal against
80    /// the assumption.
81    fn consider_additional_alias_assumptions(
82        ecx: &mut EvalCtxt<'_, D>,
83        goal: Goal<I, Self>,
84        alias_ty: ty::AliasTy<I>,
85    ) -> Vec<Candidate<I>> {
86        let cx = ecx.cx();
87        let mut candidates = ::alloc::vec::Vec::new()vec![];
88
89        let def_id = match alias_ty.kind {
90            ty::AliasTyKind::Projection { def_id } => def_id.into(),
91            ty::AliasTyKind::Inherent { def_id } => def_id.into(),
92            ty::AliasTyKind::Opaque { def_id } => def_id.into(),
93            ty::AliasTyKind::Free { def_id } => def_id.into(),
94        };
95
96        if !ecx.cx().alias_has_const_conditions(def_id) {
97            return ::alloc::vec::Vec::new()vec![];
98        }
99
100        for clause in elaborate::elaborate(
101            cx,
102            cx.explicit_implied_const_bounds(def_id).iter_instantiated(cx, alias_ty.args).map(
103                |trait_ref| {
104                    trait_ref.to_host_effect_clause(cx, goal.predicate.constness).skip_norm_wip()
105                },
106            ),
107        ) {
108            candidates.extend(Self::probe_and_match_goal_against_assumption(
109                ecx,
110                CandidateSource::AliasBound(AliasBoundKind::SelfBounds),
111                goal,
112                clause,
113                |ecx| {
114                    // Const conditions must hold for the implied const bound to hold.
115                    ecx.add_goals(
116                        GoalSource::AliasBoundConstCondition,
117                        cx.const_conditions(def_id).iter_instantiated(cx, alias_ty.args).map(
118                            |trait_ref| {
119                                goal.with(
120                                    cx,
121                                    trait_ref
122                                        .to_host_effect_clause(cx, goal.predicate.constness)
123                                        .skip_norm_wip(),
124                                )
125                            },
126                        ),
127                    )?;
128                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
129                },
130            ));
131        }
132
133        candidates
134    }
135
136    fn consider_impl_candidate(
137        ecx: &mut EvalCtxt<'_, D>,
138        goal: Goal<I, Self>,
139        goal_trait_ref: ty::TraitRef<I>,
140        impl_def_id: I::ImplId,
141        then: impl FnOnce(&mut EvalCtxt<'_, D>, Certainty) -> QueryResultOrRerunNonErased<I>,
142    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
143        let cx = ecx.cx();
144
145        let impl_trait_ref = cx.impl_trait_ref(impl_def_id);
146        if !DeepRejectCtxt::relate_rigid_infer(ecx.cx())
147            .args_may_unify(goal_trait_ref.args, impl_trait_ref.skip_binder().args)
148        {
149            return Err(NoSolution.into());
150        }
151
152        // For every `default impl`, there's always a non-default `impl` that will *also* apply.
153        // There's no reason to register a candidate for this impl, since it is *not* proof that
154        // the trait goal holds.
155        if cx.impl_is_default(impl_def_id) {
156            return Err(NoSolution.into());
157        }
158
159        let impl_polarity = cx.impl_polarity(impl_def_id);
160        let certainty = match impl_polarity {
161            ty::ImplPolarity::Negative => return Err(NoSolution.into()),
162            ty::ImplPolarity::Reservation => {
163                if ecx.typing_mode().is_coherence() {
164                    Certainty::AMBIGUOUS
165                } else {
166                    return Err(NoSolution.into());
167                }
168            }
169            ty::ImplPolarity::Positive => Certainty::Yes,
170        };
171
172        if !cx.impl_is_const(impl_def_id) {
173            return Err(NoSolution.into());
174        }
175
176        ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
177            let impl_args = ecx.fresh_args_for_item(impl_def_id.into());
178            ecx.record_impl_args(impl_args);
179            let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args).skip_norm_wip();
180
181            ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
182            let where_clause_bounds = cx
183                .clauses_of(impl_def_id.into())
184                .iter_instantiated(cx, impl_args)
185                .map(Unnormalized::skip_norm_wip)
186                .map(|clause| goal.with(cx, clause));
187            ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds)?;
188
189            // For this impl to be `const`, we need to check its `[const]` bounds too.
190            let const_conditions = cx
191                .const_conditions(impl_def_id.into())
192                .iter_instantiated(cx, impl_args)
193                .map(|bound_trait_ref| {
194                    goal.with(
195                        cx,
196                        bound_trait_ref
197                            .to_host_effect_clause(cx, goal.predicate.constness)
198                            .skip_norm_wip(),
199                    )
200                });
201            ecx.add_goals(GoalSource::ImplWhereBound, const_conditions)?;
202
203            then(ecx, certainty)
204        })
205    }
206
207    fn consider_error_guaranteed_candidate(
208        ecx: &mut EvalCtxt<'_, D>,
209        _goal: Goal<I, Self>,
210        _guar: I::ErrorGuaranteed,
211    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
212        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
213            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
214    }
215
216    fn consider_auto_trait_candidate(
217        ecx: &mut EvalCtxt<'_, D>,
218        _goal: Goal<I, Self>,
219    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
220        ecx.cx().delay_bug("auto traits are never const");
221        Err(NoSolution.into())
222    }
223
224    fn consider_trait_alias_candidate(
225        ecx: &mut EvalCtxt<'_, D>,
226        goal: Goal<I, Self>,
227    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
228        let cx = ecx.cx();
229
230        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
231            let where_clause_bounds = cx
232                .clauses_of(goal.predicate.def_id().into())
233                .iter_instantiated(cx, goal.predicate.trait_ref.args)
234                .map(Unnormalized::skip_norm_wip)
235                .map(|c| goal.with(cx, c));
236
237            let const_conditions = cx
238                .const_conditions(goal.predicate.def_id().into())
239                .iter_instantiated(cx, goal.predicate.trait_ref.args)
240                .map(|bound_trait_ref| {
241                    goal.with(
242                        cx,
243                        bound_trait_ref
244                            .to_host_effect_clause(cx, goal.predicate.constness)
245                            .skip_norm_wip(),
246                    )
247                });
248            // While you could think of trait aliases to have a single builtin impl
249            // which uses its implied trait bounds as where-clauses, using
250            // `GoalSource::ImplWhereClause` here would be incorrect, as we also
251            // impl them, which means we're "stepping out of the impl constructor"
252            // again. To handle this, we treat these cycles as ambiguous for now.
253            ecx.add_goals(GoalSource::Misc, where_clause_bounds)?;
254            ecx.add_goals(GoalSource::Misc, const_conditions)?;
255            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
256        })
257    }
258
259    fn consider_builtin_sizedness_candidates(
260        _ecx: &mut EvalCtxt<'_, D>,
261        _goal: Goal<I, Self>,
262        _sizedness: SizedTraitKind,
263    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
264        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("Sized/MetaSized is never const")));
}unreachable!("Sized/MetaSized is never const")
265    }
266
267    fn consider_builtin_copy_clone_candidate(
268        ecx: &mut EvalCtxt<'_, D>,
269        goal: Goal<I, Self>,
270    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
271        let cx = ecx.cx();
272
273        let self_ty = goal.predicate.self_ty();
274        let constituent_tys =
275            structural_traits::instantiate_constituent_tys_for_copy_clone_trait(ecx, self_ty)?;
276
277        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
278            ecx.enter_forall_with_assumptions(constituent_tys, goal.param_env, |ecx, tys| {
279                ecx.add_goals(
280                    GoalSource::ImplWhereBound,
281                    tys.into_iter().map(|ty| {
282                        goal.with(
283                            cx,
284                            ty::ClauseKind::HostEffect(
285                                goal.predicate.with_replaced_self_ty(cx, ty),
286                            ),
287                        )
288                    }),
289                )
290            })?;
291
292            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
293        })
294    }
295
296    fn consider_builtin_fn_ptr_trait_candidate(
297        _ecx: &mut EvalCtxt<'_, D>,
298        _goal: Goal<I, Self>,
299    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
300        {
    ::core::panicking::panic_fmt(format_args!("not implemented: {0}",
            format_args!("Fn* are not yet const")));
}unimplemented!("Fn* are not yet const")
301    }
302
303    x;#[instrument(level = "trace", skip_all, ret)]
304    fn consider_builtin_fn_trait_candidates(
305        ecx: &mut EvalCtxt<'_, D>,
306        goal: Goal<I, Self>,
307        _kind: rustc_type_ir::ClosureKind,
308    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
309        let cx = ecx.cx();
310
311        let self_ty = goal.predicate.self_ty();
312        let (inputs_and_output, def_id, args) =
313            structural_traits::extract_fn_def_from_const_callable(cx, self_ty)?;
314        let (inputs, output) = ecx.instantiate_binder_with_infer(inputs_and_output);
315
316        // A built-in `Fn` impl only holds if the output is sized.
317        // (FIXME: technically we only need to check this if the type is a fn ptr...)
318        let output_is_sized_pred =
319            ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output]);
320        let requirements = cx
321            .const_conditions(def_id)
322            .iter_instantiated(cx, args)
323            .map(|trait_ref| {
324                (
325                    GoalSource::ImplWhereBound,
326                    goal.with(
327                        cx,
328                        trait_ref
329                            .to_host_effect_clause(cx, goal.predicate.constness)
330                            .skip_norm_wip(),
331                    ),
332                )
333            })
334            .chain([(GoalSource::ImplWhereBound, goal.with(cx, output_is_sized_pred))]);
335
336        let pred = ty::Binder::dummy(ty::TraitRef::new(
337            cx,
338            goal.predicate.def_id(),
339            [goal.predicate.self_ty(), inputs],
340        ))
341        .to_host_effect_clause(cx, goal.predicate.constness);
342
343        Self::probe_and_consider_implied_clause(
344            ecx,
345            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
346            goal,
347            pred,
348            requirements,
349        )
350        .map_err(Into::into)
351    }
352
353    fn consider_builtin_async_fn_trait_candidates(
354        _ecx: &mut EvalCtxt<'_, D>,
355        _goal: Goal<I, Self>,
356        _kind: rustc_type_ir::ClosureKind,
357    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
358        {
    ::core::panicking::panic_fmt(format_args!("not implemented: {0}",
            format_args!("AsyncFn* are not yet const")));
}unimplemented!("AsyncFn* are not yet const")
359    }
360
361    fn consider_builtin_async_fn_kind_helper_candidate(
362        _ecx: &mut EvalCtxt<'_, D>,
363        _goal: Goal<I, Self>,
364    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
365        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("AsyncFnKindHelper is not const")));
}unreachable!("AsyncFnKindHelper is not const")
366    }
367
368    fn consider_builtin_tuple_candidate(
369        _ecx: &mut EvalCtxt<'_, D>,
370        _goal: Goal<I, Self>,
371    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
372        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("Tuple trait is not const")));
}unreachable!("Tuple trait is not const")
373    }
374
375    fn consider_builtin_pointee_candidate(
376        _ecx: &mut EvalCtxt<'_, D>,
377        _goal: Goal<I, Self>,
378    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
379        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("Pointee is not const")));
}unreachable!("Pointee is not const")
380    }
381
382    fn consider_builtin_future_candidate(
383        _ecx: &mut EvalCtxt<'_, D>,
384        _goal: Goal<I, Self>,
385    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
386        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("Future is not const")));
}unreachable!("Future is not const")
387    }
388
389    fn consider_builtin_iterator_candidate(
390        _ecx: &mut EvalCtxt<'_, D>,
391        _goal: Goal<I, Self>,
392    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
393        Err(NoSolutionOrRerunNonErased::NoSolution(NoSolution))
394    }
395
396    fn consider_builtin_fused_iterator_candidate(
397        _ecx: &mut EvalCtxt<'_, D>,
398        _goal: Goal<I, Self>,
399    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
400        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("FusedIterator is not const")));
}unreachable!("FusedIterator is not const")
401    }
402
403    fn consider_builtin_async_iterator_candidate(
404        _ecx: &mut EvalCtxt<'_, D>,
405        _goal: Goal<I, Self>,
406    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
407        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("AsyncIterator is not const")));
}unreachable!("AsyncIterator is not const")
408    }
409
410    fn consider_builtin_coroutine_candidate(
411        _ecx: &mut EvalCtxt<'_, D>,
412        _goal: Goal<I, Self>,
413    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
414        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("Coroutine is not const")));
}unreachable!("Coroutine is not const")
415    }
416
417    fn consider_builtin_discriminant_kind_candidate(
418        _ecx: &mut EvalCtxt<'_, D>,
419        _goal: Goal<I, Self>,
420    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
421        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("DiscriminantKind is not const")));
}unreachable!("DiscriminantKind is not const")
422    }
423
424    fn consider_builtin_destruct_candidate(
425        ecx: &mut EvalCtxt<'_, D>,
426        goal: Goal<I, Self>,
427    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
428        let cx = ecx.cx();
429
430        let self_ty = goal.predicate.self_ty();
431        let const_conditions = structural_traits::const_conditions_for_destruct(cx, self_ty)?;
432
433        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
434            ecx.add_goals(
435                GoalSource::AliasBoundConstCondition,
436                const_conditions.into_iter().map(|trait_ref| {
437                    goal.with(
438                        cx,
439                        ty::Binder::dummy(trait_ref)
440                            .to_host_effect_clause(cx, goal.predicate.constness),
441                    )
442                }),
443            )?;
444            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
445        })
446    }
447
448    fn consider_builtin_transmute_candidate(
449        _ecx: &mut EvalCtxt<'_, D>,
450        _goal: Goal<I, Self>,
451    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
452        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("TransmuteFrom is not const")));
}unreachable!("TransmuteFrom is not const")
453    }
454
455    fn consider_builtin_bikeshed_guaranteed_no_drop_candidate(
456        _ecx: &mut EvalCtxt<'_, D>,
457        _goal: Goal<I, Self>,
458    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
459        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("BikeshedGuaranteedNoDrop is not const")));
};unreachable!("BikeshedGuaranteedNoDrop is not const");
460    }
461
462    fn consider_builtin_try_as_dyn_candidate(
463        _ecx: &mut EvalCtxt<'_, D>,
464        goal: Goal<I, Self>,
465    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
466        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("`TryAsDynCompat` is not const: {0:?}", goal)));
}unreachable!("`TryAsDynCompat` is not const: {:?}", goal)
467    }
468
469    fn consider_structural_builtin_unsize_candidates(
470        _ecx: &mut EvalCtxt<'_, D>,
471        _goal: Goal<I, Self>,
472    ) -> Result<Vec<Candidate<I>>, RerunNonErased> {
473        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("Unsize is not const")));
}unreachable!("Unsize is not const")
474    }
475
476    fn consider_builtin_field_candidate(
477        _ecx: &mut EvalCtxt<'_, D>,
478        _goal: Goal<<D as SolverDelegate>::Interner, Self>,
479    ) -> Result<Candidate<<D as SolverDelegate>::Interner>, NoSolutionOrRerunNonErased> {
480        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("Field is not const")));
}unreachable!("Field is not const")
481    }
482}
483
484impl<D, I> EvalCtxt<'_, D>
485where
486    D: SolverDelegate<Interner = I>,
487    I: Interner,
488{
489    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("compute_host_effect_goal",
                                    "rustc_next_trait_solver::solve::effect_goals",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_next_trait_solver/src/solve/effect_goals.rs"),
                                    ::tracing_core::__macro_support::Option::Some(489u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::effect_goals"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("goal")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("goal");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&goal)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: QueryResultOrRerunNonErased<I> =
                loop {};
            return __tracing_attr_fake_return;
        }
        {
            let (_, proven_via) =
                self.probe(|_|
                                ProbeKind::ShadowedEnvProbing).enter(|ecx|
                            {
                                let trait_goal: Goal<I, ty::TraitClause<I>> =
                                    goal.with(ecx.cx(), goal.predicate.trait_ref);
                                ecx.compute_trait_goal(trait_goal).map_err(Into::into)
                            })?;
            self.assemble_and_merge_candidates(proven_via, goal, |_ecx| None,
                |_ecx| Err(NoSolution.into()))
        }
    }
}#[instrument(level = "trace", skip(self))]
490    pub(super) fn compute_host_effect_goal(
491        &mut self,
492        goal: Goal<I, ty::HostEffectClause<I>>,
493    ) -> QueryResultOrRerunNonErased<I> {
494        let (_, proven_via) = self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| {
495            let trait_goal: Goal<I, ty::TraitClause<I>> =
496                goal.with(ecx.cx(), goal.predicate.trait_ref);
497            ecx.compute_trait_goal(trait_goal).map_err(Into::into)
498        })?;
499        self.assemble_and_merge_candidates(
500            proven_via,
501            goal,
502            |_ecx| None,
503            |_ecx| Err(NoSolution.into()),
504        )
505    }
506}