rustc_ty_utils/
implied_bounds.rs1use std::iter;
2
3use rustc_data_structures::fx::FxHashMap;
4use rustc_hir as hir;
5use rustc_hir::def::DefKind;
6use rustc_hir::def_id::LocalDefId;
7use rustc_middle::query::Providers;
8use rustc_middle::ty::{self, Ty, TyCtxt, Unnormalized, fold_regions};
9use rustc_span::{Span, bug, span_bug};
10
11pub(crate) fn provide(providers: &mut Providers) {
12 *providers = Providers {
13 assumed_wf_types,
14 assumed_wf_types_for_rpitit: |tcx, def_id| {
15 if !tcx.is_impl_trait_in_trait(def_id.to_def_id()) {
::core::panicking::panic("assertion failed: tcx.is_impl_trait_in_trait(def_id.to_def_id())")
};assert!(tcx.is_impl_trait_in_trait(def_id.to_def_id()));
16 tcx.assumed_wf_types(def_id)
17 },
18 ..*providers
19 };
20}
21
22fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'tcx>, Span)] {
23 let kind = tcx.def_kind(def_id);
24 match kind {
25 DefKind::Fn => {
26 let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip();
27 let liberated_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);
28 tcx.arena.alloc_from_iter(itertools::zip_eq(
29 liberated_sig.inputs_and_output,
30 fn_sig_spans(tcx, def_id),
31 ))
32 }
33 DefKind::AssocFn => {
34 let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip();
35 let liberated_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);
36 let mut assumed_wf_types: Vec<_> =
37 tcx.assumed_wf_types(tcx.local_parent(def_id)).into();
38 assumed_wf_types.extend(itertools::zip_eq(
39 liberated_sig.inputs_and_output,
40 fn_sig_spans(tcx, def_id),
41 ));
42 tcx.arena.alloc_slice(&assumed_wf_types)
43 }
44 DefKind::Impl { of_trait } => {
45 let tys = if of_trait {
48 let trait_ref = tcx.impl_trait_ref(def_id);
49 trait_ref.skip_binder().args.types().collect()
50 } else {
51 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[tcx.type_of(def_id).instantiate_identity().skip_norm_wip()]))vec![tcx.type_of(def_id).instantiate_identity().skip_norm_wip()]
52 };
53
54 let mut impl_spans = impl_spans(tcx, def_id);
55 tcx.arena.alloc_from_iter(tys.into_iter().map(|ty| (ty, impl_spans.next().unwrap())))
56 }
57 DefKind::AssocTy if let Some(data) = tcx.opt_rpitit_info(def_id.to_def_id()) => {
58 match data {
59 ty::ImplTraitInTraitData::Trait { fn_def_id, .. } => {
60 let mut mapping = FxHashMap::default();
70 let generics = tcx.generics_of(def_id);
71
72 for param in &generics.own_params[tcx.generics_of(fn_def_id).own_params.len()..]
77 {
78 let orig_lt =
79 tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local());
80 if #[allow(non_exhaustive_omitted_patterns)] match orig_lt.kind() {
ty::ReLateParam(..) => true,
_ => false,
}matches!(orig_lt.kind(), ty::ReLateParam(..)) {
81 mapping.insert(
82 orig_lt,
83 ty::Region::new_early_param(
84 tcx,
85 ty::EarlyParamRegion { index: param.index, name: param.name },
86 ),
87 );
88 }
89 }
90 let remapped_wf_tys = fold_regions(
92 tcx,
93 tcx.assumed_wf_types(fn_def_id.expect_local()).to_vec(),
94 |region, _| {
95 if let Some(remapped_region) = mapping.get(®ion) {
99 *remapped_region
100 } else {
101 region
102 }
103 },
104 );
105 tcx.arena.alloc_from_iter(remapped_wf_tys)
106 }
107 ty::ImplTraitInTraitData::Impl { .. } => {
110 let impl_def_id = tcx.local_parent(def_id);
111 let rpitit_def_id = tcx.trait_item_of(def_id).unwrap();
112 let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto(
113 tcx,
114 impl_def_id.to_def_id(),
115 tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip().args,
116 );
117 tcx.arena.alloc_from_iter(
118 ty::EarlyBinder::bind_iter(tcx.assumed_wf_types_for_rpitit(rpitit_def_id))
119 .iter_instantiated_copied(tcx, args)
120 .map(Unnormalized::skip_norm_wip)
121 .chain(tcx.assumed_wf_types(impl_def_id).into_iter().copied()),
122 )
123 }
124 }
125 }
126 DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)),
127 DefKind::Static { .. }
128 | DefKind::Const
129 | DefKind::AnonConst
130 | DefKind::Struct
131 | DefKind::Union
132 | DefKind::Enum
133 | DefKind::Trait
134 | DefKind::TraitAlias
135 | DefKind::TyAlias
136 | DefKind::TestBinderConstraints => ty::List::empty(),
137 DefKind::OpaqueTy
138 | DefKind::Mod
139 | DefKind::Variant
140 | DefKind::ForeignTy
141 | DefKind::TyParam
142 | DefKind::ConstParam
143 | DefKind::Ctor(_, _)
144 | DefKind::Macro(_)
145 | DefKind::ExternCrate
146 | DefKind::Use
147 | DefKind::ForeignMod
148 | DefKind::Field
149 | DefKind::LifetimeParam
150 | DefKind::GlobalAsm
151 | DefKind::Closure
152 | DefKind::SyntheticCoroutineBody => {
153 bug_impl(Some(tcx.def_span(def_id)),
format_args!("`assumed_wf_types` not defined for {0} `{1:?}`",
kind.descr(def_id.to_def_id()), def_id), Location::caller());span_bug!(
154 tcx.def_span(def_id),
155 "`assumed_wf_types` not defined for {} `{def_id:?}`",
156 kind.descr(def_id.to_def_id())
157 );
158 }
159 }
160}
161
162fn fn_sig_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator<Item = Span> {
163 let node = tcx.hir_node_by_def_id(def_id);
164 if let Some(decl) = node.fn_decl() {
165 decl.inputs.iter().map(|ty| ty.span).chain(iter::once(decl.output.span()))
166 } else {
167 bug_impl(None,
format_args!("unexpected item for fn {0:?}: {1:?}", def_id, node),
Location::caller())bug!("unexpected item for fn {def_id:?}: {node:?}")
168 }
169}
170
171fn impl_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator<Item = Span> {
172 let item = tcx.hir_expect_item(def_id);
173 if let hir::ItemKind::Impl(impl_) = item.kind {
174 let trait_args = impl_
175 .of_trait
176 .map(|of_trait| of_trait.trait_ref.path.segments.last().unwrap().args().args)
177 .into_flat_iter()
178 .map(|arg| arg.span());
179 let dummy_spans_for_default_args = impl_
180 .of_trait
181 .map(|of_trait| iter::repeat(of_trait.trait_ref.path.span))
182 .into_flat_iter();
183 iter::once(impl_.self_ty.span).chain(trait_args).chain(dummy_spans_for_default_args)
184 } else {
185 bug_impl(None,
format_args!("unexpected item for impl {0:?}: {1:?}", def_id, item),
Location::caller())bug!("unexpected item for impl {def_id:?}: {item:?}")
186 }
187}