Skip to content

Commit 16a95b5

Browse files
Instantiate predicate binder without recanonicalizing goal in new solver
1 parent c241e14 commit 16a95b5

24 files changed

+91
-241
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs

+1-16
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use rustc_span::Span;
77
use rustc_trait_selection::solve::inspect::{
88
InspectConfig, InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor,
99
};
10-
use rustc_type_ir::solve::GoalSource;
1110
use tracing::{debug, instrument, trace};
1211

1312
use crate::FnCtxt;
@@ -120,21 +119,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'a, 'tcx> {
120119
fn visit_goal(&mut self, inspect_goal: &InspectGoal<'_, 'tcx>) {
121120
let tcx = self.fcx.tcx;
122121
let goal = inspect_goal.goal();
123-
if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty)
124-
// We do not push the instantiated forms of goals as it would cause any
125-
// aliases referencing bound vars to go from having escaping bound vars to
126-
// being able to be normalized to an inference variable.
127-
//
128-
// This is mostly just a hack as arbitrary nested goals could still contain
129-
// such aliases while having a different `GoalSource`. Closure signature inference
130-
// however can't really handle *every* higher ranked `Fn` goal also being present
131-
// in the form of `?c: Fn<(<?x as Trait<'!a>>::Assoc)`.
132-
//
133-
// This also just better matches the behaviour of the old solver where we do not
134-
// encounter instantiated forms of goals, only nested goals that referred to bound
135-
// vars from instantiated goals.
136-
&& !matches!(inspect_goal.source(), GoalSource::InstantiateHigherRanked)
137-
{
122+
if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty) {
138123
self.obligations_for_self_ty.push(traits::Obligation::new(
139124
tcx,
140125
self.root_cause.clone(),

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

+46-56
Original file line numberDiff line numberDiff line change
@@ -448,63 +448,53 @@ where
448448
fn compute_goal(&mut self, goal: Goal<I, I::Predicate>) -> QueryResult<I> {
449449
let Goal { param_env, predicate } = goal;
450450
let kind = predicate.kind();
451-
if let Some(kind) = kind.no_bound_vars() {
452-
match kind {
453-
ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => {
454-
self.compute_trait_goal(Goal { param_env, predicate }).map(|(r, _via)| r)
455-
}
456-
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => {
457-
self.compute_host_effect_goal(Goal { param_env, predicate })
458-
}
459-
ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => {
460-
self.compute_projection_goal(Goal { param_env, predicate })
461-
}
462-
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(predicate)) => {
463-
self.compute_type_outlives_goal(Goal { param_env, predicate })
464-
}
465-
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(predicate)) => {
466-
self.compute_region_outlives_goal(Goal { param_env, predicate })
467-
}
468-
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
469-
self.compute_const_arg_has_type_goal(Goal { param_env, predicate: (ct, ty) })
470-
}
471-
ty::PredicateKind::Subtype(predicate) => {
472-
self.compute_subtype_goal(Goal { param_env, predicate })
473-
}
474-
ty::PredicateKind::Coerce(predicate) => {
475-
self.compute_coerce_goal(Goal { param_env, predicate })
476-
}
477-
ty::PredicateKind::DynCompatible(trait_def_id) => {
478-
self.compute_dyn_compatible_goal(trait_def_id)
479-
}
480-
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
481-
self.compute_well_formed_goal(Goal { param_env, predicate: arg })
482-
}
483-
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => {
484-
self.compute_const_evaluatable_goal(Goal { param_env, predicate: ct })
485-
}
486-
ty::PredicateKind::ConstEquate(_, _) => {
487-
panic!("ConstEquate should not be emitted when `-Znext-solver` is active")
488-
}
489-
ty::PredicateKind::NormalizesTo(predicate) => {
490-
self.compute_normalizes_to_goal(Goal { param_env, predicate })
491-
}
492-
ty::PredicateKind::AliasRelate(lhs, rhs, direction) => self
493-
.compute_alias_relate_goal(Goal {
494-
param_env,
495-
predicate: (lhs, rhs, direction),
496-
}),
497-
ty::PredicateKind::Ambiguous => {
498-
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
499-
}
451+
self.enter_forall(kind, |ecx, kind| match kind {
452+
ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => {
453+
ecx.compute_trait_goal(Goal { param_env, predicate }).map(|(r, _via)| r)
500454
}
501-
} else {
502-
self.enter_forall(kind, |ecx, kind| {
503-
let goal = goal.with(ecx.cx(), ty::Binder::dummy(kind));
504-
ecx.add_goal(GoalSource::InstantiateHigherRanked, goal);
505-
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
506-
})
507-
}
455+
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => {
456+
ecx.compute_host_effect_goal(Goal { param_env, predicate })
457+
}
458+
ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => {
459+
ecx.compute_projection_goal(Goal { param_env, predicate })
460+
}
461+
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(predicate)) => {
462+
ecx.compute_type_outlives_goal(Goal { param_env, predicate })
463+
}
464+
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(predicate)) => {
465+
ecx.compute_region_outlives_goal(Goal { param_env, predicate })
466+
}
467+
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
468+
ecx.compute_const_arg_has_type_goal(Goal { param_env, predicate: (ct, ty) })
469+
}
470+
ty::PredicateKind::Subtype(predicate) => {
471+
ecx.compute_subtype_goal(Goal { param_env, predicate })
472+
}
473+
ty::PredicateKind::Coerce(predicate) => {
474+
ecx.compute_coerce_goal(Goal { param_env, predicate })
475+
}
476+
ty::PredicateKind::DynCompatible(trait_def_id) => {
477+
ecx.compute_dyn_compatible_goal(trait_def_id)
478+
}
479+
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
480+
ecx.compute_well_formed_goal(Goal { param_env, predicate: arg })
481+
}
482+
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => {
483+
ecx.compute_const_evaluatable_goal(Goal { param_env, predicate: ct })
484+
}
485+
ty::PredicateKind::ConstEquate(_, _) => {
486+
panic!("ConstEquate should not be emitted when `-Znext-solver` is active")
487+
}
488+
ty::PredicateKind::NormalizesTo(predicate) => {
489+
ecx.compute_normalizes_to_goal(Goal { param_env, predicate })
490+
}
491+
ty::PredicateKind::AliasRelate(lhs, rhs, direction) => {
492+
ecx.compute_alias_relate_goal(Goal { param_env, predicate: (lhs, rhs, direction) })
493+
}
494+
ty::PredicateKind::Ambiguous => {
495+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
496+
}
497+
})
508498
}
509499

