Skip to main content

rustc_trait_selection/traits/query/type_op/
ascribe_user_type.rs

1use rustc_hir::def::DefKind;
2use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
3use rustc_infer::traits::Obligation;
4use rustc_middle::traits::query::NoSolution;
5pub use rustc_middle::traits::query::type_op::AscribeUserType;
6use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
7use rustc_middle::ty::{
8    self, ParamEnvAnd, Ty, TyCtxt, Unnormalized, UserArgs, UserSelfTy, UserTypeKind,
9};
10use rustc_span::{DUMMY_SP, Span};
11use tracing::{debug, instrument};
12
13use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse};
14use crate::traits::ObligationCtxt;
15
16impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> {
17    type QueryResponse = ();
18
19    fn try_fast_path(
20        _tcx: TyCtxt<'tcx>,
21        _key: &ParamEnvAnd<'tcx, Self>,
22    ) -> Option<Self::QueryResponse> {
23        None
24    }
25
26    fn perform_query(
27        tcx: TyCtxt<'tcx>,
28        canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>,
29    ) -> Result<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
30        tcx.type_op_ascribe_user_type(canonicalized)
31    }
32
33    fn perform_locally_with_next_solver(
34        ocx: &ObligationCtxt<'_, 'tcx>,
35        key: ParamEnvAnd<'tcx, Self>,
36        span: Span,
37    ) -> Result<Self::QueryResponse, NoSolution> {
38        type_op_ascribe_user_type_with_span(ocx, key, span)
39    }
40}
41
42/// The core of the `type_op_ascribe_user_type` query: for diagnostics purposes in NLL HRTB errors,
43/// this query can be re-run to better track the span of the obligation cause, and improve the error
44/// message. Do not call directly unless you're in that very specific context.
45pub fn type_op_ascribe_user_type_with_span<'tcx>(
46    ocx: &ObligationCtxt<'_, 'tcx>,
47    key: ParamEnvAnd<'tcx, AscribeUserType<'tcx>>,
48    span: Span,
49) -> Result<(), NoSolution> {
50    let ty::ParamEnvAnd { param_env, value: AscribeUserType { mir_ty, user_ty } } = key;
51    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs:51",
                        "rustc_trait_selection::traits::query::type_op::ascribe_user_type",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs"),
                        ::tracing_core::__macro_support::Option::Some(51u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::type_op::ascribe_user_type"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("type_op_ascribe_user_type: mir_ty={0:?} user_ty={1:?}",
                                                    mir_ty, user_ty) as &dyn Value))])
            });
    } else { ; }
};debug!("type_op_ascribe_user_type: mir_ty={:?} user_ty={:?}", mir_ty, user_ty);
52    match user_ty.kind {
53        UserTypeKind::Ty(user_ty) => relate_mir_and_user_ty(ocx, param_env, span, mir_ty, user_ty)?,
54        UserTypeKind::TypeOf(def_id, user_args) => {
55            relate_mir_and_user_args(ocx, param_env, span, mir_ty, def_id, user_args)?
56        }
57    };
58
59    // Enforce any bounds that come from impl trait in bindings.
60    ocx.register_obligations(user_ty.bounds.iter().map(|clause| {
61        Obligation::new(ocx.infcx.tcx, ObligationCause::dummy_with_span(span), param_env, clause)
62    }));
63
64    Ok(())
65}
66
67#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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("relate_mir_and_user_ty",
                                    "rustc_trait_selection::traits::query::type_op::ascribe_user_type",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs"),
                                    ::tracing_core::__macro_support::Option::Some(67u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::type_op::ascribe_user_type"),
                                    ::tracing_core::field::FieldSet::new(&["mir_ty", "user_ty"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::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};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&mir_ty)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&user_ty)
                                                            as &dyn 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: Result<(), NoSolution> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let cause = ObligationCause::dummy_with_span(span);
            ocx.register_obligation(Obligation::new(ocx.infcx.tcx,
                    cause.clone(), param_env,
                    ty::ClauseKind::WellFormed(user_ty.into())));
            let user_ty =
                ocx.normalize(&cause, param_env,
                    Unnormalized::new_wip(user_ty));
            ocx.eq(&cause, param_env, mir_ty, user_ty)?;
            Ok(())
        }
    }
}#[instrument(level = "debug", skip(ocx, param_env, span))]
68fn relate_mir_and_user_ty<'tcx>(
69    ocx: &ObligationCtxt<'_, 'tcx>,
70    param_env: ty::ParamEnv<'tcx>,
71    span: Span,
72    mir_ty: Ty<'tcx>,
73    user_ty: Ty<'tcx>,
74) -> Result<(), NoSolution> {
75    let cause = ObligationCause::dummy_with_span(span);
76    ocx.register_obligation(Obligation::new(
77        ocx.infcx.tcx,
78        cause.clone(),
79        param_env,
80        ty::ClauseKind::WellFormed(user_ty.into()),
81    ));
82
83    let user_ty = ocx.normalize(&cause, param_env, Unnormalized::new_wip(user_ty));
84    ocx.eq(&cause, param_env, mir_ty, user_ty)?;
85
86    Ok(())
87}
88
89#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::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("relate_mir_and_user_args",
                                    "rustc_trait_selection::traits::query::type_op::ascribe_user_type",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs"),
                                    ::tracing_core::__macro_support::Option::Some(89u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::type_op::ascribe_user_type"),
                                    ::tracing_core::field::FieldSet::new(&["mir_ty", "def_id",
                                                    "user_args"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::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};
                                let mut iter = meta.fields().iter();
                                meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&mir_ty)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
                                                            as &dyn Value)),
                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                    ::tracing::__macro_support::Option::Some(&::tracing::field::debug(&user_args)
                                                            as &dyn 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: Result<(), NoSolution> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let UserArgs { user_self_ty, args } = user_args;
            let tcx = ocx.infcx.tcx;
            let cause = ObligationCause::dummy_with_span(span);
            let is_inherent_assoc_const =
                #[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(def_id)
                            {
                            DefKind::AssocConst { .. } => true,
                            _ => false,
                        } &&
                        tcx.def_kind(tcx.parent(def_id)) ==
                            DefKind::Impl { of_trait: false } &&
                    tcx.is_type_const(def_id);
            let args =
                if is_inherent_assoc_const {
                    let impl_def_id = tcx.parent(def_id);
                    let impl_args =
                        ocx.infcx.fresh_args_for_item(span, impl_def_id);
                    let impl_self_ty =
                        ocx.normalize(&cause, param_env,
                            tcx.type_of(impl_def_id).instantiate(tcx, impl_args));
                    let user_self_ty =
                        ocx.normalize(&cause, param_env,
                            Unnormalized::new_wip(args[0].expect_ty()));
                    ocx.eq(&cause, param_env, impl_self_ty, user_self_ty)?;
                    let gat_args = &args[1..];
                    tcx.mk_args_from_iter(impl_args.iter().chain(gat_args.iter().copied()))
                } else { args };
            let ty = tcx.type_of(def_id).instantiate(tcx, args);
            let ty = ocx.normalize(&cause, param_env, ty);
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs:125",
                                    "rustc_trait_selection::traits::query::type_op::ascribe_user_type",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs"),
                                    ::tracing_core::__macro_support::Option::Some(125u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::type_op::ascribe_user_type"),
                                    ::tracing_core::field::FieldSet::new(&["message"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&format_args!("relate_type_and_user_type: ty of def-id is {0:?}",
                                                                ty) as &dyn Value))])
                        });
                } else { ; }
            };
            ocx.eq(&cause, param_env, mir_ty, ty)?;
            let instantiated_predicates =
                tcx.predicates_of(def_id).instantiate(tcx, args);
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs:136",
                                    "rustc_trait_selection::traits::query::type_op::ascribe_user_type",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs"),
                                    ::tracing_core::__macro_support::Option::Some(136u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::type_op::ascribe_user_type"),
                                    ::tracing_core::field::FieldSet::new(&["instantiated_predicates"],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::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};
                            let mut iter = __CALLSITE.metadata().fields().iter();
                            __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                ::tracing::__macro_support::Option::Some(&debug(&instantiated_predicates)
                                                        as &dyn Value))])
                        });
                } else { ; }
            };
            for (instantiated_predicate, predicate_span) in
                instantiated_predicates {
                let span =
                    if span == DUMMY_SP { predicate_span } else { span };
                let cause =
                    ObligationCause::new(span, CRATE_DEF_ID,
                        ObligationCauseCode::AscribeUserTypeProvePredicate(predicate_span));
                let instantiated_predicate =
                    ocx.normalize(&cause, param_env, instantiated_predicate);
                ocx.register_obligation(Obligation::new(tcx, cause, param_env,
                        instantiated_predicate));
            }
            for term in args.iter().filter_map(ty::GenericArg::as_term) {
                ocx.register_obligation(Obligation::new(tcx, cause.clone(),
                        param_env, ty::ClauseKind::WellFormed(term)));
            }
            if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
                ocx.register_obligation(Obligation::new(tcx, cause.clone(),
                        param_env, ty::ClauseKind::WellFormed(self_ty.into())));
                let self_ty =
                    ocx.normalize(&cause, param_env,
                        Unnormalized::new_wip(self_ty));
                let impl_self_ty =
                    tcx.type_of(impl_def_id).instantiate(tcx,
                            args).skip_norm_wip();
                let impl_self_ty =
                    ocx.normalize(&cause, param_env,
                        Unnormalized::new_wip(impl_self_ty));
                ocx.eq(&cause, param_env, self_ty, impl_self_ty)?;
            }
            Ok(())
        }
    }
}#[instrument(level = "debug", skip(ocx, param_env, span))]
90fn relate_mir_and_user_args<'tcx>(
91    ocx: &ObligationCtxt<'_, 'tcx>,
92    param_env: ty::ParamEnv<'tcx>,
93    span: Span,
94    mir_ty: Ty<'tcx>,
95    def_id: DefId,
96    user_args: UserArgs<'tcx>,
97) -> Result<(), NoSolution> {
98    let UserArgs { user_self_ty, args } = user_args;
99    let tcx = ocx.infcx.tcx;
100    let cause = ObligationCause::dummy_with_span(span);
101
102    // For IACs, the user args are in the format [SelfTy, GAT_args...] but type_of expects [impl_args..., GAT_args...].
103    // We need to infer the impl args by equating the impl's self type with the user-provided self type.
104    let is_inherent_assoc_const = matches!(tcx.def_kind(def_id), DefKind::AssocConst { .. })
105        && tcx.def_kind(tcx.parent(def_id)) == DefKind::Impl { of_trait: false }
106        && tcx.is_type_const(def_id);
107
108    let args = if is_inherent_assoc_const {
109        let impl_def_id = tcx.parent(def_id);
110        let impl_args = ocx.infcx.fresh_args_for_item(span, impl_def_id);
111        let impl_self_ty =
112            ocx.normalize(&cause, param_env, tcx.type_of(impl_def_id).instantiate(tcx, impl_args));
113        let user_self_ty =
114            ocx.normalize(&cause, param_env, Unnormalized::new_wip(args[0].expect_ty()));
115        ocx.eq(&cause, param_env, impl_self_ty, user_self_ty)?;
116
117        let gat_args = &args[1..];
118        tcx.mk_args_from_iter(impl_args.iter().chain(gat_args.iter().copied()))
119    } else {
120        args
121    };
122
123    let ty = tcx.type_of(def_id).instantiate(tcx, args);
124    let ty = ocx.normalize(&cause, param_env, ty);
125    debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
126
127    ocx.eq(&cause, param_env, mir_ty, ty)?;
128
129    // Prove the predicates coming along with `def_id`.
130    //
131    // Also, normalize the `instantiated_predicates`
132    // because otherwise we wind up with duplicate "type
133    // outlives" error messages.
134    let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args);
135
136    debug!(?instantiated_predicates);
137    for (instantiated_predicate, predicate_span) in instantiated_predicates {
138        let span = if span == DUMMY_SP { predicate_span } else { span };
139        let cause = ObligationCause::new(
140            span,
141            CRATE_DEF_ID,
142            ObligationCauseCode::AscribeUserTypeProvePredicate(predicate_span),
143        );
144        let instantiated_predicate = ocx.normalize(&cause, param_env, instantiated_predicate);
145
146        ocx.register_obligation(Obligation::new(tcx, cause, param_env, instantiated_predicate));
147    }
148
149    // Now prove the well-formedness of `def_id` with `args`.
150    // Note for some items, proving the WF of `ty` is not sufficient because the
151    // well-formedness of an item may depend on the WF of gneneric args not present in the
152    // item's type. Currently this is true for associated consts, e.g.:
153    // ```rust
154    // impl<T> MyTy<T> {
155    //     const CONST: () = { /* arbitrary code that depends on T being WF */ };
156    // }
157    // ```
158    for term in args.iter().filter_map(ty::GenericArg::as_term) {
159        ocx.register_obligation(Obligation::new(
160            tcx,
161            cause.clone(),
162            param_env,
163            ty::ClauseKind::WellFormed(term),
164        ));
165    }
166
167    if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
168        ocx.register_obligation(Obligation::new(
169            tcx,
170            cause.clone(),
171            param_env,
172            ty::ClauseKind::WellFormed(self_ty.into()),
173        ));
174
175        let self_ty = ocx.normalize(&cause, param_env, Unnormalized::new_wip(self_ty));
176        let impl_self_ty = tcx.type_of(impl_def_id).instantiate(tcx, args).skip_norm_wip();
177        let impl_self_ty = ocx.normalize(&cause, param_env, Unnormalized::new_wip(impl_self_ty));
178
179        ocx.eq(&cause, param_env, self_ty, impl_self_ty)?;
180    }
181
182    Ok(())
183}