Rollup merge of #112734 - dswij:bounds-predicates-clause, r=compiler-errors

Make `Bound::predicates`  use `Clause`

Part of #107250

`Bound::predicates` returns an iterator over `Binder<_, Clause>` instead of `Predicate`.

I tried updating `explicit_predicates_of` as well, but it seems that it needs a lot more change than I thought. Will do it in a separate PR instead.
This commit is contained in:
Matthias Krüger 2023-06-18 08:06:43 +02:00 committed by GitHub
commit 3436069c34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 24 deletions

View File

@ -31,9 +31,10 @@ use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause; use rustc_infer::traits::ObligationCause;
use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::middle::stability::AllowUnstable;
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef}; use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
use rustc_middle::ty::DynKind;
use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::GenericParamDefKind;
use rustc_middle::ty::ToPredicate;
use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{DynKind, ToPredicate};
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::symbol::{kw, Ident, Symbol};
@ -944,7 +945,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let mut trait_bounds = vec![]; let mut trait_bounds = vec![];
let mut projection_bounds = vec![]; let mut projection_bounds = vec![];
for (pred, span) in bounds.predicates() { for (clause, span) in bounds.predicates() {
let pred: ty::Predicate<'tcx> = clause.to_predicate(tcx);
let bound_pred = pred.kind(); let bound_pred = pred.kind();
match bound_pred.skip_binder() { match bound_pred.skip_binder() {
ty::PredicateKind::Clause(clause) => match clause { ty::PredicateKind::Clause(clause) => match clause {

View File

@ -2,6 +2,7 @@
//! `ty` form from the HIR. //! `ty` form from the HIR.
use rustc_hir::LangItem; use rustc_hir::LangItem;
use rustc_middle::ty::Binder;
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt}; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
use rustc_span::Span; use rustc_span::Span;
@ -23,52 +24,58 @@ use rustc_span::Span;
/// include the self type (e.g., `trait_bounds`) but in others we do not /// include the self type (e.g., `trait_bounds`) but in others we do not
#[derive(Default, PartialEq, Eq, Clone, Debug)] #[derive(Default, PartialEq, Eq, Clone, Debug)]
pub struct Bounds<'tcx> { pub struct Bounds<'tcx> {
pub predicates: Vec<(ty::Predicate<'tcx>, Span)>, pub predicates: Vec<(Binder<'tcx, ty::Clause<'tcx>>, Span)>,
} }
impl<'tcx> Bounds<'tcx> { impl<'tcx> Bounds<'tcx> {
pub fn push_region_bound( pub fn push_region_bound(
&mut self, &mut self,
tcx: TyCtxt<'tcx>, _tcx: TyCtxt<'tcx>,
region: ty::PolyTypeOutlivesPredicate<'tcx>, region: ty::PolyTypeOutlivesPredicate<'tcx>,
span: Span, span: Span,
) { ) {
self.predicates.push((region.to_predicate(tcx), span)); self.predicates.push((region.map_bound(|p| ty::Clause::TypeOutlives(p)), span));
} }
pub fn push_trait_bound( pub fn push_trait_bound(
&mut self, &mut self,
tcx: TyCtxt<'tcx>, _tcx: TyCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>,
span: Span, span: Span,
constness: ty::BoundConstness, constness: ty::BoundConstness,
polarity: ty::ImplPolarity, polarity: ty::ImplPolarity,
) { ) {
self.predicates.push(( self.predicates.push((
trait_ref trait_ref.map_bound(|trait_ref| {
.map_bound(|trait_ref| ty::TraitPredicate { trait_ref, constness, polarity }) ty::Clause::Trait(ty::TraitPredicate { trait_ref, constness, polarity })
.to_predicate(tcx), }),
span, span,
)); ));
} }
pub fn push_projection_bound( pub fn push_projection_bound(
&mut self, &mut self,
tcx: TyCtxt<'tcx>, _tcx: TyCtxt<'tcx>,
projection: ty::PolyProjectionPredicate<'tcx>, projection: ty::PolyProjectionPredicate<'tcx>,
span: Span, span: Span,
) { ) {
self.predicates.push((projection.to_predicate(tcx), span)); self.predicates.push((projection.map_bound(|proj| ty::Clause::Projection(proj)), span));
} }
pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) { pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) {
let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span)); let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span));
let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]); let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]);
// Preferable to put this obligation first, since we report better errors for sized ambiguity. // Preferable to put this obligation first, since we report better errors for sized ambiguity.
self.predicates.insert(0, (trait_ref.without_const().to_predicate(tcx), span)); self.predicates.insert(
0,
(
ty::Binder::dummy(ty::Clause::Trait(trait_ref.without_const().to_predicate(tcx))),
span,
),
);
} }
pub fn predicates(&self) -> impl Iterator<Item = (ty::Predicate<'tcx>, Span)> + '_ { pub fn predicates(&self) -> impl Iterator<Item = (Binder<'tcx, ty::Clause<'tcx>>, Span)> + '_ {
self.predicates.iter().cloned() self.predicates.iter().cloned()
} }
} }

