Check xform_ret_ty for WF in the new solver to improve method winnowing
This commit is contained in:
parent
f2abf827c1
commit
4120fdbeab
2 changed files with 69 additions and 0 deletions
|
@ -1642,6 +1642,28 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(-Znext-solver): See the linked issue below.
|
||||||
|
// <https://github.com/rust-lang/trait-system-refactor-initiative/issues/134>
|
||||||
|
//
|
||||||
|
// In the new solver, check the well-formedness of the return type.
|
||||||
|
// This emulates, in a way, the predicates that fall out of
|
||||||
|
// normalizing the return type in the old solver.
|
||||||
|
//
|
||||||
|
// We alternatively could check the predicates of the method itself hold,
|
||||||
|
// but we intentionally do not do this in the old solver b/c of cycles,
|
||||||
|
// and doing it in the new solver would be stronger. This should be fixed
|
||||||
|
// in the future, since it likely leads to much better method winnowing.
|
||||||
|
if let Some(xform_ret_ty) = xform_ret_ty
|
||||||
|
&& self.infcx.next_trait_solver()
|
||||||
|
{
|
||||||
|
ocx.register_obligation(traits::Obligation::new(
|
||||||
|
self.tcx,
|
||||||
|
cause.clone(),
|
||||||
|
self.param_env,
|
||||||
|
ty::ClauseKind::WellFormed(xform_ret_ty.into()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
// Evaluate those obligations to see if they might possibly hold.
|
// Evaluate those obligations to see if they might possibly hold.
|
||||||
for error in ocx.select_where_possible() {
|
for error in ocx.select_where_possible() {
|
||||||
result = ProbeResult::NoMatch;
|
result = ProbeResult::NoMatch;
|
||||||
|
|
47
tests/ui/traits/next-solver/non-wf-ret.rs
Normal file
47
tests/ui/traits/next-solver/non-wf-ret.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
//@ check-pass
|
||||||
|
//@ compile-flags: -Znext-solver
|
||||||
|
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
pub struct List<T> {
|
||||||
|
skel: [T],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Copy> IntoIterator for &'a List<T> {
|
||||||
|
type Item = T;
|
||||||
|
type IntoIter = std::iter::Copied<<&'a [T] as IntoIterator>::IntoIter>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Deref for List<T> {
|
||||||
|
type Target = [T];
|
||||||
|
|
||||||
|
fn deref(&self) -> &[T] {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> List<T> {
|
||||||
|
fn iter(&self) -> <&Self as IntoIterator>::IntoIter
|
||||||
|
where
|
||||||
|
T: Copy,
|
||||||
|
{
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test<Q>(t: &List<Q>) {
|
||||||
|
// Checking that `<&List<Q> as IntoIterator>::IntoIter` is WF
|
||||||
|
// will disqualify the inherent method, since normalizing it
|
||||||
|
// requires `Q: Copy` which does not hold. and allow us to fall
|
||||||
|
// through to the deref'd `<[Q]>::iter` method which works.
|
||||||
|
//
|
||||||
|
// In the old solver, the same behavior is achieved by just
|
||||||
|
// eagerly normalizing the return type.
|
||||||
|
t.iter();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue