Skip to content

Commit 794cb89

Browse files
Consider polarity in new solver
1 parent b72460f commit 794cb89

File tree

2 files changed

+74
-3
lines changed

2 files changed

+74
-3
lines changed

compiler/rustc_middle/src/ty/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,11 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
861861
pub fn is_const_if_const(self) -> bool {
862862
self.skip_binder().is_const_if_const()
863863
}
864+
865+
#[inline]
866+
pub fn polarity(self) -> ImplPolarity {
867+
self.skip_binder().polarity
868+
}
864869
}
865870

866871
/// `A: B`

compiler/rustc_trait_selection/src/solve/trait_goals.rs

+69-3
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
8686
) -> QueryResult<'tcx> {
8787
if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred()
8888
&& poly_trait_pred.def_id() == goal.predicate.def_id()
89+
&& poly_trait_pred.polarity() == goal.predicate.polarity
8990
{
90-
// FIXME: Constness and polarity
91+
// FIXME: Constness
9192
ecx.probe(|ecx| {
9293
let assumption_trait_pred =
9394
ecx.instantiate_binder_with_infer(poly_trait_pred);
@@ -111,6 +112,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
111112
) -> QueryResult<'tcx> {
112113
if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred()
113114
&& poly_trait_pred.def_id() == goal.predicate.def_id()
115+
&& poly_trait_pred.polarity() == goal.predicate.polarity
114116
{
115117
// FIXME: Constness and polarity
116118
ecx.probe(|ecx| {
@@ -147,6 +149,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
147149
ecx: &mut EvalCtxt<'_, 'tcx>,
148150
goal: Goal<'tcx, Self>,
149151
) -> QueryResult<'tcx> {
152+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
153+
return Err(NoSolution);
154+
}
155+
150156
if let Some(result) = ecx.disqualify_auto_trait_candidate_due_to_possible_impl(goal) {
151157
return result;
152158
}
@@ -161,6 +167,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
161167
ecx: &mut EvalCtxt<'_, 'tcx>,
162168
goal: Goal<'tcx, Self>,
163169
) -> QueryResult<'tcx> {
170+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
171+
return Err(NoSolution);
172+
}
173+
164174
let tcx = ecx.tcx();
165175

166176
ecx.probe(|ecx| {
@@ -176,6 +186,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
176186
ecx: &mut EvalCtxt<'_, 'tcx>,
177187
goal: Goal<'tcx, Self>,
178188
) -> QueryResult<'tcx> {
189+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
190+
return Err(NoSolution);
191+
}
192+
179193
ecx.probe_and_evaluate_goal_for_constituent_tys(
180194
goal,
181195
structural_traits::instantiate_constituent_tys_for_sized_trait,
@@ -186,6 +200,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
186200
ecx: &mut EvalCtxt<'_, 'tcx>,
187201
goal: Goal<'tcx, Self>,
188202
) -> QueryResult<'tcx> {
203+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
204+
return Err(NoSolution);
205+
}
206+
189207
ecx.probe_and_evaluate_goal_for_constituent_tys(
190208
goal,
191209
structural_traits::instantiate_constituent_tys_for_copy_clone_trait,
@@ -196,6 +214,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
196214
ecx: &mut EvalCtxt<'_, 'tcx>,
197215
goal: Goal<'tcx, Self>,
198216
) -> QueryResult<'tcx> {
217+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
218+
return Err(NoSolution);
219+
}
220+
199221
if goal.predicate.self_ty().has_non_region_infer() {
200222
return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
201223
}
@@ -217,6 +239,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
217239
ecx: &mut EvalCtxt<'_, 'tcx>,
218240
goal: Goal<'tcx, Self>,
219241
) -> QueryResult<'tcx> {
242+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
243+
return Err(NoSolution);
244+
}
245+
220246
if let ty::FnPtr(..) = goal.predicate.self_ty().kind() {
221247
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
222248
} else {
@@ -229,6 +255,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
229255
goal: Goal<'tcx, Self>,
230256
goal_kind: ty::ClosureKind,
231257
) -> QueryResult<'tcx> {
258+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
259+
return Err(NoSolution);
260+
}
261+
232262
let tcx = ecx.tcx();
233263
let tupled_inputs_and_output =
234264
match structural_traits::extract_tupled_inputs_and_output_from_callable(
@@ -259,6 +289,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
259289
ecx: &mut EvalCtxt<'_, 'tcx>,
260290
goal: Goal<'tcx, Self>,
261291
) -> QueryResult<'tcx> {
292+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
293+
return Err(NoSolution);
294+
}
295+
262296
if let ty::Tuple(..) = goal.predicate.self_ty().kind() {
263297
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
264298
} else {
@@ -268,15 +302,23 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
268302

269303
fn consider_builtin_pointee_candidate(
270304
ecx: &mut EvalCtxt<'_, 'tcx>,
271-
_goal: Goal<'tcx, Self>,
305+
goal: Goal<'tcx, Self>,
272306
) -> QueryResult<'tcx> {
307+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
308+
return Err(NoSolution);
309+
}
310+
273311
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
274312
}
275313

