Skip to content

Commit

Permalink
Auto merge of #112938 - compiler-errors:clause-3, r=oli-obk
Browse files Browse the repository at this point in the history
Migrate `TyCtxt::predicates_of` and `ParamEnv::caller_bounds` to `Clause`

The last big change in the series.

I will follow-up with additional filed issues once this PR lands:
- [ ] Investigate making `TypeFoldable<TyCtxt<'tcx>> for ty::Clause<'tcx>` implementation less weird: https://github.com/rust-lang/rust/blob/2efe09170530fa18e42ff05b8d9dd23f00b5c430/compiler/rustc_middle/src/ty/structural_impls.rs#L672
- [ ] Clean up the elaborator since it should only be emitting child clauses, not predicates
- [ ] Rename identifiers like `pred` and `predicates` to `clause` if they're actually clauses around the codebase
- [ ] Validate that all of the `ToPredicate` impls are acutally still needed, or prune them if they're not

r? `@ghost` until the other branch lands
  • Loading branch information
bors committed Jun 27, 2023
2 parents b9ad9b7 + 374173c commit b5e51db
Show file tree
Hide file tree
Showing 84 changed files with 512 additions and 738 deletions.
6 changes: 3 additions & 3 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,8 +678,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let tcx = self.infcx.tcx;

