2023-06-27 21:13:39 +00:00
|
|
|
use rustc_hir as hir;
|
|
|
|
use rustc_hir::def::DefKind;
|
|
|
|
use rustc_hir::def_id::LocalDefId;
|
2023-05-15 04:24:45 +00:00
|
|
|
use rustc_middle::query::Providers;
|
2022-08-17 10:22:32 +00:00
|
|
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
2023-06-27 21:13:39 +00:00
|
|
|
use rustc_span::Span;
|
|
|
|
use std::iter;
|
2022-08-17 10:22:32 +00:00
|
|
|
|
2023-05-15 04:24:45 +00:00
|
|
|
pub fn provide(providers: &mut Providers) {
|
|
|
|
*providers = Providers { assumed_wf_types, ..*providers };
|
2022-08-17 10:22:32 +00:00
|
|
|
}
|
|
|
|
|
2023-06-27 21:13:39 +00:00
|
|
|
fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'tcx>, Span)] {
|
2022-08-17 10:22:32 +00:00
|
|
|
match tcx.def_kind(def_id) {
|
|
|
|
DefKind::Fn => {
|
2023-01-19 19:52:52 +00:00
|
|
|
let sig = tcx.fn_sig(def_id).subst_identity();
|
2023-06-27 21:13:39 +00:00
|
|
|
let liberated_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);
|
|
|
|
tcx.arena.alloc_from_iter(itertools::zip_eq(
|
|
|
|
liberated_sig.inputs_and_output,
|
|
|
|
fn_sig_spans(tcx, def_id),
|
|
|
|
))
|
2022-08-17 10:22:32 +00:00
|
|
|
}
|
|
|
|
DefKind::AssocFn => {
|
2023-01-19 19:52:52 +00:00
|
|
|
let sig = tcx.fn_sig(def_id).subst_identity();
|
2023-06-27 21:13:39 +00:00
|
|
|
let liberated_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);
|
2022-08-17 10:22:32 +00:00
|
|
|
let mut assumed_wf_types: Vec<_> =
|
2023-06-27 21:13:39 +00:00
|
|
|
tcx.assumed_wf_types(tcx.local_parent(def_id)).into();
|
|
|
|
assumed_wf_types.extend(itertools::zip_eq(
|
|
|
|
liberated_sig.inputs_and_output,
|
|
|
|
fn_sig_spans(tcx, def_id),
|
|
|
|
));
|
|
|
|
tcx.arena.alloc_slice(&assumed_wf_types)
|
2022-08-17 10:22:32 +00:00
|
|
|
}
|
2023-02-12 18:26:47 +00:00
|
|
|
DefKind::Impl { .. } => {
|
2023-06-27 21:13:39 +00:00
|
|
|
// Trait arguments and the self type for trait impls or only the self type for
|
|
|
|
// inherent impls.
|
|
|
|
let tys = match tcx.impl_trait_ref(def_id) {
|
|
|
|
Some(trait_ref) => trait_ref.skip_binder().substs.types().collect(),
|
|
|
|
None => vec![tcx.type_of(def_id).subst_identity()],
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut impl_spans = impl_spans(tcx, def_id);
|
|
|
|
tcx.arena.alloc_from_iter(tys.into_iter().map(|ty| (ty, impl_spans.next().unwrap())))
|
2023-01-10 21:22:52 +00:00
|
|
|
}
|
2023-06-27 21:13:39 +00:00
|
|
|
DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)),
|
|
|
|
DefKind::OpaqueTy => match tcx.def_kind(tcx.local_parent(def_id)) {
|
2022-12-22 11:36:09 +00:00
|
|
|
DefKind::TyAlias => ty::List::empty(),
|
2023-06-27 21:13:39 +00:00
|
|
|
DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)),
|
2022-12-22 11:36:09 +00:00
|
|
|
// Nested opaque types only occur in associated types:
|
|
|
|
// ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; `
|
|
|
|
// assumed_wf_types should include those of `Opaque<T>`, `Opaque<T>` itself
|
|
|
|
// and `&'static T`.
|
2023-06-27 21:13:39 +00:00
|
|
|
DefKind::OpaqueTy => bug!("unimplemented implied bounds for nested opaque types"),
|
2022-12-22 11:36:09 +00:00
|
|
|
def_kind @ _ => {
|
|
|
|
bug!("unimplemented implied bounds for opaque types with parent {def_kind:?}")
|
|
|
|
}
|
|
|
|
},
|
2022-08-17 10:22:32 +00:00
|
|
|
DefKind::Mod
|
|
|
|
| DefKind::Struct
|
|
|
|
| DefKind::Union
|
|
|
|
| DefKind::Enum
|
|
|
|
| DefKind::Variant
|
|
|
|
| DefKind::Trait
|
|
|
|
| DefKind::TyAlias
|
|
|
|
| DefKind::ForeignTy
|
|
|
|
| DefKind::TraitAlias
|
|
|
|
| DefKind::TyParam
|
|
|
|
| DefKind::Const
|
|
|
|
| DefKind::ConstParam
|
|
|
|
| DefKind::Static(_)
|
|
|
|
| DefKind::Ctor(_, _)
|
|
|
|
| DefKind::Macro(_)
|
|
|
|
| DefKind::ExternCrate
|
|
|
|
| DefKind::Use
|
|
|
|
| DefKind::ForeignMod
|
|
|
|
| DefKind::AnonConst
|
|
|
|
| DefKind::InlineConst
|
|
|
|
| DefKind::Field
|
|
|
|
| DefKind::LifetimeParam
|
|
|
|
| DefKind::GlobalAsm
|
|
|
|
| DefKind::Closure
|
|
|
|
| DefKind::Generator => ty::List::empty(),
|
|
|
|
}
|
|
|
|
}
|
2023-06-27 21:13:39 +00:00
|
|
|
|
|
|
|
fn fn_sig_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator<Item = Span> + '_ {
|
|
|
|
let node = tcx.hir().get(tcx.local_def_id_to_hir_id(def_id));
|
|
|
|
if let Some(decl) = node.fn_decl() {
|
|
|
|
decl.inputs.iter().map(|ty| ty.span).chain(iter::once(decl.output.span()))
|
|
|
|
} else {
|
|
|
|
bug!("unexpected item for fn {def_id:?}: {node:?}")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn impl_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator<Item = Span> + '_ {
|
|
|
|
let item = tcx.hir().expect_item(def_id);
|
|
|
|
if let hir::ItemKind::Impl(impl_) = item.kind {
|
|
|
|
let trait_args = impl_
|
|
|
|
.of_trait
|
|
|
|
.into_iter()
|
|
|
|
.flat_map(|trait_ref| trait_ref.path.segments.last().unwrap().args().args)
|
|
|
|
.map(|arg| arg.span());
|
|
|
|
let dummy_spans_for_default_args =
|
|
|
|
impl_.of_trait.into_iter().flat_map(|trait_ref| iter::repeat(trait_ref.path.span));
|
|
|
|
iter::once(impl_.self_ty.span).chain(trait_args).chain(dummy_spans_for_default_args)
|
|
|
|
} else {
|
|
|
|
bug!("unexpected item for impl {def_id:?}: {item:?}")
|
|
|
|
}
|
|
|
|
}
|