Split item bounds and item super predicates
This commit is contained in:
parent
a128516cf9
commit
aa39dbb962
20 changed files with 186 additions and 46 deletions
|
@ -431,7 +431,7 @@ fn fn_sig_suggestion<'tcx>(
|
|||
|
||||
let asyncness = if tcx.asyncness(assoc.def_id).is_async() {
|
||||
output = if let ty::Alias(_, alias_ty) = *output.kind() {
|
||||
tcx.explicit_item_bounds(alias_ty.def_id)
|
||||
tcx.explicit_item_super_predicates(alias_ty.def_id)
|
||||
.iter_instantiated_copied(tcx, alias_ty.args)
|
||||
.find_map(|(bound, _)| bound.as_projection_clause()?.no_bound_vars()?.term.ty())
|
||||
.unwrap_or_else(|| {
|
||||
|
|
|
@ -61,6 +61,9 @@ pub fn provide(providers: &mut Providers) {
|
|||
type_alias_is_lazy: type_of::type_alias_is_lazy,
|
||||
item_bounds: item_bounds::item_bounds,
|
||||
explicit_item_bounds: item_bounds::explicit_item_bounds,
|
||||
item_super_predicates: item_bounds::item_super_predicates,
|
||||
explicit_item_super_predicates: item_bounds::explicit_item_super_predicates,
|
||||
item_non_self_assumptions: item_bounds::item_non_self_assumptions,
|
||||
generics_of: generics_of::generics_of,
|
||||
predicates_of: predicates_of::predicates_of,
|
||||
predicates_defined_on,
|
||||
|
@ -633,7 +636,9 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
|||
tcx.ensure().generics_of(def_id);
|
||||
tcx.ensure().predicates_of(def_id);
|
||||
tcx.ensure().explicit_item_bounds(def_id);
|
||||
tcx.ensure().explicit_item_super_predicates(def_id);
|
||||
tcx.ensure().item_bounds(def_id);
|
||||
tcx.ensure().item_super_predicates(def_id);
|
||||
}
|
||||
|
||||
hir::ItemKind::TyAlias(..) => {
|
||||
|
@ -689,6 +694,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
|
|||
|
||||
hir::TraitItemKind::Type(_, Some(_)) => {
|
||||
tcx.ensure().item_bounds(def_id);
|
||||
tcx.ensure().item_super_predicates(def_id);
|
||||
tcx.ensure().type_of(def_id);
|
||||
// Account for `type T = _;`.
|
||||
let mut visitor = HirPlaceholderCollector::default();
|
||||
|
@ -698,6 +704,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
|
|||
|
||||
hir::TraitItemKind::Type(_, None) => {
|
||||
tcx.ensure().item_bounds(def_id);
|
||||
tcx.ensure().item_super_predicates(def_id);
|
||||
// #74612: Visit and try to find bad placeholders
|
||||
// even if there is no concrete type.
|
||||
let mut visitor = HirPlaceholderCollector::default();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use super::ItemCtxt;
|
||||
use crate::astconv::{AstConv, PredicateFilter};
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::traits::util;
|
||||
use rustc_middle::ty::GenericArgs;
|
||||
|
@ -19,6 +20,7 @@ fn associated_type_bounds<'tcx>(
|
|||
assoc_item_def_id: LocalDefId,
|
||||
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
|
||||
span: Span,
|
||||
filter: PredicateFilter,
|
||||
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
|
||||
let item_ty = Ty::new_projection(
|
||||
tcx,
|
||||
|
@ -27,7 +29,7 @@ fn associated_type_bounds<'tcx>(
|
|||
);
|
||||
|
||||
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
|
||||
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, PredicateFilter::All);
|
||||
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, filter);
|
||||
// Associated types are implicitly sized unless a `?Sized` bound is found
|
||||
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
|
||||
|
||||
|
@ -63,10 +65,11 @@ fn opaque_type_bounds<'tcx>(
|
|||
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
|
||||
item_ty: Ty<'tcx>,
|
||||
span: Span,
|
||||
filter: PredicateFilter,
|
||||
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
|
||||
ty::print::with_reduced_queries!({
|
||||
let icx = ItemCtxt::new(tcx, opaque_def_id);
|
||||
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, PredicateFilter::All);
|
||||
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, filter);
|
||||
// Opaque types are implicitly sized unless a `?Sized` bound is found
|
||||
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
|
||||
debug!(?bounds);
|
||||
|
@ -78,6 +81,21 @@ fn opaque_type_bounds<'tcx>(
|
|||
pub(super) fn explicit_item_bounds(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: LocalDefId,
|
||||
) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> {
|
||||
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::All)
|
||||
}
|
||||
|
||||
pub(super) fn explicit_item_super_predicates(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: LocalDefId,
|
||||
) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> {
|
||||
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::SelfOnly)
|
||||
}
|
||||
|
||||
pub(super) fn explicit_item_bounds_with_filter(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: LocalDefId,
|
||||
filter: PredicateFilter,
|
||||
) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> {
|
||||
match tcx.opt_rpitit_info(def_id.to_def_id()) {
|
||||
// RPITIT's bounds are the same as opaque type bounds, but with
|
||||
|
@ -95,6 +113,7 @@ pub(super) fn explicit_item_bounds(
|
|||
ty::GenericArgs::identity_for_item(tcx, def_id),
|
||||
),
|
||||
item.span,
|
||||
filter,
|
||||
));
|
||||
}
|
||||
Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!(
|
||||
|
@ -109,7 +128,7 @@ pub(super) fn explicit_item_bounds(
|
|||
kind: hir::TraitItemKind::Type(bounds, _),
|
||||
span,
|
||||
..
|
||||
}) => associated_type_bounds(tcx, def_id, bounds, *span),
|
||||
}) => associated_type_bounds(tcx, def_id, bounds, *span, filter),
|
||||
hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait: false, .. }),
|
||||
span,
|
||||
|
@ -117,7 +136,7 @@ pub(super) fn explicit_item_bounds(
|
|||
}) => {
|
||||
let args = GenericArgs::identity_for_item(tcx, def_id);
|
||||
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
||||
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
|
||||
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
|
||||
}
|
||||
// Since RPITITs are astconv'd as projections in `ast_ty_to_ty`, when we're asking
|
||||
// for the item bounds of the *opaques* in a trait's default method signature, we
|
||||
|
@ -135,7 +154,7 @@ pub(super) fn explicit_item_bounds(
|
|||
let args = GenericArgs::identity_for_item(tcx, def_id);
|
||||
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
||||
tcx.arena.alloc_slice(
|
||||
&opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
|
||||
&opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
|
||||
.to_vec()
|
||||
.fold_with(&mut AssocTyToOpaque { tcx, fn_def_id: fn_def_id.to_def_id() }),
|
||||
)
|
||||
|
@ -155,6 +174,31 @@ pub(super) fn item_bounds(
|
|||
})
|
||||
}
|
||||
|
||||
pub(super) fn item_super_predicates(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: DefId,
|
||||
) -> ty::EarlyBinder<&'_ ty::List<ty::Clause<'_>>> {
|
||||
tcx.explicit_item_super_predicates(def_id).map_bound(|bounds| {
|
||||
tcx.mk_clauses_from_iter(
|
||||
util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound)).filter_only_self(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn item_non_self_assumptions(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: DefId,
|
||||
) -> ty::EarlyBinder<&'_ ty::List<ty::Clause<'_>>> {
|
||||
let all_bounds: FxIndexSet<_> = tcx.item_bounds(def_id).skip_binder().iter().collect();
|
||||
let own_bounds: FxIndexSet<_> =
|
||||
tcx.item_super_predicates(def_id).skip_binder().iter().collect();
|
||||
if all_bounds.len() == own_bounds.len() {
|
||||
ty::EarlyBinder::bind(ty::List::empty())
|
||||
} else {
|
||||
ty::EarlyBinder::bind(tcx.mk_clauses_from_iter(all_bounds.difference(&own_bounds).copied()))
|
||||
}
|
||||
}
|
||||
|
||||
struct AssocTyToOpaque<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
fn_def_id: DefId,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue