Use DeepRejectCtxt in assemble_inherent_candidates_from_param

This commit is contained in:
Michael Goulet 2025-05-21 10:02:54 +00:00
parent 87b4541569
commit ad59f0b6e6
4 changed files with 58 additions and 12 deletions

View file

@ -2,6 +2,7 @@
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![feature(array_windows)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]

View file

@ -1,3 +1,4 @@
use std::assert_matches::debug_assert_matches;
use std::cell::{Cell, RefCell};
use std::cmp::max;
use std::ops::Deref;
@ -16,7 +17,7 @@ use rustc_infer::traits::ObligationCauseCode;
use rustc_middle::middle::stability;
use rustc_middle::query::Providers;
use rustc_middle::ty::elaborate::supertrait_def_ids;
use rustc_middle::ty::fast_reject::{TreatParams, simplify_type};
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type};
use rustc_middle::ty::{
self, AssocItem, AssocItemContainer, GenericArgs, GenericArgsRef, GenericParamDefKind,
ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt, Upcast,
@ -807,8 +808,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
);
}
}
ty::Param(p) => {
self.assemble_inherent_candidates_from_param(p);
ty::Param(_) => {
self.assemble_inherent_candidates_from_param(raw_self_ty);
}
ty::Bool
| ty::Char
@ -909,18 +910,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
}
#[instrument(level = "debug", skip(self))]
fn assemble_inherent_candidates_from_param(&mut self, param_ty: ty::ParamTy) {
fn assemble_inherent_candidates_from_param(&mut self, param_ty: Ty<'tcx>) {
debug_assert_matches!(param_ty.kind(), ty::Param(_));
let tcx = self.tcx;
let bounds = self.param_env.caller_bounds().iter().filter_map(|predicate| {
let bound_predicate = predicate.kind();
match bound_predicate.skip_binder() {
ty::ClauseKind::Trait(trait_predicate) => {
match *trait_predicate.trait_ref.self_ty().kind() {
ty::Param(p) if p == param_ty => {
Some(bound_predicate.rebind(trait_predicate.trait_ref))
}
_ => None,
}
}
ty::ClauseKind::Trait(trait_predicate) => DeepRejectCtxt::relate_rigid_rigid(tcx)
.types_may_unify(param_ty, trait_predicate.trait_ref.self_ty())
.then(|| bound_predicate.rebind(trait_predicate.trait_ref)),
ty::ClauseKind::RegionOutlives(_)
| ty::ClauseKind::TypeOutlives(_)
| ty::ClauseKind::Projection(_)

View file

@ -0,0 +1,29 @@
//@ check-pass
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/214>.
// See comment below.
trait A {
fn hello(&self) {}
}
trait B {
fn hello(&self) {}
}
impl<T> A for T {}
impl<T> B for T {}
fn test<F, R>(q: F::Item)
where
F: Iterator<Item = R>,
// We want to prefer `A` for `R.hello()`
F::Item: A,
{
q.hello();
}
fn main() {}

View file

@ -0,0 +1,17 @@
//@ check-pass
//@ compile-flags: -Znext-solver
// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/214>.
fn execute<K, F, R>(q: F::Item) -> R
where
F: Iterator<Item = R>,
// Both of the below bounds should be considered for `.into()`, and then be combined
// into a single `R: Into<?0>` bound which can be inferred to `?0 = R`.
F::Item: Into<K>,
R: Into<String>,
{
q.into()
}
fn main() {}