// Find out if the predicates show that the type is a Fn or FnMut
let find_fn_kind_from_did = |(pred, _): (ty::Predicate<'tcx>, _)| {
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) = pred.kind().skip_binder()
let find_fn_kind_from_did = |(pred, _): (ty::Clause<'tcx>, _)| {
if let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder()
&& pred.self_ty() == ty
{
if Some(pred.def_id()) == tcx.lang_items().fn_trait() {
Expand All @@ -705,7 +705,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => tcx
.explicit_item_bounds(def_id)
.subst_iter_copied(tcx, substs)
.find_map(|(clause, span)| find_fn_kind_from_did((clause.as_predicate(), span))),
.find_map(|(clause, span)| find_fn_kind_from_did((clause, span))),
ty::Closure(_, substs) => match substs.as_closure().kind() {
ty::ClosureKind::Fn => Some(hir::Mutability::Not),
ty::ClosureKind::FnMut => Some(hir::Mutability::Mut),
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_borrowck/src/diagnostics/region_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {

fn any_param_predicate_mentions(
&self,
predicates: &[ty::Predicate<'tcx>],
clauses: &[ty::Clause<'tcx>],
ty: Ty<'tcx>,
region: ty::EarlyBoundRegion,
) -> bool {
Expand All @@ -937,10 +937,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Param(_) = ty.kind()
{
predicates.iter().any(|pred| {
clauses.iter().any(|pred| {
match pred.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) if data.self_ty() == ty => {}
ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) if data.projection_ty.self_ty() == ty => {}
ty::ClauseKind::Trait(data) if data.self_ty() == ty => {}
ty::ClauseKind::Projection(data) if data.projection_ty.self_ty() == ty => {}
_ => return false,
}
tcx.any_free_region_meets(pred, |r| {
Expand Down
60 changes: 25 additions & 35 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -945,40 +945,30 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {

let mut trait_bounds = vec![];
let mut projection_bounds = vec![];
for (clause, span) in bounds.clauses() {
let pred: ty::Predicate<'tcx> = clause.as_predicate();
for (pred, span) in bounds.clauses() {
let bound_pred = pred.kind();
match bound_pred.skip_binder() {
ty::PredicateKind::Clause(clause) => match clause {
ty::ClauseKind::Trait(trait_pred) => {
assert_eq!(trait_pred.polarity, ty::ImplPolarity::Positive);
trait_bounds.push((
bound_pred.rebind(trait_pred.trait_ref),
span,
trait_pred.constness,
));
}
ty::ClauseKind::Projection(proj) => {
projection_bounds.push((bound_pred.rebind(proj), span));
}
ty::ClauseKind::TypeOutlives(_) => {
// Do nothing, we deal with regions separately
}
ty::ClauseKind::RegionOutlives(_)
| ty::ClauseKind::ConstArgHasType(..)
| ty::ClauseKind::WellFormed(_)
| ty::ClauseKind::ConstEvaluatable(_) => {
bug!()
}
},
ty::PredicateKind::AliasRelate(..)
| ty::PredicateKind::ObjectSafe(_)
| ty::PredicateKind::ClosureKind(_, _, _)
| ty::PredicateKind::Subtype(_)
| ty::PredicateKind::Coerce(_)
| ty::PredicateKind::ConstEquate(_, _)
| ty::PredicateKind::TypeWellFormedFromEnv(_)
| ty::PredicateKind::Ambiguous => bug!(),
ty::ClauseKind::Trait(trait_pred) => {
assert_eq!(trait_pred.polarity, ty::ImplPolarity::Positive);
trait_bounds.push((
bound_pred.rebind(trait_pred.trait_ref),
span,
trait_pred.constness,
));
}
ty::ClauseKind::Projection(proj) => {
projection_bounds.push((bound_pred.rebind(proj), span));
}
ty::ClauseKind::TypeOutlives(_) => {
// Do nothing, we deal with regions separately
}
ty::ClauseKind::RegionOutlives(_)
| ty::ClauseKind::ConstArgHasType(..)
| ty::ClauseKind::WellFormed(_)
| ty::ClauseKind::ConstEvaluatable(_)
| ty::ClauseKind::TypeWellFormedFromEnv(_) => {
bug!()
}
}
}

Expand Down Expand Up @@ -1425,9 +1415,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|| {
traits::transitive_bounds_that_define_assoc_item(
tcx,
predicates.iter().filter_map(|(p, _)| {
Some(p.to_opt_poly_trait_pred()?.map_bound(|t| t.trait_ref))
}),
predicates
.iter()
.filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref))),
assoc_name,
)
},
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ fn compare_method_predicate_entailment<'tcx>(
// the new hybrid bounds we computed.
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
let param_env = ty::ParamEnv::new(
tcx.mk_predicates(&hybrid_preds.predicates),
tcx.mk_clauses(&hybrid_preds.predicates),
Reveal::UserFacing,
hir::Constness::NotConst,
);
Expand Down Expand Up @@ -1835,7 +1835,7 @@ fn compare_type_predicate_entailment<'tcx>(
let impl_ty_span = tcx.def_span(impl_ty_def_id);
let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_def_id);
let param_env = ty::ParamEnv::new(
tcx.mk_predicates(&hybrid_preds.predicates),
tcx.mk_clauses(&hybrid_preds.predicates),
Reveal::UserFacing,
hir::Constness::NotConst,
);
Expand Down Expand Up @@ -2011,7 +2011,7 @@ pub(super) fn check_type_bounds<'tcx>(
.to_predicate(tcx),
),
};
ty::ParamEnv::new(tcx.mk_predicates(&predicates), Reveal::UserFacing, param_env.constness())
ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing, param_env.constness())
};
debug!(?normalize_param_env);

Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,15 +296,15 @@ fn default_body_is_unstable(
/// Re-sugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
fn bounds_from_generic_predicates<'tcx>(
tcx: TyCtxt<'tcx>,
predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
predicates: impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>,
) -> (String, String) {
let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
let mut projections = vec![];
for (predicate, _) in predicates {
debug!("predicate {:?}", predicate);
let bound_predicate = predicate.kind();
match bound_predicate.skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
ty::ClauseKind::Trait(trait_predicate) => {
let entry = types.entry(trait_predicate.self_ty()).or_default();
let def_id = trait_predicate.def_id();
if Some(def_id) != tcx.lang_items().sized_trait() {
Expand All @@ -313,7 +313,7 @@ fn bounds_from_generic_predicates<'tcx>(
entry.push(trait_predicate.def_id());
}
}
ty::PredicateKind::Clause(ty::ClauseKind::Projection(projection_pred)) => {
ty::ClauseKind::Projection(projection_pred) => {
projections.push(bound_predicate.rebind(projection_pred));
}
_ => {}
Expand Down Expand Up @@ -362,7 +362,7 @@ fn fn_sig_suggestion<'tcx>(
tcx: TyCtxt<'tcx>,
sig: ty::FnSig<'tcx>,
ident: Ident,
predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
predicates: impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>,
assoc: ty::AssocItem,
) -> String {
let args = sig
Expand Down
64 changes: 30 additions & 34 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc_middle::mir::ConstraintCategory;
use rustc_middle::query::Providers;
use rustc_middle::ty::trait_def::TraitSpecializationKind;
use rustc_middle::ty::{
self, AdtKind, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
TypeVisitable, TypeVisitableExt, TypeVisitor,
};
use rustc_middle::ty::{GenericArgKind, InternalSubsts};
Expand Down Expand Up @@ -322,7 +322,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
// Gather the bounds with which all other items inside of this trait constrain the GAT.
// This is calculated by taking the intersection of the bounds that each item
// constrains the GAT with individually.
let mut new_required_bounds: Option<FxHashSet<ty::Predicate<'_>>> = None;
let mut new_required_bounds: Option<FxHashSet<ty::Clause<'_>>> = None;
for item in associated_items {
let item_def_id = item.id.owner_id;
// Skip our own GAT, since it does not constrain itself at all.
Expand Down Expand Up @@ -419,28 +419,25 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
let mut unsatisfied_bounds: Vec<_> = required_bounds
.into_iter()
.filter(|clause| match clause.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(
ty::OutlivesPredicate(a, b),
)) => !region_known_to_outlive(
tcx,
gat_def_id.def_id,
param_env,
&FxIndexSet::default(),
a,
b,
),
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
a,
b,
))) => !ty_known_to_outlive(
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => {
!region_known_to_outlive(
tcx,
gat_def_id.def_id,
param_env,
&FxIndexSet::default(),
a,
b,
)
}
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => !ty_known_to_outlive(
tcx,
gat_def_id.def_id,
param_env,
&FxIndexSet::default(),
a,
b,
),
_ => bug!("Unexpected PredicateKind"),
_ => bug!("Unexpected ClauseKind"),
})
.map(|clause| clause.to_string())
.collect();
Expand Down Expand Up @@ -488,7 +485,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
fn augment_param_env<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
new_predicates: Option<&FxHashSet<ty::Predicate<'tcx>>>,
new_predicates: Option<&FxHashSet<ty::Clause<'tcx>>>,
) -> ty::ParamEnv<'tcx> {
let Some(new_predicates) = new_predicates else {
return param_env;
Expand All @@ -498,7 +495,7 @@ fn augment_param_env<'tcx>(
return param_env;
}

let bounds = tcx.mk_predicates_from_iter(
let bounds = tcx.mk_clauses_from_iter(
param_env.caller_bounds().iter().chain(new_predicates.iter().cloned()),
);
// FIXME(compiler-errors): Perhaps there is a case where we need to normalize this
Expand All @@ -524,7 +521,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
wf_tys: &FxIndexSet<Ty<'tcx>>,
gat_def_id: LocalDefId,
gat_generics: &'tcx ty::Generics,
) -> Option<FxHashSet<ty::Predicate<'tcx>>> {
) -> Option<FxHashSet<ty::Clause<'tcx>>> {
// The bounds we that we would require from `to_check`
let mut bounds = FxHashSet::default();

Expand Down Expand Up @@ -573,11 +570,10 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
);
// The predicate we expect to see. (In our example,
// `Self: 'me`.)
let clause = ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
ty::OutlivesPredicate(ty_param, region_param),
));
let clause = tcx.mk_predicate(ty::Binder::dummy(clause));
bounds.insert(clause);
bounds.insert(
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty_param, region_param))
.to_predicate(tcx),
);
}
}

Expand Down Expand Up @@ -622,11 +618,13 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
},
);
// The predicate we expect to see.
let clause = ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(
ty::OutlivesPredicate(region_a_param, region_b_param),
));
let clause = tcx.mk_predicate(ty::Binder::dummy(clause));
bounds.insert(clause);
bounds.insert(
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
region_a_param,
region_b_param,
))
.to_predicate(tcx),
);
}
}
}
Expand Down Expand Up @@ -1406,7 +1404,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
infcx,
wfcx.param_env.without_const(),
wfcx.body_def_id,
p,
p.as_predicate(),
sp,
)
});
Expand Down Expand Up @@ -1875,9 +1873,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
// We lower empty bounds like `Vec<dyn Copy>:` as
// `WellFormed(Vec<dyn Copy>)`, which will later get checked by
// regular WF checking
if let ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..)) =
pred.kind().skip_binder()
{
if let ty::ClauseKind::WellFormed(..) = pred.kind().skip_binder() {
continue;
}
// Match the existing behavior.
Expand Down
12 changes: 4 additions & 8 deletions compiler/rustc_hir_analysis/src/collect/item_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,12 @@ fn associated_type_bounds<'tcx>(
.iter()
.copied()
.filter(|(pred, _)| match pred.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr)) => tr.self_ty() == item_ty,
ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) => {
proj.projection_ty.self_ty() == item_ty
}
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(outlives)) => {
outlives.0 == item_ty
}
ty::ClauseKind::Trait(tr) => tr.self_ty() == item_ty,
ty::ClauseKind::Projection(proj) => proj.projection_ty.self_ty() == item_ty,
ty::ClauseKind::TypeOutlives(outlives) => outlives.0 == item_ty,
_ => false,
})
.map(|(pred, span)| (pred.expect_clause(), span));
.map(|(clause, span)| (clause, span));

let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses().chain(bounds_from_parent));
debug!(
Expand Down
Loading

0 comments on commit b5e51db

Please sign in to comment.