Skip to main content

rustc_next_trait_solver/solve/project_goals/
mod.rs

1mod anon_const;
2mod free_alias;
3mod inherent;
4mod opaque_types;
5
6use rustc_type_ir::search_graph::LowerAvailableDepth;
7use rustc_type_ir::solve::QueryResultOrRerunNonErased;
8use rustc_type_ir::{self as ty, Interner, ProjectionClause};
9use tracing::{instrument, trace};
10
11use crate::delegate::SolverDelegate;
12use crate::solve::{
13    Certainty, EvalCtxt, Goal, GoalEvaluation, GoalSource, NestedNormalizationGoals,
14};
15
16impl<D, I> EvalCtxt<'_, D>
17where
18    D: SolverDelegate<Interner = I>,
19    I: Interner,
20{
21    {}
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_projection_goal",
                                "rustc_next_trait_solver::solve::project_goals",
                                ::tracing::Level::TRACE,
                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs"),
                                ::tracing_core::__macro_support::Option::Some(21u32),
                                ::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::project_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();
}
#[allow(clippy :: redundant_closure_call)]
let x =
    (move ||
                {

                    #[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;
                    }
                    {
                        match goal.predicate.projection_term.kind {
                            ty::AliasTermKind::ProjectionTy { .. } |
                                ty::AliasTermKind::ProjectionConst { .. } => {
                                self.normalize_associated_term(goal)
                            }
                            ty::AliasTermKind::InherentTy { .. } |
                                ty::AliasTermKind::InherentConstSelf { .. } |
                                ty::AliasTermKind::InherentConstImpl { .. } => {
                                self.normalize_inherent_associated_term(goal)
                            }
                            ty::AliasTermKind::OpaqueTy { .. } =>
                                self.normalize_opaque_type(goal),
                            ty::AliasTermKind::FreeTy { .. } |
                                ty::AliasTermKind::FreeConst { .. } => {
                                self.normalize_free_alias(goal).map_err(Into::into)
                            }
                            ty::AliasTermKind::AnonConst { .. } => {
                                self.normalize_anon_const(goal).map_err(Into::into)
                            }
                        }
                    }
                })();
{
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs:21",
                        "rustc_next_trait_solver::solve::project_goals",
                        ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(21u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::project_goals"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("return")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("return");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};
x;#[instrument(level = "trace", skip(self), ret)]
22    pub(super) fn compute_projection_goal(
23        &mut self,
24        goal: Goal<I, ProjectionClause<I>>,
25    ) -> QueryResultOrRerunNonErased<I> {
26        match goal.predicate.projection_term.kind {
27            ty::AliasTermKind::ProjectionTy { .. } | ty::AliasTermKind::ProjectionConst { .. } => {
28                self.normalize_associated_term(goal)
29            }
30            ty::AliasTermKind::InherentTy { .. }
31            | ty::AliasTermKind::InherentConstSelf { .. }
32            | ty::AliasTermKind::InherentConstImpl { .. } => {
33                self.normalize_inherent_associated_term(goal)
34            }
35            ty::AliasTermKind::OpaqueTy { .. } => self.normalize_opaque_type(goal),
36            ty::AliasTermKind::FreeTy { .. } | ty::AliasTermKind::FreeConst { .. } => {
37                self.normalize_free_alias(goal).map_err(Into::into)
38            }
39            ty::AliasTermKind::AnonConst { .. } => {
40                self.normalize_anon_const(goal).map_err(Into::into)
41            }
42        }
43    }
44
45    fn normalize_associated_term(
46        &mut self,
47        goal: Goal<I, ProjectionClause<I>>,
48    ) -> QueryResultOrRerunNonErased<I> {
49        let ty::ProjectionClause { projection_term: alias, term } = goal.predicate;
50        let unconstrained_term = self.next_term_infer_of_alias_kind(alias);
51        let normalizes_to =
52            goal.with(self.cx(), ty::NormalizesTo { alias, term: unconstrained_term });
53
54        // We don't want candidate selection when normalizing associated terms to be impacted by
55        // the expected term. Normalization should behave like a function of just the alias being
56        // normalized. Because of this, we use an internal `NormalizesTo` goal for which the
57        // expected term is always fully unconstrained and then equate that to the actual expected
58        // term afterwards.
59        //
60        // But this results in weaker type inference if there's a nested where-clause when
61        // normalizing which we can actually make progress on based on the expected term. To avoid
62        // this, we return ambiguous nested goals for `NormalizesTo` to this context and register
63        // them as if they were this `Projection` goal's own nested goals. (See #122687)
64        //
65        // After registering those goals, we equate the original expected term to the normalization
66        // result. Although equating them can add inference constraint to the alias term, we don't
67        // reevaluate this special `NormalizesTo` goal. But that's fine because as those inference
68        // constraints should cause the caller to reevaluate the current `Projection `goal, which
69        // will then also reevaluate the `NormalizesTo` goal.
70        let (
71            NestedNormalizationGoals(nested_goals),
72            GoalEvaluation { goal: _, certainty, stalled_on: _, has_changed: _ },
73        ) = self.evaluate_goal_raw(
74            GoalSource::TypeRelating,
75            normalizes_to,
76            // We don't lower thr available depth for this `NormalizesTo` goal, as evaluating
77            // it is an extra step only exists in the new solver that behaves like a function
78            // call rather than an independent nested goal evaluation. So, decreasing the
79            // available depth may end up regressions which hit the recursion limits for crates
80            // compiled well with the old solver.
81            LowerAvailableDepth::No,
82        )?;
83
84        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs:84",
                        "rustc_next_trait_solver::solve::project_goals",
                        ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs"),
                        ::tracing_core::__macro_support::Option::Some(84u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::project_goals"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("nested_goals")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("nested_goals");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&nested_goals)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};trace!(?nested_goals);
85
86        // Add a `make_canonical_response` probe step so that we treat this as
87        // a candidate, even if `try_evaluate_added_goals` bails due to an error.
88        // It's `Certainty::AMBIGUOUS` because this candidate is not "finished",
89        // since equating the normalized terms will lead to additional constraints.
90        self.inspect.make_canonical_response(Certainty::AMBIGUOUS);
91
92        self.eq(goal.param_env, term, unconstrained_term)?;
93
94        // Add the nested goals from normalization to our own nested goals.
95        for (s, g) in nested_goals {
96            self.add_goal(s, g)?;
97        }
98
99        self.evaluate_added_goals_and_make_canonical_response(certainty)
100    }
101}