1
Fork 0

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:
bors 2024-09-17 12:44:08 +00:00
commit e9e13a68d7
17 changed files with 141 additions and 56 deletions

View file

@ -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(_) => {

View file

@ -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;