Skip to content

Commit 1f9fc8f

Browse files
committed
Auto merge of rust-lang#127473 - compiler-errors:perf-revert-receiver, r=<try>
Revert "Rework receiver_is_valid" This reverts commit 465e7d5. Testing perf: rust-lang#127172 (comment) r? `@ghost`
2 parents 89aefb9 + 355ef6b commit 1f9fc8f

File tree

1 file changed

+50
-42
lines changed

1 file changed

+50
-42
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+50-42
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use rustc_session::parse::feature_err;
2929
use rustc_span::symbol::{sym, Ident};
3030
use rustc_span::{Span, DUMMY_SP};
3131
use rustc_target::spec::abi::Abi;
32+
use rustc_trait_selection::infer::InferCtxtExt;
3233
use rustc_trait_selection::regions::InferCtxtRegionExt;
3334
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
3435
use rustc_trait_selection::traits::misc::{
@@ -39,7 +40,6 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _
3940
use rustc_trait_selection::traits::{
4041
self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc,
4142
};
42-
use rustc_type_ir::solve::NoSolution;
4343
use rustc_type_ir::TypeFlags;
4444

4545
use std::cell::LazyCell;
@@ -1713,12 +1713,13 @@ fn receiver_is_valid<'tcx>(
17131713
let cause =
17141714
ObligationCause::new(span, wfcx.body_def_id, traits::ObligationCauseCode::MethodReceiver);
17151715

1716-
// Special case `receiver == self_ty`, which doesn't necessarily require the `Receiver` lang item.
1717-
if let Ok(()) = wfcx.infcx.commit_if_ok(|_| {
1718-
let ocx = ObligationCtxt::new(wfcx.infcx);
1719-
ocx.eq(&cause, wfcx.param_env, self_ty, receiver_ty)?;
1720-
if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(NoSolution) }
1721-
}) {
1716+
let can_eq_self = |ty| infcx.can_eq(wfcx.param_env, self_ty, ty);
1717+
1718+
// `self: Self` is always valid.
1719+
if can_eq_self(receiver_ty) {
1720+
if let Err(err) = wfcx.eq(&cause, wfcx.param_env, self_ty, receiver_ty) {
1721+
infcx.err_ctxt().report_mismatched_types(&cause, self_ty, receiver_ty, err).emit();
1722+
}
17221723
return true;
17231724
}
17241725

@@ -1729,51 +1730,58 @@ fn receiver_is_valid<'tcx>(
17291730
autoderef = autoderef.include_raw_pointers();
17301731
}
17311732

1733+
// The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it.
1734+
autoderef.next();
1735+
17321736
let receiver_trait_def_id = tcx.require_lang_item(LangItem::Receiver, Some(span));
17331737

17341738
// Keep dereferencing `receiver_ty` until we get to `self_ty`.
1735-
while let Some((potential_self_ty, _)) = autoderef.next() {
1736-
debug!(
1737-
"receiver_is_valid: potential self type `{:?}` to match `{:?}`",
1738-
potential_self_ty, self_ty
1739-
);
1739+
loop {
1740+
if let Some((potential_self_ty, _)) = autoderef.next() {
1741+
debug!(
1742+
"receiver_is_valid: potential self type `{:?}` to match `{:?}`",
1743+
potential_self_ty, self_ty
1744+
);
17401745

1741-
// Check if the self type unifies. If it does, then commit the result
1742-
// since it may have region side-effects.
1743-
if let Ok(()) = wfcx.infcx.commit_if_ok(|_| {
1744-
let ocx = ObligationCtxt::new(wfcx.infcx);
1745-
ocx.eq(&cause, wfcx.param_env, self_ty, potential_self_ty)?;
1746-
if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(NoSolution) }
1747-
}) {
1748-
wfcx.register_obligations(autoderef.into_obligations());
1749-
return true;
1750-
}
1746+
if can_eq_self(potential_self_ty) {
1747+
wfcx.register_obligations(autoderef.into_obligations());
1748+
1749+
if let Err(err) = wfcx.eq(&cause, wfcx.param_env, self_ty, potential_self_ty) {
1750+
infcx
1751+
.err_ctxt()
1752+
.report_mismatched_types(&cause, self_ty, potential_self_ty, err)
1753+
.emit();
1754+
}
17511755

1752-
// Without `feature(arbitrary_self_types)`, we require that each step in the
1753-
// deref chain implement `receiver`.
1754-
if !arbitrary_self_types_enabled {
1755-
if !receiver_is_implemented(
1756-
wfcx,
1757-
receiver_trait_def_id,
1758-
cause.clone(),
1759-
potential_self_ty,
1760-
) {
1761-
// We cannot proceed.
17621756
break;
1757+
} else {
1758+
// Without `feature(arbitrary_self_types)`, we require that each step in the
1759+
// deref chain implement `receiver`
1760+
if !arbitrary_self_types_enabled
1761+
&& !receiver_is_implemented(
1762+
wfcx,
1763+
receiver_trait_def_id,
1764+
cause.clone(),
1765+
potential_self_ty,
1766+
)
1767+
{
1768+
return false;
1769+
}
17631770
}
1764-
1765-
// Register the bound, in case it has any region side-effects.
1766-
wfcx.register_bound(
1767-
cause.clone(),
1768-
wfcx.param_env,
1769-
potential_self_ty,
1770-
receiver_trait_def_id,
1771-
);
1771+
} else {
1772+
debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty);
1773+
return false;
17721774
}
17731775
}
17741776

1775-
debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty);
1776-
false
1777+
// Without `feature(arbitrary_self_types)`, we require that `receiver_ty` implements `Receiver`.
1778+
if !arbitrary_self_types_enabled
1779+
&& !receiver_is_implemented(wfcx, receiver_trait_def_id, cause.clone(), receiver_ty)
1780+
{
1781+
return false;
1782+
}
1783+
1784+
true
17771785
}
17781786

17791787
fn receiver_is_implemented<'tcx>(

0 commit comments

Comments
 (0)