diff options
Diffstat (limited to 'compiler/rustc_trait_selection')
9 files changed, 55 insertions, 50 deletions
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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { } } // 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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::infer::region_constraints::{Constraint, RegionConstraintData}; 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 @@ impl<'tcx> AutoTraitFinder<'tcx> { ty::TraitPredicate { trait_ref, polarity: if polarity { - ImplPolarity::Positive + ty::PredicatePolarity::Positive } else { - ImplPolarity::Negative + ty::PredicatePolarity::Negative }, }, )); @@ -258,7 +258,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { 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 @@ impl<'tcx> InferCtxt<'tcx> { &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 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { 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 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { cause.span, [nested_ty.into(), host_effect_param], ), - polarity: ty::ImplPolarity::Positive, + polarity: ty::PredicatePolarity::Positive, }), &mut nested, ); @@ -1485,7 +1485,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // 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; } |
