|  | 
| 1 | 1 | use crate::rustc_middle::ty::DefIdTree; | 
| 2 |  | -use rustc_hir::{def::DefKind, def_id::DefId}; | 
|  | 2 | +use rustc_hir::{self as hir, def::DefKind, def_id::DefId}; | 
| 3 | 3 | use rustc_middle::ty::{self, Ty, TyCtxt}; | 
|  | 4 | +use rustc_span::{Span, DUMMY_SP}; | 
| 4 | 5 | 
 | 
| 5 | 6 | pub fn provide(providers: &mut ty::query::Providers) { | 
| 6 | 7 |     *providers = ty::query::Providers { assumed_wf_types, ..*providers }; | 
| 7 | 8 | } | 
| 8 | 9 | 
 | 
| 9 |  | -fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> { | 
|  | 10 | +fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &[(Ty<'_>, Span)] { | 
| 10 | 11 |     match tcx.def_kind(def_id) { | 
| 11 | 12 |         DefKind::Fn => { | 
| 12 | 13 |             let sig = tcx.fn_sig(def_id); | 
| 13 | 14 |             let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig); | 
| 14 |  | -            liberated_sig.inputs_and_output | 
|  | 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 | +            } | 
| 15 | 28 |         } | 
| 16 | 29 |         DefKind::AssocFn => { | 
| 17 | 30 |             let sig = tcx.fn_sig(def_id); | 
| 18 | 31 |             let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig); | 
| 19 |  | -            let mut assumed_wf_types: Vec<_> = | 
| 20 |  | -                tcx.assumed_wf_types(tcx.parent(def_id)).as_slice().into(); | 
| 21 |  | -            assumed_wf_types.extend(liberated_sig.inputs_and_output); | 
| 22 |  | -            tcx.intern_type_list(&assumed_wf_types) | 
|  | 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 | +            } | 
| 23 | 46 |         } | 
| 24 | 47 |         DefKind::Impl => match tcx.impl_trait_ref(def_id) { | 
| 25 | 48 |             Some(trait_ref) => { | 
| 26 | 49 |                 let types: Vec<_> = trait_ref.substs.types().collect(); | 
| 27 |  | -                tcx.intern_type_list(&types) | 
|  | 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 | +                )) | 
| 28 | 64 |             } | 
| 29 | 65 |             // Only the impl self type | 
| 30 |  | -            None => tcx.intern_type_list(&[tcx.type_of(def_id)]), | 
|  | 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 | +            } | 
| 31 | 78 |         }, | 
| 32 | 79 |         DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)), | 
| 33 | 80 |         DefKind::Mod | 
| @@ -56,6 +103,6 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> { | 
| 56 | 103 |         | DefKind::LifetimeParam | 
| 57 | 104 |         | DefKind::GlobalAsm | 
| 58 | 105 |         | DefKind::Closure | 
| 59 |  | -        | DefKind::Generator => ty::List::empty(), | 
|  | 106 | +        | DefKind::Generator => &[], | 
| 60 | 107 |     } | 
| 61 | 108 | } | 
0 commit comments