Skip to content

Commit

Permalink
Bound::predicates to return Clause
Browse files Browse the repository at this point in the history
  • Loading branch information
dswij committed Jun 17, 2023
1 parent 1d7d824 commit f874345
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 24 deletions.
6 changes: 4 additions & 2 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
use rustc_middle::middle::stability::AllowUnstable;
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
use rustc_middle::ty::DynKind;
use rustc_middle::ty::GenericParamDefKind;
use rustc_middle::ty::ToPredicate;
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_span::edit_distance::find_best_match_for_name;
use rustc_span::symbol::{kw, Ident, Symbol};
Expand Down Expand Up @@ -1509,7 +1510,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {

let mut trait_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();
match bound_pred.skip_binder() {
ty::PredicateKind::Clause(clause) => match clause {
Expand Down
29 changes: 18 additions & 11 deletions compiler/rustc_hir_analysis/src/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! `ty` form from the HIR.

use rustc_hir::LangItem;
use rustc_middle::ty::Binder;
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
use rustc_span::Span;

Expand All @@ -23,52 +24,58 @@ use rustc_span::Span;
/// include the self type (e.g., `trait_bounds`) but in others we do not
#[derive(Default, PartialEq, Eq, Clone, Debug)]
pub struct Bounds<'tcx> {
pub predicates: Vec<(ty::Predicate<'tcx>, Span)>,
pub predicates: Vec<(Binder<'tcx, ty::Clause<'tcx>>, Span)>,
}

impl<'tcx> Bounds<'tcx> {
pub fn push_region_bound(
&mut self,
tcx: TyCtxt<'tcx>,
_tcx: TyCtxt<'tcx>,
region: ty::PolyTypeOutlivesPredicate<'tcx>,
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(
&mut self,
tcx: TyCtxt<'tcx>,
_tcx: TyCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
span: Span,
constness: ty::BoundConstness,
polarity: ty::ImplPolarity,
) {
self.predicates.push((
trait_ref
.map_bound(|trait_ref| ty::TraitPredicate { trait_ref, constness, polarity })
.to_predicate(tcx),
trait_ref.map_bound(|trait_ref| {
ty::Clause::Trait(ty::TraitPredicate { trait_ref, constness, polarity })
}),
span,
));
}

pub fn push_projection_bound(
&mut self,
tcx: TyCtxt<'tcx>,
_tcx: TyCtxt<'tcx>,
projection: ty::PolyProjectionPredicate<'tcx>,
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) {
let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span));
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.
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()
}
}
12 changes: 10 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/item_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::astconv::{AstConv, OnlySelfBounds};
use rustc_hir as hir;
use rustc_infer::traits::util;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::ToPredicate;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::Span;
Expand Down Expand Up @@ -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!(
"associated_type_bounds({}) = {:?}",
tcx.def_path_str(assoc_item_def_id.to_def_id()),
Expand Down Expand Up @@ -72,7 +78,9 @@ fn opaque_type_bounds<'tcx>(
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
debug!(?bounds);

tcx.arena.alloc_from_iter(bounds.predicates())
tcx.arena.alloc_from_iter(
bounds.predicates().map(|(clause, span)| (clause.to_predicate(tcx), span)),
)
})
}

Expand Down
21 changes: 15 additions & 6 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
predicates.extend(
icx.astconv()
.compute_bounds(tcx.types.self_param, self_bounds, OnlySelfBounds(false))
.predicates(),
.predicates()
.map(|(clause, span)| (clause.to_predicate(tcx), span)),
);
}

Expand Down Expand Up @@ -175,7 +176,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
param.span,
);
trace!(?bounds);
predicates.extend(bounds.predicates());
predicates.extend(
bounds.predicates().map(|(clause, span)| (clause.to_predicate(tcx), span)),
);
trace!(?predicates);
}
GenericParamKind::Const { .. } => {
Expand Down Expand Up @@ -234,7 +237,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
bound_vars,
OnlySelfBounds(false),
);
predicates.extend(bounds.predicates());
predicates.extend(
bounds.predicates().map(|(clause, span)| (clause.to_predicate(tcx), span)),
);
}

hir::WherePredicate::RegionPredicate(region_pred) => {
Expand Down Expand Up @@ -658,8 +663,12 @@ pub(super) fn implied_predicates_with_filter(
};

// Combine the two lists to form the complete set of superbounds:
let implied_bounds =
&*tcx.arena.alloc_from_iter(superbounds.predicates().chain(where_bounds_that_match));
let implied_bounds = &*tcx.arena.alloc_from_iter(
superbounds
.predicates()
.map(|(clause, span)| (clause.to_predicate(tcx), span))
.chain(where_bounds_that_match),
);
debug!(?implied_bounds);

// Now require that immediate supertraits are converted, which will, in
Expand Down Expand Up @@ -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))]
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
#[inline(always)]
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1270,13 +1270,13 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
);

for (pred, _) in bounds.predicates() {
match pred.kind().skip_binder() {
ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => {
match pred.skip_binder() {
ty::Clause::Trait(trait_predicate) => {
if self.visit_trait(trait_predicate.trait_ref).is_break() {
return;
}
}
ty::PredicateKind::Clause(ty::Clause::Projection(proj_predicate)) => {
ty::Clause::Projection(proj_predicate) => {
let term = self.visit(proj_predicate.term);
if term.is_break()
|| self.visit_projection_ty(proj_predicate.projection_ty).is_break()
Expand Down

0 comments on commit f874345

Please sign in to comment.