Auto merge of #129073 - compiler-errors:receiver-variance, r=lcnr
Relate receiver invariantly in method probe for `Mode::Path` Effectively reverts part of #126128 Fixes #126227 This PR changes method probing to use equality for fully path-based method lookup, and subtyping for receiver `.` method lookup. r? lcnr
This commit is contained in:
commit
e9e13a68d7
17 changed files with 141 additions and 56 deletions
|
@ -1388,10 +1388,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// This also occurs for an enum variant on a type alias.
|
||||
let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args));
|
||||
let self_ty = self.normalize(span, self_ty);
|
||||
match self.at(&self.misc(span), self.param_env).sub(
|
||||
match self.at(&self.misc(span), self.param_env).eq(
|
||||
DefineOpaqueTypes::Yes,
|
||||
self_ty,
|
||||
impl_ty,
|
||||
self_ty,
|
||||
) {
|
||||
Ok(ok) => self.register_infer_ok_obligations(ok),
|
||||
Err(_) => {
|
||||
|
|
|
@ -621,6 +621,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
self.unsatisfied_predicates.borrow_mut().clear();
|
||||
}
|
||||
|
||||
/// When we're looking up a method by path (UFCS), we relate the receiver
|
||||
/// types invariantly. When we are looking up a method by the `.` operator,
|
||||
/// we relate them covariantly.
|
||||
fn variance(&self) -> ty::Variance {
|
||||
match self.mode {
|
||||
Mode::MethodCall => ty::Covariant,
|
||||
Mode::Path => ty::Invariant,
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// CANDIDATE ASSEMBLY
|
||||
|
||||
|
@ -1443,7 +1453,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
(xform_self_ty, xform_ret_ty) =
|
||||
self.xform_self_ty(probe.item, impl_ty, impl_args);
|
||||
xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty);
|
||||
match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) {
|
||||
match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty)
|
||||
{
|
||||
Ok(()) => {}
|
||||
Err(err) => {
|
||||
debug!("--> cannot relate self-types {:?}", err);
|
||||
|
@ -1514,7 +1525,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
{
|
||||
return ProbeResult::NoMatch;
|
||||
}
|
||||
_ => match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) {
|
||||
_ => match ocx.relate(
|
||||
cause,
|
||||
self.param_env,
|
||||
self.variance(),
|
||||
self_ty,
|
||||
xform_self_ty,
|
||||
) {
|
||||
Ok(()) => {}
|
||||
Err(err) => {
|
||||
debug!("--> cannot relate self-types {:?}", err);
|
||||
|
@ -1560,7 +1577,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
(xform_self_ty, xform_ret_ty) =
|
||||
self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args);
|
||||
xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty);
|
||||
match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) {
|
||||
match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty)
|
||||
{
|
||||
Ok(()) => {}
|
||||
Err(err) => {
|
||||
debug!("--> cannot relate self-types {:?}", err);
|
||||
|
@ -1603,7 +1621,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
debug!("comparing return_ty {:?} with xform ret ty {:?}", return_ty, xform_ret_ty);
|
||||
match ocx.sup(cause, self.param_env, return_ty, xform_ret_ty) {
|
||||
match ocx.relate(cause, self.param_env, self.variance(), xform_ret_ty, return_ty) {
|
||||
Ok(()) => {}
|
||||
Err(_) => {
|
||||
result = ProbeResult::BadReturnType;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue