Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a fully fledged Clause type, rename old Clause to ClauseKind #112772

Merged
merged 3 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, '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::Clause::Trait(pred)) = pred.kind().skip_binder()
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) = pred.kind().skip_binder()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's your opinion on reexporting the ClauseKind variants from a clause module and using clause::Trait instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh, doesn't really seem worthwhile tbh. Or at least, I think I want to do it as a follow-up 😸

&& pred.self_ty() == ty
{
if Some(pred.def_id()) == tcx.lang_items().fn_trait() {
Expand Down Expand Up @@ -775,7 +775,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let predicates: Result<Vec<_>, _> = errors
.into_iter()
.map(|err| match err.obligation.predicate.kind().skip_binder() {
PredicateKind::Clause(ty::Clause::Trait(predicate)) => {
PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => {
match predicate.self_ty().kind() {
ty::Param(param_ty) => Ok((
generics.type_param(param_ty, tcx),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/region_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -939,8 +939,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
{
predicates.iter().any(|pred| {
match pred.kind().skip_binder() {
ty::PredicateKind::Clause(ty::Clause::Trait(data)) if data.self_ty() == ty => {}
ty::PredicateKind::Clause(ty::Clause::Projection(data)) if data.projection_ty.self_ty() == ty => {}
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 => {}
_ => return false,
}
tcx.any_free_region_meets(pred, |r| {
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,9 @@ fn check_opaque_type_well_formed<'tcx>(
// Require the hidden type to be well-formed with only the generics of the opaque type.
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
// hidden type is well formed even without those bounds.
let predicate =
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(definition_ty.into())));
let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
definition_ty.into(),
)));
ocx.register_obligation(Obligation::misc(tcx, definition_span, def_id, param_env, predicate));

// Check that all obligations are satisfied by the implementation's
Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_borrowck/src/type_check/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
category: ConstraintCategory<'tcx>,
) {
self.prove_predicate(
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::Trait(ty::TraitPredicate {
trait_ref,
constness: ty::BoundConstness::NotConst,
polarity: ty::ImplPolarity::Positive,
}))),
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::Trait(
ty::TraitPredicate {
trait_ref,
constness: ty::BoundConstness::NotConst,
polarity: ty::ImplPolarity::Positive,
},
))),
locations,
category,
);
Expand Down
13 changes: 7 additions & 6 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1420,7 +1420,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// See #91068 for an example.
self.prove_predicates(
sig.inputs_and_output.iter().map(|ty| {
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
ty.into(),
)))
}),
Expand Down Expand Up @@ -1852,7 +1852,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {

let array_ty = rvalue.ty(body.local_decls(), tcx);
self.prove_predicate(
ty::PredicateKind::Clause(ty::Clause::WellFormed(array_ty.into())),
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(array_ty.into())),
Locations::Single(location),
ConstraintCategory::Boring,
);
Expand Down Expand Up @@ -2025,10 +2025,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
ConstraintCategory::Cast,
);

let outlives_predicate =
tcx.mk_predicate(Binder::dummy(ty::PredicateKind::Clause(
ty::Clause::TypeOutlives(ty::OutlivesPredicate(self_ty, *region)),
)));
let outlives_predicate = tcx.mk_predicate(Binder::dummy(
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
ty::OutlivesPredicate(self_ty, *region),
)),
));
self.prove_predicate(
outlives_predicate,
location.to_locations(),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/astconv/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let format_pred = |pred: ty::Predicate<'tcx>| {
let bound_predicate = pred.kind();
match bound_predicate.skip_binder() {
ty::PredicateKind::Clause(ty::Clause::Projection(pred)) => {
ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => {
let pred = bound_predicate.rebind(pred);
// `<Foo as Iterator>::Item = String`.
let projection_ty = pred.skip_binder().projection_ty;
Expand All @@ -364,7 +364,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
bound_span_label(projection_ty.self_ty(), &obligation, &quiet);
Some((obligation, projection_ty.self_ty()))
}
ty::PredicateKind::Clause(ty::Clause::Trait(poly_trait_ref)) => {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(poly_trait_ref)) => {
let p = poly_trait_ref.trait_ref;
let self_ty = p.self_ty();
let path = p.print_only_trait_path();
Expand Down
24 changes: 13 additions & 11 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -945,29 +945,31 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {

let mut trait_bounds = vec![];
let mut projection_bounds = vec![];
for (clause, span) in bounds.predicates() {
let pred: ty::Predicate<'tcx> = clause.to_predicate(tcx);
for (clause, span) in bounds.clauses() {
let pred: ty::Predicate<'tcx> = clause.as_predicate();
let bound_pred = pred.kind();
match bound_pred.skip_binder() {
ty::PredicateKind::Clause(clause) => match clause {
ty::Clause::Trait(trait_pred) => {
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::Clause::Projection(proj) => {
ty::ClauseKind::Projection(proj) => {
projection_bounds.push((bound_pred.rebind(proj), span));
}
ty::Clause::TypeOutlives(_) => {
ty::ClauseKind::TypeOutlives(_) => {
// Do nothing, we deal with regions separately
}
ty::Clause::RegionOutlives(_)
| ty::Clause::ConstArgHasType(..)
| ty::Clause::WellFormed(_)
| ty::Clause::ConstEvaluatable(_) => bug!(),
ty::ClauseKind::RegionOutlives(_)
| ty::ClauseKind::ConstArgHasType(..)
| ty::ClauseKind::WellFormed(_)
| ty::ClauseKind::ConstEvaluatable(_) => {
bug!()
}
},
ty::PredicateKind::AliasRelate(..)
| ty::PredicateKind::ObjectSafe(_)
Expand Down Expand Up @@ -1064,7 +1066,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {

let bound_predicate = pred.kind();
match bound_predicate.skip_binder() {
ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
let pred = bound_predicate.rebind(pred);
associated_types.entry(span).or_default().extend(
tcx.associated_items(pred.def_id())
Expand All @@ -1074,7 +1076,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.map(|item| item.def_id),
);
}
ty::PredicateKind::Clause(ty::Clause::Projection(pred)) => {
ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => {
let pred = bound_predicate.rebind(pred);
// A `Self` within the original bound will be substituted with a
// `trait_object_dummy_self`, so check for that.
Expand Down
39 changes: 19 additions & 20 deletions compiler/rustc_hir_analysis/src/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//! `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 @@ -24,58 +23,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<(Binder<'tcx, ty::Clause<'tcx>>, Span)>,
pub clauses: Vec<(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.map_bound(|p| ty::Clause::TypeOutlives(p)), span));
self.clauses
.push((region.map_bound(|p| ty::ClauseKind::TypeOutlives(p)).to_predicate(tcx), 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::Clause::Trait(ty::TraitPredicate { trait_ref, constness, polarity })
}),
self.clauses.push((
trait_ref
.map_bound(|trait_ref| {
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, constness, polarity })
})
.to_predicate(tcx),
span,
));
}

pub fn push_projection_bound(
&mut self,
_tcx: TyCtxt<'tcx>,
tcx: TyCtxt<'tcx>,
projection: ty::PolyProjectionPredicate<'tcx>,
span: Span,
) {
self.predicates.push((projection.map_bound(|proj| ty::Clause::Projection(proj)), span));
self.clauses.push((
projection.map_bound(|proj| ty::ClauseKind::Projection(proj)).to_predicate(tcx),
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,
(
ty::Binder::dummy(ty::Clause::Trait(trait_ref.without_const().to_predicate(tcx))),
span,
),
);
self.clauses.insert(0, (trait_ref.to_predicate(tcx), span));
}

pub fn predicates(&self) -> impl Iterator<Item = (Binder<'tcx, ty::Clause<'tcx>>, Span)> + '_ {
self.predicates.iter().cloned()
pub fn clauses(&self) -> impl Iterator<Item = (ty::Clause<'tcx>, Span)> + '_ {
self.clauses.iter().cloned()
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ fn check_opaque_meets_bounds<'tcx>(
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
// hidden type is well formed even without those bounds.
let predicate =
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(hidden_ty.into())));
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(hidden_ty.into())));
ocx.register_obligation(Obligation::new(tcx, misc_cause, param_env, predicate));

// Check that all obligations are satisfied by the implementation's
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ fn compare_method_predicate_entailment<'tcx>(
infcx.tcx,
ObligationCause::dummy(),
param_env,
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
unnormalized_impl_fty.into(),
))),
));
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ fn bounds_from_generic_predicates<'tcx>(
debug!("predicate {:?}", predicate);
let bound_predicate = predicate.kind();
match bound_predicate.skip_binder() {
ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => {
ty::PredicateKind::Clause(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::Clause::Projection(projection_pred)) => {
ty::PredicateKind::Clause(ty::ClauseKind::Projection(projection_pred)) => {
projections.push(bound_predicate.rebind(projection_pred));
}
_ => {}
Expand Down
20 changes: 10 additions & 10 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
self.tcx(),
cause,
param_env,
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(arg))),
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg))),
));
}
}
Expand Down Expand Up @@ -419,18 +419,17 @@ 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::Clause::RegionOutlives(ty::OutlivesPredicate(
a,
b,
))) => !region_known_to_outlive(
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::Clause::TypeOutlives(ty::OutlivesPredicate(
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
a,
b,
))) => !ty_known_to_outlive(
Expand Down Expand Up @@ -574,7 +573,7 @@ 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::Clause::TypeOutlives(
let clause = ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
ty::OutlivesPredicate(ty_param, region_param),
));
let clause = tcx.mk_predicate(ty::Binder::dummy(clause));
Expand Down Expand Up @@ -623,7 +622,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
},
);
// The predicate we expect to see.
let clause = ty::PredicateKind::Clause(ty::Clause::RegionOutlives(
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));
Expand Down Expand Up @@ -1032,7 +1031,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
tcx,
cause,
wfcx.param_env,
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(
ty::Const::from_anon_const(tcx, discr_def_id.expect_local()),
))),
));
Expand Down Expand Up @@ -1876,7 +1875,8 @@ 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::Clause::WellFormed(..)) = pred.kind().skip_binder()
if let ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..)) =
pred.kind().skip_binder()
{
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/coherence/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ fn infringing_fields_error(
.or_default()
.push(error.obligation.cause.span);
}
if let ty::PredicateKind::Clause(ty::Clause::Trait(ty::TraitPredicate {
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate {
trait_ref,
polarity: ty::ImplPolarity::Positive,
..
Expand Down