276314
fn consider_builtin_future_candidate(
277315
ecx: &mut EvalCtxt<'_, 'tcx>,
278316
goal: Goal<'tcx, Self>,
279317
) -> QueryResult<'tcx> {
318+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
319+
return Err(NoSolution);
320+
}
321+
280322
let ty::Generator(def_id, _, _) = *goal.predicate.self_ty().kind() else {
281323
return Err(NoSolution);
282324
};
@@ -297,6 +339,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
297339
ecx: &mut EvalCtxt<'_, 'tcx>,
298340
goal: Goal<'tcx, Self>,
299341
) -> QueryResult<'tcx> {
342+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
343+
return Err(NoSolution);
344+
}
345+
300346
let self_ty = goal.predicate.self_ty();
301347
let ty::Generator(def_id, substs, _) = *self_ty.kind() else {
302348
return Err(NoSolution);
@@ -326,6 +372,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
326372
ecx: &mut EvalCtxt<'_, 'tcx>,
327373
goal: Goal<'tcx, Self>,
328374
) -> QueryResult<'tcx> {
375+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
376+
return Err(NoSolution);
377+
}
378+
329379
let tcx = ecx.tcx();
330380
let a_ty = goal.predicate.self_ty();
331381
let b_ty = goal.predicate.trait_ref.substs.type_at(1);
@@ -447,6 +497,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
447497
ecx: &mut EvalCtxt<'_, 'tcx>,
448498
goal: Goal<'tcx, Self>,
449499
) -> Vec<CanonicalResponse<'tcx>> {
500+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
501+
return vec![];
502+
}
503+
450504
let tcx = ecx.tcx();
451505

452506
let a_ty = goal.predicate.self_ty();
@@ -521,8 +575,12 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
521575

522576
fn consider_builtin_discriminant_kind_candidate(
523577
ecx: &mut EvalCtxt<'_, 'tcx>,
524-
_goal: Goal<'tcx, Self>,
578+
goal: Goal<'tcx, Self>,
525579
) -> QueryResult<'tcx> {
580+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
581+
return Err(NoSolution);
582+
}
583+
526584
// `DiscriminantKind` is automatically implemented for every type.
527585
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
528586
}
@@ -531,6 +589,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
531589
ecx: &mut EvalCtxt<'_, 'tcx>,
532590
goal: Goal<'tcx, Self>,
533591
) -> QueryResult<'tcx> {
592+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
593+
return Err(NoSolution);
594+
}
595+
534596
if !goal.param_env.is_const() {
535597
// `Destruct` is automatically implemented for every type in
536598
// non-const environments.
@@ -545,6 +607,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
545607
ecx: &mut EvalCtxt<'_, 'tcx>,
546608
goal: Goal<'tcx, Self>,
547609
) -> QueryResult<'tcx> {
610+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
611+
return Err(NoSolution);
612+
}
613+
548614
// `rustc_transmute` does not have support for type or const params
549615
if goal.has_non_region_placeholders() {
550616
return Err(NoSolution);

0 commit comments

Comments
 (0)