]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_ty_utils/src/implied_bounds.rs
Improve spans of non-WF implied bound types
[rust.git] / compiler / rustc_ty_utils / src / implied_bounds.rs
1 use crate::rustc_middle::ty::DefIdTree;
2 use rustc_hir::{self as hir, def::DefKind, def_id::DefId};
3 use rustc_middle::ty::{self, Ty, TyCtxt};
4 use rustc_span::{Span, DUMMY_SP};
5
6 pub fn provide(providers: &mut ty::query::Providers) {
7     *providers = ty::query::Providers { assumed_wf_types, ..*providers };
8 }
9
10 fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &[(Ty<'_>, Span)] {
11     match tcx.def_kind(def_id) {
12         DefKind::Fn => {
13             let sig = tcx.fn_sig(def_id);
14             let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig);
15             if let Some(node) = tcx.hir().get_if_local(def_id)
16                 && let Some(decl) = node.fn_decl()
17             {
18                 assert_eq!(decl.inputs.len(), liberated_sig.inputs().len());
19                 tcx.arena.alloc_from_iter(std::iter::zip(
20                     liberated_sig.inputs_and_output,
21                     decl.inputs.iter().map(|ty| ty.span).chain([decl.output.span()]),
22                 ))
23             } else {
24                 tcx.arena.alloc_from_iter(
25                     liberated_sig.inputs_and_output.iter().map(|ty| (ty, DUMMY_SP)),
26                 )
27             }
28         }
29         DefKind::AssocFn => {
30             let sig = tcx.fn_sig(def_id);
31             let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig);
32             let assumed_wf_types = tcx.assumed_wf_types(tcx.parent(def_id));
33             if let Some(node) = tcx.hir().get_if_local(def_id)
34                 && let Some(decl) = node.fn_decl()
35             {
36                 assert_eq!(decl.inputs.len(), liberated_sig.inputs().len());
37                 tcx.arena.alloc_from_iter(assumed_wf_types.iter().copied().chain(std::iter::zip(
38                     liberated_sig.inputs_and_output,
39                     decl.inputs.iter().map(|ty| ty.span).chain([decl.output.span()]),
40                 )))
41             } else {
42                 tcx.arena.alloc_from_iter(assumed_wf_types.iter().copied().chain(
43                     liberated_sig.inputs_and_output.iter().map(|ty| (ty, DUMMY_SP)),
44                 ))
45             }
46         }
47         DefKind::Impl => match tcx.impl_trait_ref(def_id) {
48             Some(trait_ref) => {
49                 let types: Vec<_> = trait_ref.substs.types().collect();
50                 let self_span = if let Some(hir::Node::Item(hir::Item {
51                     kind: hir::ItemKind::Impl(impl_),
52                     ..
53                 })) = tcx.hir().get_if_local(def_id)
54                 {
55                     impl_.self_ty.span
56                 } else {
57                     DUMMY_SP
58                 };
59                 tcx.arena.alloc_from_iter(std::iter::zip(
60                     types,
61                     // FIXME: reliable way of getting trait ref substs...
62                     [self_span].into_iter().chain(std::iter::repeat(DUMMY_SP)),
63                 ))
64             }
65             // Only the impl self type
66             None => {
67                 let span = if let Some(hir::Node::Item(hir::Item {
68                     kind: hir::ItemKind::Impl(impl_),
69                     ..
70                 })) = tcx.hir().get_if_local(def_id)
71                 {
72                     impl_.self_ty.span
73                 } else {
74                     DUMMY_SP
75                 };
76                 tcx.arena.alloc_from_iter([(tcx.type_of(def_id), span)])
77             }
78         },
79         DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)),
80         DefKind::Mod
81         | DefKind::Struct
82         | DefKind::Union
83         | DefKind::Enum
84         | DefKind::Variant
85         | DefKind::Trait
86         | DefKind::TyAlias
87         | DefKind::ForeignTy
88         | DefKind::TraitAlias
89         | DefKind::TyParam
90         | DefKind::Const
91         | DefKind::ConstParam
92         | DefKind::Static(_)
93         | DefKind::Ctor(_, _)
94         | DefKind::Macro(_)
95         | DefKind::ExternCrate
96         | DefKind::Use
97         | DefKind::ForeignMod
98         | DefKind::AnonConst
99         | DefKind::InlineConst
100         | DefKind::OpaqueTy
101         | DefKind::ImplTraitPlaceholder
102         | DefKind::Field
103         | DefKind::LifetimeParam
104         | DefKind::GlobalAsm
105         | DefKind::Closure
106         | DefKind::Generator => &[],
107     }
108 }