From 4b87c0b9c98e6399d62550e3293dfe625841731f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 21 Mar 2024 15:45:28 -0400 Subject: [PATCH 1/4] Split out ImplPolarity and PredicatePolarity --- .../src/type_check/canonical.rs | 2 +- compiler/rustc_hir_analysis/src/bounds.rs | 4 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- .../src/coherence/builtin.rs | 2 +- .../src/collect/predicates_of.rs | 4 +- .../src/hir_ty_lowering/bounds.rs | 8 +-- .../src/hir_ty_lowering/mod.rs | 4 +- .../src/hir_ty_lowering/object_safety.rs | 4 +- compiler/rustc_hir_typeck/src/expr.rs | 2 +- .../rustc_hir_typeck/src/method/suggest.rs | 2 +- .../infer/error_reporting/note_and_explain.rs | 4 +- compiler/rustc_infer/src/traits/mod.rs | 2 +- compiler/rustc_infer/src/traits/util.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 8 +-- compiler/rustc_middle/src/ty/mod.rs | 37 ++++++++++ compiler/rustc_middle/src/ty/predicate.rs | 12 ++-- compiler/rustc_middle/src/ty/print/pretty.rs | 24 +++---- compiler/rustc_middle/src/ty/relate.rs | 14 ++++ .../rustc_smir/src/rustc_smir/convert/ty.rs | 12 ++++ .../src/solve/trait_goals.rs | 68 ++++++++++--------- .../src/traits/auto_trait.rs | 8 +-- .../traits/error_reporting/infer_ctxt_ext.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 6 +- .../src/traits/object_safety.rs | 2 +- .../src/traits/select/candidate_assembly.rs | 2 +- .../src/traits/select/confirmation.rs | 4 +- .../src/traits/select/mod.rs | 11 +-- .../rustc_trait_selection/src/traits/wf.rs | 2 +- compiler/stable_mir/src/ty.rs | 8 ++- 30 files changed, 169 insertions(+), 95 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index a673c4c2aca..f28b786e4f7 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -82,7 +82,7 @@ pub(super) fn prove_trait_ref( ) { 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, diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index d659d2c5235..d5465bb5dd5 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -42,7 +42,7 @@ pub fn push_trait_bound( 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); } @@ -52,7 +52,7 @@ fn push_trait_bound_inner( tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, span: Span, - polarity: ty::ImplPolarity, + polarity: ty::PredicatePolarity, ) { self.clauses.push(( trait_ref diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 2b4a35d0b9b..fe122fbcf08 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -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, diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 8d8b13d6cb3..4d375aed536 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -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() { diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 6d8b257a0f5..efd3ceebe6c 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -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()); } @@ -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()); } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 6f7a788ca6e..11bd3e5282d 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -140,16 +140,16 @@ pub(crate) fn lower_poly_bounds<'hir, I: Iterator { 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, }; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 109e00d4f24..49b092f2276 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -673,7 +673,7 @@ pub(crate) fn lower_poly_trait_ref( 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, @@ -710,7 +710,7 @@ pub(crate) fn lower_poly_trait_ref( // 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::Negative { assert!( self.tcx().dcx().has_errors().is_some(), "negative trait bounds should not have bindings", diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs index c5a36128cff..b5b3a9131c5 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs @@ -43,7 +43,7 @@ pub(super) fn lower_trait_object_ty( &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 @@ -60,7 +60,7 @@ pub(super) fn lower_trait_object_ty( 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) => { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index bd1d7d122d1..e87d8f873b1 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3100,7 +3100,7 @@ fn find_and_report_unsatisfied_index_impl( 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( diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index f3615c03215..e6129e3a008 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -875,7 +875,7 @@ pub fn report_no_match_method_error( 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, } diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index fda3564bdbe..008b75b4c9a 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -306,7 +306,7 @@ fn foo(&self, x: T) -> T { 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 } @@ -420,7 +420,7 @@ fn foo(&self, x: T) -> T { 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(); diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 4808a1defdd..616f5cc0456 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -209,7 +209,7 @@ pub fn new( } impl<'tcx> PolyTraitObligation<'tcx> { - pub fn polarity(&self) -> ty::ImplPolarity { + pub fn polarity(&self) -> ty::PredicatePolarity { self.predicate.skip_binder().polarity } diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index e9df0505cbb..0876a54f16d 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -270,7 +270,7 @@ fn elaborate(&mut self, elaboratable: &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::Negative { return; } // Get predicates implied by the trait, or only super predicates if we only care about self predicates. diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index aff1dc40954..0fc53c6a8b2 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -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, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8a87538e788..3393f444843 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -27,8 +27,8 @@ 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}; @@ -1526,7 +1526,7 @@ fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { nop_slice_lift! {ty::ValTree<'a> => ty::ValTree<'tcx>} TrivialLiftImpls! { - ImplPolarity, Promoted + ImplPolarity, PredicatePolarity, Promoted } macro_rules! sty_debug_print { @@ -1833,7 +1833,7 @@ pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool { return false; }; trait_predicate.trait_ref.def_id == future_trait - && trait_predicate.polarity == ImplPolarity::Positive + && trait_predicate.polarity == PredicatePolarity::Positive }) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6632d980bff..b2fa944b34f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -301,6 +301,43 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } } +impl From for ImplPolarity { + fn from(value: PredicatePolarity) -> Self { + match value { + PredicatePolarity::Positive => ImplPolarity::Positive, + PredicatePolarity::Negative => ImplPolarity::Negative, + } + } +} + +#[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) -> PredicatePolarity { + match self { + PredicatePolarity::Positive => PredicatePolarity::Negative, + PredicatePolarity::Negative => PredicatePolarity::Positive, + } + } +} + +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"), + } + } +} + #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)] #[derive(TypeFoldable, TypeVisitable)] pub enum Asyncness { diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 62822505fa5..d3bc7dd22e7 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -11,7 +11,7 @@ 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>; @@ -70,7 +70,7 @@ pub fn flip_polarity(self, tcx: TyCtxt<'tcx>) -> Option> { polarity, })) => Some(PredicateKind::Clause(ClauseKind::Trait(TraitPredicate { trait_ref, - polarity: polarity.flip()?, + polarity: polarity.flip(), }))), _ => None, @@ -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>>; @@ -693,7 +693,7 @@ pub fn self_ty(self) -> ty::Binder<'tcx, Ty<'tcx>> { } #[inline] - pub fn polarity(self) -> ImplPolarity { + pub fn polarity(self) -> PredicatePolarity { self.skip_binder().polarity } } @@ -907,7 +907,7 @@ fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'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 } } } @@ -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, }) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 995b439d10a..bf339a878dd 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -995,11 +995,11 @@ fn pretty_print_opaque_impl_type( // Don't print `+ Sized`, but rather `+ ?Sized` if absent. if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() { match pred.polarity { - ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => { + ty::PredicatePolarity::Positive => { has_sized_bound = true; continue; } - ty::ImplPolarity::Negative => has_negative_sized_bound = true, + ty::PredicatePolarity::Negative => has_negative_sized_bound = true, } } @@ -1020,7 +1020,7 @@ fn pretty_print_opaque_impl_type( self.insert_trait_and_projection( trait_ref, - ty::ImplPolarity::Positive, + ty::PredicatePolarity::Positive, Some(proj_ty), &mut traits, &mut fn_traits, @@ -1085,7 +1085,7 @@ fn pretty_print_opaque_impl_type( _ => { if entry.has_fn_once { traits - .entry((fn_once_trait_ref, ty::ImplPolarity::Positive)) + .entry((fn_once_trait_ref, ty::PredicatePolarity::Positive)) .or_default() .extend( // Group the return ty with its def id, if we had one. @@ -1095,10 +1095,10 @@ fn pretty_print_opaque_impl_type( ); } if let Some(trait_ref) = entry.fn_mut_trait_ref { - traits.entry((trait_ref, ty::ImplPolarity::Positive)).or_default(); + traits.entry((trait_ref, ty::PredicatePolarity::Positive)).or_default(); } if let Some(trait_ref) = entry.fn_trait_ref { - traits.entry((trait_ref, ty::ImplPolarity::Positive)).or_default(); + traits.entry((trait_ref, ty::PredicatePolarity::Positive)).or_default(); } } } @@ -1114,7 +1114,7 @@ fn pretty_print_opaque_impl_type( self.wrap_binder(&trait_ref, |trait_ref, cx| { define_scoped_cx!(cx); - if polarity == ty::ImplPolarity::Negative { + if polarity == ty::PredicatePolarity::Negative { p!("!"); } p!(print(trait_ref.print_only_trait_name())); @@ -1223,10 +1223,10 @@ fn pretty_print_opaque_impl_type( fn insert_trait_and_projection( &mut self, trait_ref: ty::PolyTraitRef<'tcx>, - polarity: ty::ImplPolarity, + polarity: ty::PredicatePolarity, proj_ty: Option<(DefId, ty::Binder<'tcx, Term<'tcx>>)>, traits: &mut FxIndexMap< - (ty::PolyTraitRef<'tcx>, ty::ImplPolarity), + (ty::PolyTraitRef<'tcx>, ty::PredicatePolarity), FxIndexMap>>, >, fn_traits: &mut FxIndexMap, OpaqueFnEntry<'tcx>>, @@ -1236,7 +1236,7 @@ fn insert_trait_and_projection( // If our trait_ref is FnOnce or any of its children, project it onto the parent FnOnce // super-trait ref and record it there. // We skip negative Fn* bounds since they can't use parenthetical notation anyway. - if polarity == ty::ImplPolarity::Positive + if polarity == ty::PredicatePolarity::Positive && let Some(fn_once_trait) = self.tcx().lang_items().fn_once_trait() { // If we have a FnOnce, then insert it into @@ -3139,7 +3139,7 @@ macro_rules! define_print_and_forward_display { TraitPredPrintModifiersAndPath<'tcx> { p!(pretty_print_bound_constness(self.0.trait_ref)); - if let ty::ImplPolarity::Negative = self.0.polarity { + if let ty::PredicatePolarity::Negative = self.0.polarity { p!("!") } p!(print(self.0.trait_ref.print_only_trait_path())); @@ -3172,7 +3172,7 @@ macro_rules! define_print_and_forward_display { ty::TraitPredicate<'tcx> { p!(print(self.trait_ref.self_ty()), ": "); p!(pretty_print_bound_constness(self.trait_ref)); - if let ty::ImplPolarity::Negative = self.polarity { + if let ty::PredicatePolarity::Negative = self.polarity { p!("!"); } p!(print(self.trait_ref.print_trait_sugared())) diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 990e78aff8a..cb43ae93c8d 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -779,6 +779,20 @@ fn relate>( } } +impl<'tcx> Relate<'tcx> for ty::PredicatePolarity { + fn relate>( + _relation: &mut R, + a: ty::PredicatePolarity, + b: ty::PredicatePolarity, + ) -> RelateResult<'tcx, ty::PredicatePolarity> { + if a != b { + Err(TypeError::PolarityMismatch(expected_found(a.into(), b.into()))) + } else { + Ok(a) + } + } +} + impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> { fn relate>( relation: &mut R, diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 84c6cbf178b..bcf65d74f11 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -719,6 +719,18 @@ fn stable(&self, _: &mut Tables<'_>) -> Self::T { } } +impl<'tcx> Stable<'tcx> for ty::PredicatePolarity { + type T = stable_mir::ty::PredicatePolarity; + + fn stable(&self, _: &mut Tables<'_>) -> Self::T { + use rustc_middle::ty::PredicatePolarity::*; + match self { + Positive => stable_mir::ty::PredicatePolarity::Positive, + Negative => stable_mir::ty::PredicatePolarity::Negative, + } + } +} + impl<'tcx> Stable<'tcx> for ty::Region<'tcx> { type T = stable_mir::ty::Region; diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 184ba31f19d..a019254283e 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -55,17 +55,23 @@ fn consider_impl_candidate( // An upper bound of the certainty of this goal, used to lower the certainty // of reservation impl to ambiguous during coherence. let impl_polarity = impl_trait_header.polarity; - let maximal_certainty = match impl_polarity { - ty::ImplPolarity::Positive | ty::ImplPolarity::Negative => { - match impl_polarity == goal.predicate.polarity { - true => Certainty::Yes, - false => return Err(NoSolution), - } - } - ty::ImplPolarity::Reservation => match ecx.solver_mode() { - SolverMode::Normal => return Err(NoSolution), + let maximal_certainty = match (impl_polarity, goal.predicate.polarity) { + // In intercrate mode, this is ambiguous. But outside of intercrate, + // it's not a real impl. + (ty::ImplPolarity::Reservation, _) => match ecx.solver_mode() { SolverMode::Coherence => Certainty::AMBIGUOUS, + SolverMode::Normal => return Err(NoSolution), }, + + // Impl matches polarity + (ty::ImplPolarity::Positive, ty::PredicatePolarity::Positive) + | (ty::ImplPolarity::Negative, ty::PredicatePolarity::Negative) => Certainty::Yes, + + // Impl doesn't match polarity + (ty::ImplPolarity::Positive, ty::PredicatePolarity::Negative) + | (ty::ImplPolarity::Negative, ty::PredicatePolarity::Positive) => { + return Err(NoSolution); + } }; ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { @@ -123,7 +129,7 @@ fn consider_auto_trait_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -168,7 +174,7 @@ fn consider_trait_alias_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -191,7 +197,7 @@ fn consider_builtin_sized_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -205,7 +211,7 @@ fn consider_builtin_copy_clone_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -219,7 +225,7 @@ fn consider_builtin_pointer_like_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -251,7 +257,7 @@ fn consider_builtin_fn_ptr_trait_candidate( let self_ty = goal.predicate.self_ty(); match goal.predicate.polarity { // impl FnPtr for FnPtr {} - ty::ImplPolarity::Positive => { + ty::PredicatePolarity::Positive => { if self_ty.is_fn_ptr() { ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } else { @@ -259,7 +265,7 @@ fn consider_builtin_fn_ptr_trait_candidate( } } // impl !FnPtr for T where T != FnPtr && T is rigid {} - ty::ImplPolarity::Negative => { + ty::PredicatePolarity::Negative => { // If a type is rigid and not a fn ptr, then we know for certain // that it does *not* implement `FnPtr`. if !self_ty.is_fn_ptr() && self_ty.is_known_rigid() { @@ -268,10 +274,6 @@ fn consider_builtin_fn_ptr_trait_candidate( Err(NoSolution) } } - // FIXME: Goal polarity should be split from impl polarity - ty::ImplPolarity::Reservation => { - bug!("we never expect a `Reservation` polarity in a trait goal") - } } } @@ -280,7 +282,7 @@ fn consider_builtin_fn_trait_candidates( goal: Goal<'tcx, Self>, goal_kind: ty::ClosureKind, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -316,7 +318,7 @@ fn consider_builtin_async_fn_trait_candidates( goal: Goal<'tcx, Self>, goal_kind: ty::ClosureKind, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -386,7 +388,7 @@ fn consider_builtin_tuple_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -401,7 +403,7 @@ fn consider_builtin_pointee_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -412,7 +414,7 @@ fn consider_builtin_future_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -436,7 +438,7 @@ fn consider_builtin_iterator_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -460,7 +462,7 @@ fn consider_builtin_fused_iterator_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -482,7 +484,7 @@ fn consider_builtin_async_iterator_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -506,7 +508,7 @@ fn consider_builtin_coroutine_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -537,7 +539,7 @@ fn consider_builtin_discriminant_kind_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -549,7 +551,7 @@ fn consider_builtin_destruct_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -564,7 +566,7 @@ fn consider_builtin_transmute_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); } @@ -601,7 +603,7 @@ fn consider_structural_builtin_unsize_candidates( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> Vec<(CanonicalResponse<'tcx>, BuiltinImplSource)> { - if goal.predicate.polarity != ty::ImplPolarity::Positive { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { return vec![]; } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 0796ffcbc45..5a12e24a165 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -8,7 +8,7 @@ use crate::traits::project::ProjectAndUnifyResult; use rustc_infer::infer::DefineOpaqueTypes; use rustc_middle::mir::interpret::ErrorHandled; -use rustc_middle::ty::{ImplPolarity, Region, RegionVid}; +use rustc_middle::ty::{Region, RegionVid}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; @@ -96,9 +96,9 @@ pub fn find_auto_trait_generics( ty::TraitPredicate { trait_ref, polarity: if polarity { - ImplPolarity::Positive + ty::PredicatePolarity::Positive } else { - ImplPolarity::Negative + ty::PredicatePolarity::Negative }, }, )); @@ -258,7 +258,7 @@ fn evaluate_predicates( trait_ref: ty::TraitRef::new(infcx.tcx, trait_did, [ty]), // Auto traits are positive - polarity: ty::ImplPolarity::Positive, + polarity: ty::PredicatePolarity::Positive, })); let computed_preds = param_env.caller_bounds().iter().map(|c| c.as_predicate()); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs index cbe2ec0f0eb..6c6c8ca1d9f 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs @@ -206,7 +206,7 @@ fn type_implements_fn_trait( &self, param_env: ty::ParamEnv<'tcx>, ty: ty::Binder<'tcx, Ty<'tcx>>, - polarity: ty::ImplPolarity, + polarity: ty::PredicatePolarity, ) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()> { self.commit_if_ok(|_| { for trait_def_id in [ diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 00d00496947..ca54207f618 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -245,7 +245,7 @@ fn suggest_restricting_param_bound( associated_ty: Option<(&'static str, Ty<'tcx>)>, mut body_id: LocalDefId, ) { - if trait_pred.skip_binder().polarity == ty::ImplPolarity::Negative { + if trait_pred.skip_binder().polarity == ty::PredicatePolarity::Negative { return; } @@ -4057,7 +4057,7 @@ fn look_for_iterator_item_mistakes( span, [*ty], ), - polarity: ty::ImplPolarity::Positive, + polarity: ty::PredicatePolarity::Positive, }); let Some(generics) = node.generics() else { continue; @@ -4802,7 +4802,7 @@ pub(super) fn get_explanation_based_on_obligation<'tcx>( Some(desc) => format!(" {desc}"), None => String::new(), }; - if let ty::ImplPolarity::Positive = trait_predicate.polarity() { + if let ty::PredicatePolarity::Positive = trait_predicate.polarity() { format!( "{pre_message}the trait `{}` is not implemented for{desc} `{}`{post}", trait_predicate.print_modifiers_and_trait_path(), diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 5efb41f2bd8..5e1343b50ce 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -584,7 +584,7 @@ fn virtual_call_violations_for_method<'tcx>( // implement auto traits if the underlying type does as well. if let ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref: pred_trait_ref, - polarity: ty::ImplPolarity::Positive, + polarity: ty::PredicatePolarity::Positive, }) = pred.kind().skip_binder() && pred_trait_ref.self_ty() == tcx.types.self_param && tcx.trait_is_auto(pred_trait_ref.def_id) diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 9fb4577fb21..7a38a25f7f5 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -56,7 +56,7 @@ pub(super) fn assemble_candidates<'o>( let mut candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false }; // Negative trait predicates have different rules than positive trait predicates. - if obligation.polarity() == ty::ImplPolarity::Negative { + if obligation.polarity() == ty::PredicatePolarity::Negative { self.assemble_candidates_for_trait_alias(obligation, &mut candidates); self.assemble_candidates_from_impls(obligation, &mut candidates); self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?; diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index eca36fc343e..a9e6a3686f1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1460,7 +1460,7 @@ fn confirm_const_destruct_candidate( cause.span, [nested_ty.into(), host_effect_param], ), - polarity: ty::ImplPolarity::Positive, + polarity: ty::PredicatePolarity::Positive, }), &mut nested, ); @@ -1485,7 +1485,7 @@ fn confirm_const_destruct_candidate( cause.span, [nested_ty.into(), host_effect_param], ), - polarity: ty::ImplPolarity::Positive, + polarity: ty::PredicatePolarity::Positive, }); nested.push(Obligation::with_depth( diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index adbc7d12a64..45517498066 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1418,10 +1418,13 @@ fn filter_impls( for candidate in candidates { if let ImplCandidate(def_id) = candidate { - if ty::ImplPolarity::Reservation == tcx.impl_polarity(def_id) - || obligation.polarity() == tcx.impl_polarity(def_id) - { - result.push(candidate); + match (tcx.impl_polarity(def_id), obligation.polarity()) { + (ty::ImplPolarity::Reservation, _) + | (ty::ImplPolarity::Positive, ty::PredicatePolarity::Positive) + | (ty::ImplPolarity::Negative, ty::PredicatePolarity::Negative) => { + result.push(candidate); + } + _ => {} } } else { result.push(candidate); diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 64f02bfd321..60bbc408ba6 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -363,7 +363,7 @@ fn compute_trait_pred(&mut self, trait_pred: ty::TraitPredicate<'tcx>, elaborate // Negative trait predicates don't require supertraits to hold, just // that their args are WF. - if trait_pred.polarity == ty::ImplPolarity::Negative { + if trait_pred.polarity == ty::PredicatePolarity::Negative { self.compute_negative_trait_pred(trait_ref); return; } diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index a3376752028..21db222095f 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -1332,7 +1332,7 @@ pub enum AliasRelationDirection { #[derive(Clone, Debug, Eq, PartialEq)] pub struct TraitPredicate { pub trait_ref: TraitRef, - pub polarity: ImplPolarity, + pub polarity: PredicatePolarity, } #[derive(Clone, Debug, Eq, PartialEq)] @@ -1354,6 +1354,12 @@ pub enum ImplPolarity { Reservation, } +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum PredicatePolarity { + Positive, + Negative, +} + pub trait IndexedVal { fn to_val(index: usize) -> Self; From 127e42d33b21f05a7d1f2b1925fa28cf37e496c5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 21 Mar 2024 15:46:40 -0400 Subject: [PATCH 2/4] Use != Positive rather than == Negative Feels more complete, and for ImplPolarity has the side-effect of making sure we also handle reservation impls correctly --- compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 2 +- compiler/rustc_hir_typeck/src/method/suggest.rs | 2 +- compiler/rustc_infer/src/traits/util.rs | 2 +- compiler/rustc_trait_selection/src/traits/auto_trait.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 2 +- .../src/traits/error_reporting/type_err_ctxt_ext.rs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 49b092f2276..6307b3ab6b2 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -710,7 +710,7 @@ pub(crate) fn lower_poly_trait_ref( // 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::PredicatePolarity::Negative { + if polarity != ty::PredicatePolarity::Positive { assert!( self.tcx().dcx().has_errors().is_some(), "negative trait bounds should not have bindings", diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index e6129e3a008..6a645d346ea 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3367,7 +3367,7 @@ enum Introducer { "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 = diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 0876a54f16d..6d43011d33c 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -270,7 +270,7 @@ fn elaborate(&mut self, elaboratable: &O) { match bound_clause.skip_binder() { ty::ClauseKind::Trait(data) => { // Negative trait bounds do not imply any supertrait bounds - if data.polarity == ty::PredicatePolarity::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. diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 5a12e24a165..c909a0b49e2 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -295,7 +295,7 @@ fn evaluate_predicates( }) = impl_source { // Blame 'tidy' for the weird bracket placement. - if infcx.tcx.impl_polarity(*impl_def_id) == ty::ImplPolarity::Negative { + if infcx.tcx.impl_polarity(*impl_def_id) != ty::ImplPolarity::Positive { debug!( "evaluate_nested_obligations: found explicit negative impl\ {:?}, bailing out", diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index ca54207f618..729bbd56fc5 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -245,7 +245,7 @@ fn suggest_restricting_param_bound( associated_ty: Option<(&'static str, Ty<'tcx>)>, mut body_id: LocalDefId, ) { - if trait_pred.skip_binder().polarity == ty::PredicatePolarity::Negative { + if trait_pred.skip_binder().polarity != ty::PredicatePolarity::Positive { return; } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 4bc3ff92a67..ac5c54bfb79 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -1907,7 +1907,7 @@ fn find_similar_impl_candidates( .all_impls(trait_pred.def_id()) .filter_map(|def_id| { let imp = self.tcx.impl_trait_header(def_id).unwrap(); - if imp.polarity == ty::ImplPolarity::Negative + if imp.polarity != ty::ImplPolarity::Positive || !self.tcx.is_user_visible_dep(def_id.krate) { return None; From 560c6cc6026d653270c57a3cc00e2a4406e3d5fa Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 21 Mar 2024 15:49:17 -0400 Subject: [PATCH 3/4] Fix clippy --- src/tools/clippy/clippy_lints/src/derive.rs | 4 ++-- src/tools/clippy/clippy_lints/src/eta_reduction.rs | 4 ++-- .../clippy/clippy_lints/src/methods/unnecessary_to_owned.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index f0f2c7d6658..c554edc8fce 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -11,7 +11,7 @@ use rustc_middle::hir::nested_filter; use rustc_middle::traits::Reveal; use rustc_middle::ty::{ - self, ClauseKind, GenericArgKind, GenericParamDefKind, ImplPolarity, ParamEnv, ToPredicate, TraitPredicate, Ty, + self, ClauseKind, GenericArgKind, GenericParamDefKind, ParamEnv, ToPredicate, TraitPredicate, Ty, TyCtxt, }; use rustc_session::declare_lint_pass; @@ -502,7 +502,7 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { ClauseKind::Trait(TraitPredicate { trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]), - polarity: ImplPolarity::Positive, + polarity: ty::PredicatePolarity::Positive, }) .to_predicate(tcx) }), diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index 40be71a0e5d..eccfc31fdd3 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -9,7 +9,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{ - self, Binder, ClosureArgs, ClosureKind, FnSig, GenericArg, GenericArgKind, ImplPolarity, List, Region, RegionKind, + self, Binder, ClosureArgs, ClosureKind, FnSig, GenericArg, GenericArgKind, List, Region, RegionKind, Ty, TypeVisitableExt, TypeckResults, }; use rustc_session::declare_lint_pass; @@ -173,7 +173,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let Ok((ClosureKind::FnMut, _)) = cx.tcx.infer_ctxt().build().type_implements_fn_trait( cx.param_env, Binder::bind_with_vars(callee_ty_adjusted, List::empty()), - ImplPolarity::Positive, + ty::PredicatePolarity::Positive, ) && path_to_local(callee).map_or(false, |l| { local_used_in(cx, l, args) || local_used_after_expr(cx, l, expr) }) { diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index c234e4f9b11..abf717126fb 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -18,7 +18,7 @@ use rustc_middle::mir::Mutability; use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref}; use rustc_middle::ty::{ - self, ClauseKind, GenericArg, GenericArgKind, GenericArgsRef, ImplPolarity, ParamTy, ProjectionPredicate, + self, ClauseKind, GenericArg, GenericArgKind, GenericArgsRef, ParamTy, ProjectionPredicate, TraitPredicate, Ty, }; use rustc_span::{sym, Symbol}; @@ -669,7 +669,7 @@ fn check_borrow_predicate<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { && let Some(borrow_id) = cx.tcx.get_diagnostic_item(sym::Borrow) && cx.tcx.predicates_of(method_def_id).predicates.iter().any(|(pred, _)| { if let ClauseKind::Trait(trait_pred) = pred.kind().skip_binder() - && trait_pred.polarity == ImplPolarity::Positive + && trait_pred.polarity == ty::PredicatePolarity::Positive && trait_pred.trait_ref.def_id == borrow_id { true From d677a2d73b87926c5fa359b47830de39ab0e9626 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 21 Mar 2024 15:53:21 -0400 Subject: [PATCH 4/4] Further simplifications --- compiler/rustc_middle/src/ty/error.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 23 +++-------------------- compiler/rustc_middle/src/ty/relate.rs | 16 +--------------- 3 files changed, 5 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index e15f0378846..a2d674b9c44 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -32,7 +32,7 @@ pub fn new(a_is_expected: bool, a: T, b: T) -> Self { pub enum TypeError<'tcx> { Mismatch, ConstnessMismatch(ExpectedFound), - PolarityMismatch(ExpectedFound), + PolarityMismatch(ExpectedFound), UnsafetyMismatch(ExpectedFound), AbiMismatch(ExpectedFound), Mutability, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b2fa944b34f..6ce53ccc8cd 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -280,17 +280,6 @@ pub enum ImplPolarity { Reservation, } -impl ImplPolarity { - /// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`. - pub fn flip(&self) -> Option { - match self { - ImplPolarity::Positive => Some(ImplPolarity::Negative), - ImplPolarity::Negative => Some(ImplPolarity::Positive), - ImplPolarity::Reservation => None, - } - } -} - impl fmt::Display for ImplPolarity { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -301,15 +290,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } } -impl From for ImplPolarity { - fn from(value: PredicatePolarity) -> Self { - match value { - PredicatePolarity::Positive => ImplPolarity::Positive, - PredicatePolarity::Negative => ImplPolarity::Negative, - } - } -} - +/// 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 { diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index cb43ae93c8d..f523fd7b75a 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -769,27 +769,13 @@ fn relate>( } } -impl<'tcx> Relate<'tcx> for ty::ImplPolarity { - fn relate>( - _relation: &mut R, - a: ty::ImplPolarity, - b: ty::ImplPolarity, - ) -> RelateResult<'tcx, ty::ImplPolarity> { - if a != b { Err(TypeError::PolarityMismatch(expected_found(a, b))) } else { Ok(a) } - } -} - impl<'tcx> Relate<'tcx> for ty::PredicatePolarity { fn relate>( _relation: &mut R, a: ty::PredicatePolarity, b: ty::PredicatePolarity, ) -> RelateResult<'tcx, ty::PredicatePolarity> { - if a != b { - Err(TypeError::PolarityMismatch(expected_found(a.into(), b.into()))) - } else { - Ok(a) - } + if a != b { Err(TypeError::PolarityMismatch(expected_found(a, b))) } else { Ok(a) } } }