510500
// Recursively evaluates all the goals added to this `EvalCtxt` to completion, returning

compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs

-5
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ impl<'tcx> BestObligation<'tcx> {
209209
nested_goal.source(),
210210
GoalSource::ImplWhereBound
211211
| GoalSource::AliasBoundConstCondition
212-
| GoalSource::InstantiateHigherRanked
213212
| GoalSource::AliasWellFormed
214213
) && match (self.consider_ambiguities, nested_goal.result()) {
215214
(true, Ok(Certainty::Maybe(MaybeCause::Ambiguity)))
@@ -380,10 +379,6 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
380379
));
381380
impl_where_bound_count += 1;
382381
}
383-
// Skip over a higher-ranked predicate.
384-
(_, GoalSource::InstantiateHigherRanked) => {
385-
obligation = self.obligation.clone();
386-
}
387382
(ChildMode::PassThrough, _)
388383
| (_, GoalSource::AliasWellFormed | GoalSource::AliasBoundConstCondition) => {
389384
obligation = make_obligation(self.obligation.cause.clone());

compiler/rustc_trait_selection/src/traits/coherence.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -660,9 +660,10 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
660660
// For bound predicates we simply call `infcx.enter_forall`
661661
// and then prove the resulting predicate as a nested goal.
662662
let Goal { param_env, predicate } = goal.goal();
663-
let trait_ref = match predicate.kind().no_bound_vars() {
664-
Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr))) => tr.trait_ref,
665-
Some(ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)))
663+
let predicate_kind = goal.infcx().enter_forall_and_leak_universe(predicate.kind());
664+
let trait_ref = match predicate_kind {
665+
ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr)) => tr.trait_ref,
666+
ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj))
666667
if matches!(
667668
infcx.tcx.def_kind(proj.projection_term.def_id),
668669
DefKind::AssocTy | DefKind::AssocConst

compiler/rustc_type_ir/src/solve/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,6 @@ pub enum GoalSource {
7272
///
7373
/// FIXME(-Znext-solver=coinductive): Are these even coinductive?
7474
AliasBoundConstCondition,
75-
/// Instantiating a higher-ranked goal and re-proving it.
76-
InstantiateHigherRanked,
7775
/// Predicate required for an alias projection to be well-formed.
7876
/// This is used in two places: projecting to an opaque whose hidden type
7977
/// is already registered in the opaque type storage, and for rigid projections.

tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ LL | impl<T> Trait for Box<T> {}
1212
| ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
1313
|
1414
= note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>`
15-
= note: downstream crates may implement trait `WhereBound` for type `std::boxed::Box<_>`
15+
= note: downstream crates may implement trait `WhereBound` for type `std::boxed::Box<<std::boxed::Box<_> as WithAssoc<'a>>::Assoc>`
1616

1717
error: aborting due to 1 previous error
1818

tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.next.stderr

-23
This file was deleted.

tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@ revisions: old next
22
//@[next] compile-flags: -Znext-solver
3-
//@[old] check-pass
3+
//@ check-pass
44

55
// cc #119820
66

@@ -25,7 +25,6 @@ where
2525
// the leak check both candidates may apply and we prefer the
2626
// `param_env` candidate in winnowing.
2727
hr_bound::<&T>();
28-
//[next]~^ ERROR the trait bound `for<'a> &'a &T: Trait` is not satisfied
2928
}
3029

3130
fn main() {}

tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr

-15
This file was deleted.

tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@ revisions: current next
22
//@[next] compile-flags: -Znext-solver
3-
//@[current] check-pass
3+
//@ check-pass
44

55
// cc #119820
66

@@ -13,7 +13,6 @@ fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {}
1313

1414
fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() {
1515
impl_hr::<T>();
16-
//[next]~^ ERROR the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied
1716
}
1817

1918
fn main() {}

tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0308]: mismatched types
2-
--> $DIR/candidate-from-env-universe-err-project.rs:38:5
2+
--> $DIR/candidate-from-env-universe-err-project.rs:37:5
33
|
44
LL | projection_bound::<T>();
55
| ^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
@@ -13,7 +13,7 @@ LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
1313
| ^^^^^^^^^^^^^
1414

