mirror of https://github.com/rust-lang/rust.git
Process alias-relate obligations when proving receiver_is_valid
This commit is contained in:
parent
11dd90f761
commit
fdde66acee
|
@ -1712,7 +1712,15 @@ fn receiver_is_valid<'tcx>(
|
||||||
let cause =
|
let cause =
|
||||||
ObligationCause::new(span, wfcx.body_def_id, traits::ObligationCauseCode::MethodReceiver);
|
ObligationCause::new(span, wfcx.body_def_id, traits::ObligationCauseCode::MethodReceiver);
|
||||||
|
|
||||||
let can_eq_self = |ty| infcx.can_eq(wfcx.param_env, self_ty, ty);
|
let can_eq_self = |ty| {
|
||||||
|
wfcx.infcx.probe(|_| {
|
||||||
|
let ocx = ObligationCtxt::new(wfcx.infcx);
|
||||||
|
let Ok(()) = ocx.eq(&ObligationCause::dummy(), wfcx.param_env, self_ty, ty) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
ocx.select_where_possible().is_empty()
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
// `self: Self` is always valid.
|
// `self: Self` is always valid.
|
||||||
if can_eq_self(receiver_ty) {
|
if can_eq_self(receiver_ty) {
|
||||||
|
|
|
@ -767,6 +767,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(-Znext-solver): Get rid of this method, it's never correct. Either that,
|
||||||
|
// or we need to process the obligations.
|
||||||
pub fn can_sub<T>(&self, param_env: ty::ParamEnv<'tcx>, expected: T, actual: T) -> bool
|
pub fn can_sub<T>(&self, param_env: ty::ParamEnv<'tcx>, expected: T, actual: T) -> bool
|
||||||
where
|
where
|
||||||
T: at::ToTrace<'tcx>,
|
T: at::ToTrace<'tcx>,
|
||||||
|
@ -779,6 +781,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(-Znext-solver): Get rid of this method, it's never correct. Either that,
|
||||||
|
// or we need to process the obligations.
|
||||||
pub fn can_eq<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool
|
pub fn can_eq<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool
|
||||||
where
|
where
|
||||||
T: at::ToTrace<'tcx>,
|
T: at::ToTrace<'tcx>,
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output`
|
|
||||||
--> $DIR/issue-100222.rs:34:12
|
|
||||||
|
|
|
||||||
LL | fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
|
|
||||||
| ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output`
|
|
||||||
|
|
|
||||||
= note: expected unit type `()`
|
|
||||||
found mutable reference `&mut <() as Index>::Output`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0271`.
|
|
|
@ -1,12 +0,0 @@
|
||||||
error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output`
|
|
||||||
--> $DIR/issue-100222.rs:25:12
|
|
||||||
|
|
|
||||||
LL | fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
|
|
||||||
| ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output`
|
|
||||||
|
|
|
||||||
= note: expected unit type `()`
|
|
||||||
found mutable reference `&mut <() as Index>::Output`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0271`.
|
|
|
@ -1,6 +1,7 @@
|
||||||
//@ revisions: nn ny yn yy
|
//@ revisions: nn ny yn yy
|
||||||
//@ known-bug: #110395
|
|
||||||
//@ compile-flags: -Znext-solver
|
//@ compile-flags: -Znext-solver
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
#![feature(const_trait_impl, effects, associated_type_defaults, const_mut_refs)]
|
#![feature(const_trait_impl, effects, associated_type_defaults, const_mut_refs)]
|
||||||
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output`
|
|
||||||
--> $DIR/issue-100222.rs:34:12
|
|
||||||
|
|
|
||||||
LL | fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
|
|
||||||
| ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output`
|
|
||||||
|
|
|
||||||
= note: expected unit type `()`
|
|
||||||
found mutable reference `&mut <() as Index>::Output`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0271`.
|
|
|
@ -1,12 +0,0 @@
|
||||||
error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output`
|
|
||||||
--> $DIR/issue-100222.rs:25:12
|
|
||||||
|
|
|
||||||
LL | fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
|
|
||||||
| ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output`
|
|
||||||
|
|
|
||||||
= note: expected unit type `()`
|
|
||||||
found mutable reference `&mut <() as Index>::Output`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0271`.
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//@ compile-flags: -Znext-solver
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// Fixes a regression in `receiver_is_valid` in wfcheck where we were using
|
||||||
|
// `InferCtxt::can_eq` instead of processing alias-relate goals, leading to false
|
||||||
|
// positives, not deref'ing enough steps to check the receiver is valid.
|
||||||
|
|
||||||
|
trait Mirror {
|
||||||
|
type Mirror: ?Sized;
|
||||||
|
}
|
||||||
|
impl<T: ?Sized> Mirror for T {
|
||||||
|
type Mirror = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
fn foo(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo for <() as Mirror>::Mirror {
|
||||||
|
fn foo(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Reference in New Issue