Don't allow poly_select in new solver

This commit is contained in:
Michael Goulet 2025-05-22 11:06:42 +00:00
parent 2cd37831b0
commit 16b6ffe0db
6 changed files with 69 additions and 10 deletions

View file

@ -1503,11 +1503,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
return None;
};
let Ok(Some(ImplSource::UserDefined(impl_data))) = SelectionContext::new(self)
.poly_select(&obligation.with(
self.tcx,
predicate.kind().rebind(proj.projection_term.trait_ref(self.tcx)),
))
let trait_ref = self.enter_forall_and_leak_universe(
predicate.kind().rebind(proj.projection_term.trait_ref(self.tcx)),
);
let Ok(Some(ImplSource::UserDefined(impl_data))) =
SelectionContext::new(self).select(&obligation.with(self.tcx, trait_ref))
else {
return None;
};

View file

@ -5,7 +5,7 @@ use rustc_infer::traits::solve::inspect::ProbeKind;
use rustc_infer::traits::solve::{CandidateSource, Certainty, Goal};
use rustc_infer::traits::{
BuiltinImplSource, ImplSource, ImplSourceUserDefinedData, Obligation, ObligationCause,
PolyTraitObligation, Selection, SelectionError, SelectionResult,
Selection, SelectionError, SelectionResult, TraitObligation,
};
use rustc_macros::extension;
use rustc_middle::{bug, span_bug};
@ -17,7 +17,7 @@ use crate::solve::inspect::{self, ProofTreeInferCtxtExt};
impl<'tcx> InferCtxt<'tcx> {
fn select_in_new_trait_solver(
&self,
obligation: &PolyTraitObligation<'tcx>,
obligation: &TraitObligation<'tcx>,
) -> SelectionResult<'tcx, Selection<'tcx>> {
assert!(self.next_trait_solver());

View file

@ -265,9 +265,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
obligation: &PolyTraitObligation<'tcx>,
) -> SelectionResult<'tcx, Selection<'tcx>> {
if self.infcx.next_trait_solver() {
return self.infcx.select_in_new_trait_solver(obligation);
}
assert!(!self.infcx.next_trait_solver());
let candidate = match self.select_from_obligation(obligation) {
Err(SelectionError::Overflow(OverflowError::Canonical)) => {
@ -299,6 +297,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
obligation: &TraitObligation<'tcx>,
) -> SelectionResult<'tcx, Selection<'tcx>> {
if self.infcx.next_trait_solver() {
return self.infcx.select_in_new_trait_solver(obligation);
}
self.poly_select(&Obligation {
cause: obligation.cause.clone(),
param_env: obligation.param_env,

View file

@ -0,0 +1,12 @@
error[E0308]: mismatched types
--> $DIR/hr-projection-mismatch.rs:20:5
|
LL | wrap::<_, Thing>();
| ^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected reference `&'a _`
found reference `&_`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -0,0 +1,20 @@
error[E0271]: type mismatch resolving `<Thing as Trait<'a>>::Assoc == &i32`
--> $DIR/hr-projection-mismatch.rs:20:15
|
LL | wrap::<_, Thing>();
| ^^^^^ type mismatch resolving `<Thing as Trait<'a>>::Assoc == &i32`
|
note: types differ
--> $DIR/hr-projection-mismatch.rs:14:18
|
LL | type Assoc = &'a i32;
| ^^^^^^^
note: required by a bound in `wrap`
--> $DIR/hr-projection-mismatch.rs:17:33
|
LL | fn wrap<T, U: for<'a> Trait<'a, Assoc = T>>() {}
| ^^^^^^^^^ required by this bound in `wrap`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0271`.

View file

@ -0,0 +1,25 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
// Regression test for <https://github.com/rust-lang/rust/issues/141322>.
trait Trait<'a> {
type Assoc;
}
struct Thing;
impl<'a> Trait<'a> for Thing {
type Assoc = &'a i32;
}
fn wrap<T, U: for<'a> Trait<'a, Assoc = T>>() {}
fn foo() {
wrap::<_, Thing>();
//[next]~^ ERROR type mismatch resolving `<Thing as Trait<'a>>::Assoc == &i32
//[current]~^^ ERROR mismatched types
}
fn main() {}