1515
error[E0308]: mismatched types
16-
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
16+
--> $DIR/candidate-from-env-universe-err-project.rs:51:30
1717
|
1818
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
1919
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
@@ -22,7 +22,7 @@ LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
2222
found associated type `<T as Trait<'a>>::Assoc`
2323

2424
error[E0308]: mismatched types
25-
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
25+
--> $DIR/candidate-from-env-universe-err-project.rs:51:30
2626
|
2727
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
2828
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,5 @@
1-
error[E0277]: the trait bound `for<'a> T: Trait<'a>` is not satisfied
2-
--> $DIR/candidate-from-env-universe-err-project.rs:28:19
3-
|
4-
LL | trait_bound::<T>();
5-
| ^ the trait `for<'a> Trait<'a>` is not implemented for `T`
6-
|
7-
note: required by a bound in `trait_bound`
8-
--> $DIR/candidate-from-env-universe-err-project.rs:17:19
9-
|
10-
LL | fn trait_bound<T: for<'a> Trait<'a>>() {}
11-
| ^^^^^^^^^^^^^^^^^ required by this bound in `trait_bound`
12-
13-
error[E0277]: the trait bound `for<'a> T: Trait<'a>` is not satisfied
14-
--> $DIR/candidate-from-env-universe-err-project.rs:38:24
15-
|
16-
LL | projection_bound::<T>();
17-
| ^ the trait `for<'a> Trait<'a>` is not implemented for `T`
18-
|
19-
note: required by a bound in `projection_bound`
20-
--> $DIR/candidate-from-env-universe-err-project.rs:18:24
21-
|
22-
LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
23-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `projection_bound`
24-
251
error[E0271]: type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
26-
--> $DIR/candidate-from-env-universe-err-project.rs:38:24
2+
--> $DIR/candidate-from-env-universe-err-project.rs:37:24
273
|
284
LL | projection_bound::<T>();
295
| ^ type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
@@ -40,20 +16,19 @@ LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
4016
| ^^^^^^^^^^^^^ required by this bound in `projection_bound`
4117

4218
error: higher-ranked subtype error
43-
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
19+
--> $DIR/candidate-from-env-universe-err-project.rs:51:30
4420
|
4521
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
4622
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4723

4824
error: higher-ranked subtype error
49-
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
25+
--> $DIR/candidate-from-env-universe-err-project.rs:51:30
5026
|
5127
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
5228
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5329
|
5430
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
5531

56-
error: aborting due to 5 previous errors
32+
error: aborting due to 3 previous errors
5733

58-
Some errors have detailed explanations: E0271, E0277.
59-
For more information about an error, try `rustc --explain E0271`.
34+
For more information about this error, try `rustc --explain E0271`.

tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,12 @@ fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
2020
// We use a function with a trivial where-bound which is more
2121
// restrictive than the impl.
2222
fn function1<T: Trait<'static>>() {
23-
// err
23+
// ok
2424
//
2525
// Proving `for<'a> T: Trait<'a>` using the where-bound does not
2626
// result in a leak check failure even though it does not apply.
2727
// We prefer env candidates over impl candidatescausing this to succeed.
2828
trait_bound::<T>();
29-
//[next]~^ ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
3029
}
3130

3231
fn function2<T: Trait<'static, Assoc = usize>>() {
@@ -37,8 +36,7 @@ fn function2<T: Trait<'static, Assoc = usize>>() {
3736
// to prefer it over the impl, resulting in a placeholder error.
3837
projection_bound::<T>();
3938
//[next]~^ ERROR type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
40-
//[next]~| ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
41-
//[current]~^^^ ERROR mismatched types
39+
//[current]~^^ ERROR mismatched types
4240
}
4341

4442
fn function3<T: Trait<'static, Assoc = usize>>() {

tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr

-23
This file was deleted.

0 commit comments

Comments
 (0)