Skip to main content

rustc_hir_analysis/collect/type_of/
opaque.rs

1use rustc_hir::def::DefKind;
2use rustc_hir::def_id::LocalDefId;
3use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem, def, intravisit};
4use rustc_middle::bug;
5use rustc_middle::hir::nested_filter;
6use rustc_middle::ty::{self, DefiningScopeKind, EarlyBinder, Ty, TyCtxt, TypeVisitableExt};
7use rustc_trait_selection::opaque_types::report_item_does_not_constrain_error;
8use tracing::{debug, instrument, trace};
9
10use crate::errors::UnconstrainedOpaqueType;
11
12/// Checks "defining uses" of opaque `impl Trait` in associated types.
13/// These can only be defined by associated items of the same trait.
14#[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("find_opaque_ty_constraints_for_impl_trait_in_assoc_type",
                                    "rustc_hir_analysis::collect::type_of::opaque",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs"),
                                    ::tracing_core::__macro_support::Option::Some(14u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::type_of::opaque"),
                                    ::tracing_core::field::FieldSet::new(&["def_id",
                                                    "opaque_types_from"],
                                        ::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(&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(&opaque_types_from)
                                                            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: EarlyBinder<'_, Ty<'_>> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let mut parent_def_id = def_id;
            while tcx.def_kind(parent_def_id) == def::DefKind::OpaqueTy {
                parent_def_id = tcx.local_parent(parent_def_id);
            }
            let impl_def_id = tcx.local_parent(parent_def_id);
            match tcx.def_kind(impl_def_id) {
                DefKind::Impl { .. } => {}
                other =>
                    ::rustc_middle::util::bug::bug_fmt(format_args!("invalid impl trait in assoc type parent: {0:?}",
                            other)),
            }
            let mut locator =
                TaitConstraintLocator {
                    def_id,
                    tcx,
                    found: None,
                    opaque_types_from,
                };
            for &assoc_id in tcx.associated_item_def_ids(impl_def_id) {
                let assoc = tcx.associated_item(assoc_id);
                match assoc.kind {
                    ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => {
                        locator.check(assoc_id.expect_local())
                    }
                    ty::AssocKind::Type { .. } => {}
                }
            }
            if let Some(hidden) = locator.found {
                hidden.ty
            } else {
                let guar =
                    tcx.dcx().emit_err(UnconstrainedOpaqueType {
                            span: tcx.def_span(def_id),
                            name: tcx.item_ident(parent_def_id.to_def_id()),
                            what: "impl",
                        });
                EarlyBinder::bind(Ty::new_error(tcx, guar))
            }
        }
    }
}#[instrument(skip(tcx), level = "debug")]
15pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
16    tcx: TyCtxt<'_>,
17    def_id: LocalDefId,
18    opaque_types_from: DefiningScopeKind,
19) -> EarlyBinder<'_, Ty<'_>> {
20    let mut parent_def_id = def_id;
21    while tcx.def_kind(parent_def_id) == def::DefKind::OpaqueTy {
22        // Account for `type Alias = impl Trait<Foo = impl Trait>;` (#116031)
23        parent_def_id = tcx.local_parent(parent_def_id);
24    }
25    let impl_def_id = tcx.local_parent(parent_def_id);
26    match tcx.def_kind(impl_def_id) {
27        DefKind::Impl { .. } => {}
28        other => bug!("invalid impl trait in assoc type parent: {other:?}"),
29    }
30
31    let mut locator = TaitConstraintLocator { def_id, tcx, found: None, opaque_types_from };
32
33    for &assoc_id in tcx.associated_item_def_ids(impl_def_id) {
34        let assoc = tcx.associated_item(assoc_id);
35        match assoc.kind {
36            ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => {
37                locator.check(assoc_id.expect_local())
38            }
39            // Associated types don't have bodies, so they can't constrain hidden types
40            ty::AssocKind::Type { .. } => {}
41        }
42    }
43
44    if let Some(hidden) = locator.found {
45        hidden.ty
46    } else {
47        let guar = tcx.dcx().emit_err(UnconstrainedOpaqueType {
48            span: tcx.def_span(def_id),
49            name: tcx.item_ident(parent_def_id.to_def_id()),
50            what: "impl",
51        });
52        EarlyBinder::bind(Ty::new_error(tcx, guar))
53    }
54}
55
56/// Checks "defining uses" of opaque `impl Trait` types to ensure that they meet the restrictions
57/// laid for "higher-order pattern unification".
58/// This ensures that inference is tractable.
59/// In particular, definitions of opaque types can only use other generics as arguments,
60/// and they cannot repeat an argument. Example:
61///
62/// ```ignore (illustrative)
63/// type Foo<A, B> = impl Bar<A, B>;
64///
65/// // Okay -- `Foo` is applied to two distinct, generic types.
66/// fn a<T, U>() -> Foo<T, U> { .. }
67///
68/// // Not okay -- `Foo` is applied to `T` twice.
69/// fn b<T>() -> Foo<T, T> { .. }
70///
71/// // Not okay -- `Foo` is applied to a non-generic type.
72/// fn b<T>() -> Foo<T, u32> { .. }
73/// ```
74#[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("find_opaque_ty_constraints_for_tait",
                                    "rustc_hir_analysis::collect::type_of::opaque",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs"),
                                    ::tracing_core::__macro_support::Option::Some(74u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::type_of::opaque"),
                                    ::tracing_core::field::FieldSet::new(&["def_id",
                                                    "opaque_types_from"],
                                        ::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(&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(&opaque_types_from)
                                                            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: EarlyBinder<'_, Ty<'_>> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let mut locator =
                TaitConstraintLocator {
                    def_id,
                    tcx,
                    found: None,
                    opaque_types_from,
                };
            tcx.hir_walk_toplevel_module(&mut locator);
            if let Some(hidden) = locator.found {
                hidden.ty
            } else {
                let mut parent_def_id = def_id;
                while tcx.def_kind(parent_def_id) == def::DefKind::OpaqueTy {
                    parent_def_id = tcx.local_parent(parent_def_id);
                }
                let guar =
                    tcx.dcx().emit_err(UnconstrainedOpaqueType {
                            span: tcx.def_span(def_id),
                            name: tcx.item_ident(parent_def_id.to_def_id()),
                            what: "crate",
                        });
                EarlyBinder::bind(Ty::new_error(tcx, guar))
            }
        }
    }
}#[instrument(skip(tcx), level = "debug")]
75pub(super) fn find_opaque_ty_constraints_for_tait(
76    tcx: TyCtxt<'_>,
77    def_id: LocalDefId,
78    opaque_types_from: DefiningScopeKind,
79) -> EarlyBinder<'_, Ty<'_>> {
80    let mut locator = TaitConstraintLocator { def_id, tcx, found: None, opaque_types_from };
81
82    tcx.hir_walk_toplevel_module(&mut locator);
83
84    if let Some(hidden) = locator.found {
85        hidden.ty
86    } else {
87        let mut parent_def_id = def_id;
88        while tcx.def_kind(parent_def_id) == def::DefKind::OpaqueTy {
89            // Account for `type Alias = impl Trait<Foo = impl Trait>;` (#116031)
90            parent_def_id = tcx.local_parent(parent_def_id);
91        }
92        let guar = tcx.dcx().emit_err(UnconstrainedOpaqueType {
93            span: tcx.def_span(def_id),
94            name: tcx.item_ident(parent_def_id.to_def_id()),
95            what: "crate",
96        });
97        EarlyBinder::bind(Ty::new_error(tcx, guar))
98    }
99}
100
101struct TaitConstraintLocator<'tcx> {
102    tcx: TyCtxt<'tcx>,
103
104    /// def_id of the opaque type whose defining uses are being checked
105    def_id: LocalDefId,
106
107    /// as we walk the defining uses, we are checking that all of them
108    /// define the same hidden type. This variable is set to `Some`
109    /// with the first type that we find, and then later types are
110    /// checked against it (we also carry the span of that first
111    /// type).
112    found: Option<ty::DefinitionSiteHiddenType<'tcx>>,
113
114    opaque_types_from: DefiningScopeKind,
115}
116
117impl<'tcx> TaitConstraintLocator<'tcx> {
118    fn insert_found(&mut self, hidden_ty: ty::DefinitionSiteHiddenType<'tcx>) {
119        if let Some(prev) = &mut self.found {
120            if hidden_ty.ty != prev.ty {
121                let (Ok(guar) | Err(guar)) =
122                    prev.build_mismatch_error(&hidden_ty, self.tcx).map(|d| d.emit());
123                *prev = ty::DefinitionSiteHiddenType::new_error(self.tcx, guar);
124            }
125        } else {
126            self.found = Some(hidden_ty);
127        }
128    }
129
130    fn non_defining_use_in_defining_scope(&mut self, item_def_id: LocalDefId) {
131        // We make sure that all opaque types get defined while
132        // type checking the defining scope, so this error is unreachable
133        // with the new solver.
134        if !!self.tcx.next_trait_solver_globally() {
    ::core::panicking::panic("assertion failed: !self.tcx.next_trait_solver_globally()")
};assert!(!self.tcx.next_trait_solver_globally());
135        let guar = report_item_does_not_constrain_error(self.tcx, item_def_id, self.def_id, None);
136        self.insert_found(ty::DefinitionSiteHiddenType::new_error(self.tcx, guar));
137    }
138
139    #[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("check",
                                    "rustc_hir_analysis::collect::type_of::opaque",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs"),
                                    ::tracing_core::__macro_support::Option::Some(139u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::type_of::opaque"),
                                    ::tracing_core::field::FieldSet::new(&["item_def_id"],
                                        ::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(&item_def_id)
                                                            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: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let tcx = self.tcx;
            if !tcx.has_typeck_results(item_def_id) {
                {
                    use ::tracing::__macro_support::Callsite as _;
                    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                        {
                            static META: ::tracing::Metadata<'static> =
                                {
                                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs:144",
                                        "rustc_hir_analysis::collect::type_of::opaque",
                                        ::tracing::Level::DEBUG,
                                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs"),
                                        ::tracing_core::__macro_support::Option::Some(144u32),
                                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::type_of::opaque"),
                                        ::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!("no constraint: no typeck results")
                                                            as &dyn Value))])
                            });
                    } else { ; }
                };
                return;
            }
            let opaque_types_defined_by =
                tcx.opaque_types_defined_by(item_def_id);
            if !opaque_types_defined_by.contains(&self.def_id) {
                {
                    use ::tracing::__macro_support::Callsite as _;
                    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                        {
                            static META: ::tracing::Metadata<'static> =
                                {
                                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs:151",
                                        "rustc_hir_analysis::collect::type_of::opaque",
                                        ::tracing::Level::DEBUG,
                                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs"),
                                        ::tracing_core::__macro_support::Option::Some(151u32),
                                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::type_of::opaque"),
                                        ::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!("no constraint: no opaque types defined")
                                                            as &dyn Value))])
                            });
                    } else { ; }
                };
                return;
            }
            let hir_node = tcx.hir_node_by_def_id(item_def_id);
            if true {
                if !!#[allow(non_exhaustive_omitted_patterns)] match hir_node
                                {
                                Node::ForeignItem(..) => true,
                                _ => false,
                            } {
                    {
                        ::core::panicking::panic_fmt(format_args!("foreign items cannot constrain opaque types"));
                    }
                };
            };
            if let Some(hir_sig) = hir_node.fn_sig() &&
                    hir_sig.decl.output.is_suggestable_infer_ty().is_some() {
                let guar =
                    self.tcx.dcx().span_delayed_bug(hir_sig.decl.output.span(),
                        "inferring return types and opaque types do not mix well");
                self.found =
                    Some(ty::DefinitionSiteHiddenType::new_error(tcx, guar));
                return;
            }
            match self.opaque_types_from {
                DefiningScopeKind::HirTypeck => {
                    let tables = tcx.typeck(item_def_id);
                    if let Some(guar) = tables.tainted_by_errors {
                        self.insert_found(ty::DefinitionSiteHiddenType::new_error(tcx,
                                guar));
                    } else if let Some(&hidden_type) =
                            tables.hidden_types.get(&self.def_id) {
                        self.insert_found(hidden_type);
                    } else {
                        self.non_defining_use_in_defining_scope(item_def_id);
                    }
                }
                DefiningScopeKind::MirBorrowck =>
                    match tcx.mir_borrowck(item_def_id) {
                        Err(guar) =>
                            self.insert_found(ty::DefinitionSiteHiddenType::new_error(tcx,
                                    guar)),
                        Ok(hidden_types) => {
                            if let Some(&hidden_type) = hidden_types.get(&self.def_id) {
                                {
                                    use ::tracing::__macro_support::Callsite as _;
                                    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                                        {
                                            static META: ::tracing::Metadata<'static> =
                                                {
                                                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs:190",
                                                        "rustc_hir_analysis::collect::type_of::opaque",
                                                        ::tracing::Level::DEBUG,
                                                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs"),
                                                        ::tracing_core::__macro_support::Option::Some(190u32),
                                                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::type_of::opaque"),
                                                        ::tracing_core::field::FieldSet::new(&["message",
                                                                        "hidden_type"],
                                                            ::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!("found constraint")
                                                                            as &dyn Value)),
                                                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                                                    ::tracing::__macro_support::Option::Some(&debug(&hidden_type)
                                                                            as &dyn Value))])
                                            });
                                    } else { ; }
                                };
                                self.insert_found(hidden_type);
                            } else if let Err(guar) =
                                    tcx.type_of_opaque_hir_typeck(self.def_id).skip_binder().error_reported()
                                {
                                self.insert_found(ty::DefinitionSiteHiddenType::new_error(tcx,
                                        guar));
                            } else {
                                self.non_defining_use_in_defining_scope(item_def_id);
                            }
                        }
                    },
            }
        }
    }
}#[instrument(skip(self), level = "debug")]
140    fn check(&mut self, item_def_id: LocalDefId) {
141        // Don't try to check items that cannot possibly constrain the type.
142        let tcx = self.tcx;
143        if !tcx.has_typeck_results(item_def_id) {
144            debug!("no constraint: no typeck results");
145            return;
146        }
147
148        let opaque_types_defined_by = tcx.opaque_types_defined_by(item_def_id);
149        // Don't try to check items that cannot possibly constrain the type.
150        if !opaque_types_defined_by.contains(&self.def_id) {
151            debug!("no constraint: no opaque types defined");
152            return;
153        }
154
155        // Function items with `_` in their return type already emit an error, skip any
156        // "non-defining use" errors for them.
157        // Note that we use `Node::fn_sig` instead of `Node::fn_decl` here, because the former
158        // excludes closures, which are allowed to have `_` in their return type.
159        let hir_node = tcx.hir_node_by_def_id(item_def_id);
160        debug_assert!(
161            !matches!(hir_node, Node::ForeignItem(..)),
162            "foreign items cannot constrain opaque types",
163        );
164        if let Some(hir_sig) = hir_node.fn_sig()
165            && hir_sig.decl.output.is_suggestable_infer_ty().is_some()
166        {
167            let guar = self.tcx.dcx().span_delayed_bug(
168                hir_sig.decl.output.span(),
169                "inferring return types and opaque types do not mix well",
170            );
171            self.found = Some(ty::DefinitionSiteHiddenType::new_error(tcx, guar));
172            return;
173        }
174
175        match self.opaque_types_from {
176            DefiningScopeKind::HirTypeck => {
177                let tables = tcx.typeck(item_def_id);
178                if let Some(guar) = tables.tainted_by_errors {
179                    self.insert_found(ty::DefinitionSiteHiddenType::new_error(tcx, guar));
180                } else if let Some(&hidden_type) = tables.hidden_types.get(&self.def_id) {
181                    self.insert_found(hidden_type);
182                } else {
183                    self.non_defining_use_in_defining_scope(item_def_id);
184                }
185            }
186            DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(item_def_id) {
187                Err(guar) => self.insert_found(ty::DefinitionSiteHiddenType::new_error(tcx, guar)),
188                Ok(hidden_types) => {
189                    if let Some(&hidden_type) = hidden_types.get(&self.def_id) {
190                        debug!(?hidden_type, "found constraint");
191                        self.insert_found(hidden_type);
192                    } else if let Err(guar) =
193                        tcx.type_of_opaque_hir_typeck(self.def_id).skip_binder().error_reported()
194                    {
195                        self.insert_found(ty::DefinitionSiteHiddenType::new_error(tcx, guar));
196                    } else {
197                        self.non_defining_use_in_defining_scope(item_def_id);
198                    }
199                }
200            },
201        }
202    }
203}
204
205impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
206    type NestedFilter = nested_filter::All;
207
208    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
209        self.tcx
210    }
211    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
212        intravisit::walk_expr(self, ex);
213    }
214    fn visit_item(&mut self, it: &'tcx Item<'tcx>) {
215        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs:215",
                        "rustc_hir_analysis::collect::type_of::opaque",
                        ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs"),
                        ::tracing_core::__macro_support::Option::Some(215u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::type_of::opaque"),
                        ::tracing_core::field::FieldSet::new(&["it.owner_id"],
                            ::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};
                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(&it.owner_id)
                                            as &dyn Value))])
            });
    } else { ; }
};trace!(?it.owner_id);
216        self.check(it.owner_id.def_id);
217        intravisit::walk_item(self, it);
218    }
219    fn visit_impl_item(&mut self, it: &'tcx ImplItem<'tcx>) {
220        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs:220",
                        "rustc_hir_analysis::collect::type_of::opaque",
                        ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs"),
                        ::tracing_core::__macro_support::Option::Some(220u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::type_of::opaque"),
                        ::tracing_core::field::FieldSet::new(&["it.owner_id"],
                            ::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};
                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(&it.owner_id)
                                            as &dyn Value))])
            });
    } else { ; }
};trace!(?it.owner_id);
221        self.check(it.owner_id.def_id);
222        intravisit::walk_impl_item(self, it);
223    }
224    fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) {
225        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs:225",
                        "rustc_hir_analysis::collect::type_of::opaque",
                        ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs"),
                        ::tracing_core::__macro_support::Option::Some(225u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::type_of::opaque"),
                        ::tracing_core::field::FieldSet::new(&["it.owner_id"],
                            ::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};
                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(&it.owner_id)
                                            as &dyn Value))])
            });
    } else { ; }
};trace!(?it.owner_id);
226        self.check(it.owner_id.def_id);
227        intravisit::walk_trait_item(self, it);
228    }
229    fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) {
230        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs:230",
                        "rustc_hir_analysis::collect::type_of::opaque",
                        ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs"),
                        ::tracing_core::__macro_support::Option::Some(230u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::type_of::opaque"),
                        ::tracing_core::field::FieldSet::new(&["it.owner_id"],
                            ::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};
                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(&it.owner_id)
                                            as &dyn Value))])
            });
    } else { ; }
};trace!(?it.owner_id);
231        match (&it.owner_id.def_id, &self.def_id) {
    (left_val, right_val) => {
        if *left_val == *right_val {
            let kind = ::core::panicking::AssertKind::Ne;
            ::core::panicking::assert_failed(kind, &*left_val, &*right_val,
                ::core::option::Option::None);
        }
    }
};assert_ne!(it.owner_id.def_id, self.def_id);
232        // No need to call `check`, as we do not run borrowck on foreign items.
233        intravisit::walk_foreign_item(self, it);
234    }
235}
236
237pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
238    tcx: TyCtxt<'tcx>,
239    def_id: LocalDefId,
240    owner_def_id: LocalDefId,
241    opaque_types_from: DefiningScopeKind,
242) -> EarlyBinder<'tcx, Ty<'tcx>> {
243    // When an opaque type is stranded, its hidden type cannot be inferred
244    // so we should not continue.
245    if !tcx.opaque_types_defined_by(owner_def_id).contains(&def_id) {
246        let opaque_type_span = tcx.def_span(def_id);
247        let guar = tcx
248            .dcx()
249            .span_delayed_bug(opaque_type_span, "cannot infer type for stranded opaque type");
250        return EarlyBinder::bind(Ty::new_error(tcx, guar));
251    }
252
253    match opaque_types_from {
254        DefiningScopeKind::HirTypeck => {
255            let tables = tcx.typeck(owner_def_id);
256            if let Some(guar) = tables.tainted_by_errors {
257                EarlyBinder::bind(Ty::new_error(tcx, guar))
258            } else if let Some(hidden_ty) = tables.hidden_types.get(&def_id) {
259                hidden_ty.ty
260            } else {
261                if !!tcx.next_trait_solver_globally() {
    ::core::panicking::panic("assertion failed: !tcx.next_trait_solver_globally()")
};assert!(!tcx.next_trait_solver_globally());
262                // We failed to resolve the opaque type or it
263                // resolves to itself. We interpret this as the
264                // no values of the hidden type ever being constructed,
265                // so we can just make the hidden type be `!`.
266                // For backwards compatibility reasons, we fall back to
267                // `()` until we the diverging default is changed.
268                EarlyBinder::bind(tcx.types.unit)
269            }
270        }
271        DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(owner_def_id) {
272            Ok(hidden_types) => {
273                if let Some(hidden_ty) = hidden_types.get(&def_id) {
274                    hidden_ty.ty
275                } else {
276                    let hir_ty = tcx.type_of_opaque_hir_typeck(def_id);
277                    if let Err(guar) = hir_ty.skip_binder().error_reported() {
278                        EarlyBinder::bind(Ty::new_error(tcx, guar))
279                    } else {
280                        if !!tcx.next_trait_solver_globally() {
    ::core::panicking::panic("assertion failed: !tcx.next_trait_solver_globally()")
};assert!(!tcx.next_trait_solver_globally());
281                        hir_ty
282                    }
283                }
284            }
285            Err(guar) => EarlyBinder::bind(Ty::new_error(tcx, guar)),
286        },
287    }
288}