Skip to content

Commit

Permalink
Rollup merge of #122839 - compiler-errors:predicate-polarity, r=lcnr
Browse files Browse the repository at this point in the history
Split out `PredicatePolarity` from `ImplPolarity`

Because having to deal with a third `Reservation` level in all the trait solver code is kind of weird.

r? `@lcnr` or `@oli-obk`
  • Loading branch information
matthiaskrgr authored Mar 22, 2024
2 parents 96be3e7 + d677a2d commit 8030692
Show file tree
Hide file tree
Showing 35 changed files with 159 additions and 116 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/type_check/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
) {
self.prove_predicate(
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::Trait(
ty::TraitPredicate { trait_ref, polarity: ty::ImplPolarity::Positive },
ty::TraitPredicate { trait_ref, polarity: ty::PredicatePolarity::Positive },
))),
locations,
category,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl<'tcx> Bounds<'tcx> {
tcx: TyCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
span: Span,
polarity: ty::ImplPolarity,
polarity: ty::PredicatePolarity,
) {
self.push_trait_bound_inner(tcx, trait_ref, span, polarity);
}
Expand All @@ -52,7 +52,7 @@ impl<'tcx> Bounds<'tcx> {
tcx: TyCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
span: Span,
polarity: ty::ImplPolarity,
polarity: ty::PredicatePolarity,
) {
self.clauses.push((
trait_ref
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1322,7 +1322,7 @@ fn check_impl<'tcx>(
trait_ref,
);
let trait_pred =
ty::TraitPredicate { trait_ref, polarity: ty::ImplPolarity::Positive };
ty::TraitPredicate { trait_ref, polarity: ty::PredicatePolarity::Positive };
let mut obligations = traits::wf::trait_obligations(
wfcx.infcx,
wfcx.param_env,
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 @@ -551,7 +551,7 @@ fn infringing_fields_error(
}
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate {
trait_ref,
polarity: ty::ImplPolarity::Positive,
polarity: ty::PredicatePolarity::Positive,
..
})) = error_predicate.kind().skip_binder()
{
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ pub(super) fn implied_predicates_with_filter(
for &(pred, span) in implied_bounds {
debug!("superbound: {:?}", pred);
if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
&& bound.polarity == ty::ImplPolarity::Positive
&& bound.polarity == ty::PredicatePolarity::Positive
{
tcx.at(span).super_predicates_of(bound.def_id());
}
Expand All @@ -634,7 +634,7 @@ pub(super) fn implied_predicates_with_filter(
for &(pred, span) in implied_bounds {
debug!("superbound: {:?}", pred);
if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
&& bound.polarity == ty::ImplPolarity::Positive
&& bound.polarity == ty::PredicatePolarity::Positive
{
tcx.at(span).implied_predicates_of(bound.def_id());
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
hir::GenericBound::Trait(poly_trait_ref, modifier) => {
let (constness, polarity) = match modifier {
hir::TraitBoundModifier::Const => {
(ty::BoundConstness::Const, ty::ImplPolarity::Positive)
(ty::BoundConstness::Const, ty::PredicatePolarity::Positive)
}
hir::TraitBoundModifier::MaybeConst => {
(ty::BoundConstness::ConstIfConst, ty::ImplPolarity::Positive)
(ty::BoundConstness::ConstIfConst, ty::PredicatePolarity::Positive)
}
hir::TraitBoundModifier::None => {
(ty::BoundConstness::NotConst, ty::ImplPolarity::Positive)
(ty::BoundConstness::NotConst, ty::PredicatePolarity::Positive)
}
hir::TraitBoundModifier::Negative => {
(ty::BoundConstness::NotConst, ty::ImplPolarity::Negative)
(ty::BoundConstness::NotConst, ty::PredicatePolarity::Negative)
}
hir::TraitBoundModifier::Maybe => continue,
};
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
trait_ref: &hir::TraitRef<'tcx>,
span: Span,
constness: ty::BoundConstness,
polarity: ty::ImplPolarity,
polarity: ty::PredicatePolarity,
self_ty: Ty<'tcx>,
bounds: &mut Bounds<'tcx>,
only_self_bounds: OnlySelfBounds,
Expand Down Expand Up @@ -710,7 +710,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// Don't register additional associated type bounds for negative bounds,
// since we should have emitten an error for them earlier, and they will
// not be well-formed!
if polarity == ty::ImplPolarity::Negative {
if polarity != ty::PredicatePolarity::Positive {
assert!(
self.tcx().dcx().has_errors().is_some(),
"negative trait bounds should not have bindings",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
&trait_bound.trait_ref,
trait_bound.span,
ty::BoundConstness::NotConst,
ty::ImplPolarity::Positive,
ty::PredicatePolarity::Positive,
dummy_self,
&mut bounds,
// True so we don't populate `bounds` with associated type bounds, even
Expand All @@ -60,7 +60,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let bound_pred = pred.kind();
match bound_pred.skip_binder() {
ty::ClauseKind::Trait(trait_pred) => {
assert_eq!(trait_pred.polarity, ty::ImplPolarity::Positive);
assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive);
trait_bounds.push((bound_pred.rebind(trait_pred.trait_ref), span));
}
ty::ClauseKind::Projection(proj) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3100,7 +3100,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
cause.clone().derived_cause(
ty::Binder::dummy(ty::TraitPredicate {
trait_ref: impl_trait_ref,
polarity: ty::ImplPolarity::Positive,
polarity: ty::PredicatePolarity::Positive,
}),
|derived| {
traits::ImplDerivedObligation(Box::new(
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match pred.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
Some(pred.def_id()) == self.tcx.lang_items().sized_trait()
&& pred.polarity == ty::ImplPolarity::Positive
&& pred.polarity == ty::PredicatePolarity::Positive
}
_ => false,
}
Expand Down Expand Up @@ -3367,7 +3367,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"inherent impls can't be candidates, only trait impls can be",
)
})
.filter(|header| header.polarity == ty::ImplPolarity::Negative)
.filter(|header| header.polarity != ty::ImplPolarity::Positive)
.any(|header| {
let imp = header.trait_ref.instantiate_identity();
let imp_simp =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ impl<T> Trait<T> for X {
.any(|(pred, _span)| match pred.kind().skip_binder() {
ty::ClauseKind::Trait(trait_predicate)
if trait_predicate.polarity
== ty::ImplPolarity::Positive =>
== ty::PredicatePolarity::Positive =>
{
trait_predicate.def_id() == def_id
}
Expand Down Expand Up @@ -420,7 +420,7 @@ impl<T> Trait<T> for X {
else {
continue;
};
if trait_predicate.polarity != ty::ImplPolarity::Positive {
if trait_predicate.polarity != ty::PredicatePolarity::Positive {
continue;
}
let def_id = trait_predicate.def_id();
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ impl<'tcx> FulfillmentError<'tcx> {
}

impl<'tcx> PolyTraitObligation<'tcx> {
pub fn polarity(&self) -> ty::ImplPolarity {
pub fn polarity(&self) -> ty::PredicatePolarity {
self.predicate.skip_binder().polarity
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
match bound_clause.skip_binder() {
ty::ClauseKind::Trait(data) => {
// Negative trait bounds do not imply any supertrait bounds
if data.polarity == ty::ImplPolarity::Negative {
if data.polarity != ty::PredicatePolarity::Positive {
return;
}
// Get predicates implied by the trait, or only super predicates if we only care about self predicates.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ fn type_implements_negative_copy_modulo_regions<'tcx>(
param_env: ty::ParamEnv<'tcx>,
) -> bool {
let trait_ref = ty::TraitRef::new(tcx, tcx.require_lang_item(hir::LangItem::Copy, None), [ty]);
let pred = ty::TraitPredicate { trait_ref, polarity: ty::ImplPolarity::Negative };
let pred = ty::TraitPredicate { trait_ref, polarity: ty::PredicatePolarity::Negative };
let obligation = traits::Obligation {
cause: traits::ObligationCause::dummy(),
param_env,
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ use crate::traits::solve::{
use crate::ty::{
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind,
ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate,
PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
TypeVisitable, Visibility,
PredicateKind, PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty,
TyKind, TyVid, TypeVisitable, Visibility,
};
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
use rustc_ast::{self as ast, attr};
Expand Down Expand Up @@ -1526,7 +1526,7 @@ macro_rules! nop_slice_lift {
nop_slice_lift! {ty::ValTree<'a> => ty::ValTree<'tcx>}

TrivialLiftImpls! {
ImplPolarity, Promoted
ImplPolarity, PredicatePolarity, Promoted
}

macro_rules! sty_debug_print {
Expand Down Expand Up @@ -1833,7 +1833,7 @@ impl<'tcx> TyCtxt<'tcx> {
return false;
};
trait_predicate.trait_ref.def_id == future_trait
&& trait_predicate.polarity == ImplPolarity::Positive
&& trait_predicate.polarity == PredicatePolarity::Positive
})
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl<T> ExpectedFound<T> {
pub enum TypeError<'tcx> {
Mismatch,
ConstnessMismatch(ExpectedFound<ty::BoundConstness>),
PolarityMismatch(ExpectedFound<ty::ImplPolarity>),
PolarityMismatch(ExpectedFound<ty::PredicatePolarity>),
UnsafetyMismatch(ExpectedFound<hir::Unsafety>),
AbiMismatch(ExpectedFound<abi::Abi>),
Mutability,
Expand Down
34 changes: 27 additions & 7 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,23 +280,43 @@ pub enum ImplPolarity {
Reservation,
}

impl ImplPolarity {
impl fmt::Display for ImplPolarity {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Positive => f.write_str("positive"),
Self::Negative => f.write_str("negative"),
Self::Reservation => f.write_str("reservation"),
}
}
}

/// Polarity for a trait predicate. May either be negative or positive.
/// Distinguished from [`ImplPolarity`] since we never compute goals with
/// "reservation" level.
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)]
#[derive(TypeFoldable, TypeVisitable)]
pub enum PredicatePolarity {
/// `Type: Trait`
Positive,
/// `Type: !Trait`
Negative,
}

impl PredicatePolarity {
/// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`.
pub fn flip(&self) -> Option<ImplPolarity> {
pub fn flip(&self) -> PredicatePolarity {
match self {
ImplPolarity::Positive => Some(ImplPolarity::Negative),
ImplPolarity::Negative => Some(ImplPolarity::Positive),
ImplPolarity::Reservation => None,
PredicatePolarity::Positive => PredicatePolarity::Negative,
PredicatePolarity::Negative => PredicatePolarity::Positive,
}
}
}

impl fmt::Display for ImplPolarity {
impl fmt::Display for PredicatePolarity {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Positive => f.write_str("positive"),
Self::Negative => f.write_str("negative"),
Self::Reservation => f.write_str("reservation"),
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_middle/src/ty/predicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::cmp::Ordering;
use crate::ty::visit::TypeVisitableExt;
use crate::ty::{
self, AliasTy, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder, GenericArg, GenericArgs,
GenericArgsRef, ImplPolarity, Term, Ty, TyCtxt, TypeFlags, WithCachedTypeInfo,
GenericArgsRef, PredicatePolarity, Term, Ty, TyCtxt, TypeFlags, WithCachedTypeInfo,
};

pub type ClauseKind<'tcx> = IrClauseKind<TyCtxt<'tcx>>;
Expand Down Expand Up @@ -70,7 +70,7 @@ impl<'tcx> Predicate<'tcx> {
polarity,
})) => Some(PredicateKind::Clause(ClauseKind::Trait(TraitPredicate {
trait_ref,
polarity: polarity.flip()?,
polarity: polarity.flip(),
}))),

_ => None,
Expand Down Expand Up @@ -663,7 +663,7 @@ pub struct TraitPredicate<'tcx> {
/// exist via a series of predicates.)
///
/// If polarity is Reserved: that's a bug.
pub polarity: ImplPolarity,
pub polarity: PredicatePolarity,
}

pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
Expand Down Expand Up @@ -693,7 +693,7 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
}

#[inline]
pub fn polarity(self) -> ImplPolarity {
pub fn polarity(self) -> PredicatePolarity {
self.skip_binder().polarity
}
}
Expand Down Expand Up @@ -907,7 +907,7 @@ impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
impl<'tcx> ToPredicate<'tcx, TraitPredicate<'tcx>> for TraitRef<'tcx> {
#[inline(always)]
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> TraitPredicate<'tcx> {
TraitPredicate { trait_ref: self, polarity: ImplPolarity::Positive }
TraitPredicate { trait_ref: self, polarity: PredicatePolarity::Positive }
}
}

Expand Down Expand Up @@ -940,7 +940,7 @@ impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for Binder<'tcx, TraitRef
fn to_predicate(self, _: TyCtxt<'tcx>) -> PolyTraitPredicate<'tcx> {
self.map_bound(|trait_ref| TraitPredicate {
trait_ref,
polarity: ty::ImplPolarity::Positive,
polarity: ty::PredicatePolarity::Positive,
})
}
}
Expand Down
Loading

0 comments on commit 8030692

Please sign in to comment.