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