View File

@ -3,6 +3,7 @@ use crate::astconv::{AstConv, OnlySelfBounds};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_infer::traits::util; use rustc_infer::traits::util;
use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::ToPredicate;
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::Span; use rustc_span::Span;
@ -44,7 +45,12 @@ fn associated_type_bounds<'tcx>(
} }
}); });
let all_bounds = tcx.arena.alloc_from_iter(bounds.predicates().chain(bounds_from_parent)); let all_bounds = tcx.arena.alloc_from_iter(
bounds
.predicates()
.map(|(clause, span)| (clause.to_predicate(tcx), span))
.chain(bounds_from_parent),
);
debug!( debug!(
"associated_type_bounds({}) = {:?}", "associated_type_bounds({}) = {:?}",
tcx.def_path_str(assoc_item_def_id.to_def_id()), tcx.def_path_str(assoc_item_def_id.to_def_id()),
@ -72,7 +78,9 @@ fn opaque_type_bounds<'tcx>(
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span); icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
debug!(?bounds); debug!(?bounds);
tcx.arena.alloc_from_iter(bounds.predicates()) tcx.arena.alloc_from_iter(
bounds.predicates().map(|(clause, span)| (clause.to_predicate(tcx), span)),
)
}) })
} }

View File

@ -126,7 +126,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
predicates.extend( predicates.extend(
icx.astconv() icx.astconv()
.compute_bounds(tcx.types.self_param, self_bounds, OnlySelfBounds(false)) .compute_bounds(tcx.types.self_param, self_bounds, OnlySelfBounds(false))
.predicates(), .predicates()
.map(|(clause, span)| (clause.to_predicate(tcx), span)),
); );
} }
@ -175,7 +176,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
param.span, param.span,
); );
trace!(?bounds); trace!(?bounds);
predicates.extend(bounds.predicates()); predicates.extend(
bounds.predicates().map(|(clause, span)| (clause.to_predicate(tcx), span)),
);
trace!(?predicates); trace!(?predicates);
} }
GenericParamKind::Const { .. } => { GenericParamKind::Const { .. } => {
@ -234,7 +237,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
bound_vars, bound_vars,
OnlySelfBounds(false), OnlySelfBounds(false),
); );
predicates.extend(bounds.predicates()); predicates.extend(
bounds.predicates().map(|(clause, span)| (clause.to_predicate(tcx), span)),
);
} }
hir::WherePredicate::RegionPredicate(region_pred) => { hir::WherePredicate::RegionPredicate(region_pred) => {
@ -658,8 +663,12 @@ pub(super) fn implied_predicates_with_filter(
}; };
// Combine the two lists to form the complete set of superbounds: // Combine the two lists to form the complete set of superbounds:
let implied_bounds = let implied_bounds = &*tcx.arena.alloc_from_iter(
&*tcx.arena.alloc_from_iter(superbounds.predicates().chain(where_bounds_that_match)); superbounds
.predicates()
.map(|(clause, span)| (clause.to_predicate(tcx), span))
.chain(where_bounds_that_match),
);
debug!(?implied_bounds); debug!(?implied_bounds);
// Now require that immediate supertraits are converted, which will, in // Now require that immediate supertraits are converted, which will, in
@ -816,7 +825,7 @@ impl<'tcx> ItemCtxt<'tcx> {
); );
} }
bounds.predicates().collect() bounds.predicates().map(|(clause, span)| (clause.to_predicate(self.tcx), span)).collect()
} }
#[instrument(level = "trace", skip(self))] #[instrument(level = "trace", skip(self))]

View File

@ -1214,6 +1214,13 @@ impl<'tcx> ToPredicate<'tcx> for Clause<'tcx> {
} }
} }
impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, Clause<'tcx>> {
#[inline(always)]
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
tcx.mk_predicate(self.map_bound(|clause| ty::PredicateKind::Clause(clause)))
}
}
impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> { impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
#[inline(always)] #[inline(always)]
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {

View File

@ -1270,13 +1270,13 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
); );
for (pred, _) in bounds.predicates() { for (pred, _) in bounds.predicates() {
match pred.kind().skip_binder() { match pred.skip_binder() {
ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => { ty::Clause::Trait(trait_predicate) => {
if self.visit_trait(trait_predicate.trait_ref).is_break() { if self.visit_trait(trait_predicate.trait_ref).is_break() {
return; return;
} }
} }
ty::PredicateKind::Clause(ty::Clause::Projection(proj_predicate)) => { ty::Clause::Projection(proj_predicate) => {
let term = self.visit(proj_predicate.term); let term = self.visit(proj_predicate.term);
if term.is_break() if term.is_break()
|| self.visit_projection_ty(proj_predicate.projection_ty).is_break() || self.visit_projection_ty(proj_predicate.projection_ty).is_break()