mirror of https://github.com/rust-lang/rust.git
Rework receiver_is_valid
This commit is contained in:
parent
fb8d5f1e13
commit
465e7d546e
|
@ -29,7 +29,6 @@ use rustc_session::parse::feature_err;
|
||||||
use rustc_span::symbol::{sym, Ident};
|
use rustc_span::symbol::{sym, Ident};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
use rustc_trait_selection::infer::InferCtxtExt;
|
|
||||||
use rustc_trait_selection::regions::InferCtxtRegionExt;
|
use rustc_trait_selection::regions::InferCtxtRegionExt;
|
||||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||||
use rustc_trait_selection::traits::misc::{
|
use rustc_trait_selection::traits::misc::{
|
||||||
|
@ -40,6 +39,7 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _
|
||||||
use rustc_trait_selection::traits::{
|
use rustc_trait_selection::traits::{
|
||||||
self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc,
|
self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc,
|
||||||
};
|
};
|
||||||
|
use rustc_type_ir::solve::NoSolution;
|
||||||
use rustc_type_ir::TypeFlags;
|
use rustc_type_ir::TypeFlags;
|
||||||
|
|
||||||
use std::cell::LazyCell;
|
use std::cell::LazyCell;
|
||||||
|
@ -1713,13 +1713,12 @@ 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);
|
// Special case `receiver == self_ty`, which doesn't necessarily require the `Receiver` lang item.
|
||||||
|
if let Ok(()) = wfcx.infcx.commit_if_ok(|_| {
|
||||||
// `self: Self` is always valid.
|
let ocx = ObligationCtxt::new(wfcx.infcx);
|
||||||
if can_eq_self(receiver_ty) {
|
ocx.eq(&cause, wfcx.param_env, self_ty, receiver_ty)?;
|
||||||
if let Err(err) = wfcx.eq(&cause, wfcx.param_env, self_ty, receiver_ty) {
|
if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(NoSolution) }
|
||||||
infcx.err_ctxt().report_mismatched_types(&cause, self_ty, receiver_ty, err).emit();
|
}) {
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1730,58 +1729,51 @@ fn receiver_is_valid<'tcx>(
|
||||||
autoderef = autoderef.include_raw_pointers();
|
autoderef = autoderef.include_raw_pointers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it.
|
|
||||||
autoderef.next();
|
|
||||||
|
|
||||||
let receiver_trait_def_id = tcx.require_lang_item(LangItem::Receiver, Some(span));
|
let receiver_trait_def_id = tcx.require_lang_item(LangItem::Receiver, Some(span));
|
||||||
|
|
||||||
// Keep dereferencing `receiver_ty` until we get to `self_ty`.
|
// Keep dereferencing `receiver_ty` until we get to `self_ty`.
|
||||||
loop {
|
while let Some((potential_self_ty, _)) = autoderef.next() {
|
||||||
if let Some((potential_self_ty, _)) = autoderef.next() {
|
debug!(
|
||||||
debug!(
|
"receiver_is_valid: potential self type `{:?}` to match `{:?}`",
|
||||||
"receiver_is_valid: potential self type `{:?}` to match `{:?}`",
|
potential_self_ty, self_ty
|
||||||
potential_self_ty, self_ty
|
);
|
||||||
);
|
|
||||||
|
|
||||||
if can_eq_self(potential_self_ty) {
|
// Check if the self type unifies. If it does, then commit the result
|
||||||
wfcx.register_obligations(autoderef.into_obligations());
|
// since it may have region side-effects.
|
||||||
|
if let Ok(()) = wfcx.infcx.commit_if_ok(|_| {
|
||||||
if let Err(err) = wfcx.eq(&cause, wfcx.param_env, self_ty, potential_self_ty) {
|
let ocx = ObligationCtxt::new(wfcx.infcx);
|
||||||
infcx
|
ocx.eq(&cause, wfcx.param_env, self_ty, potential_self_ty)?;
|
||||||
.err_ctxt()
|
if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(NoSolution) }
|
||||||
.report_mismatched_types(&cause, self_ty, potential_self_ty, err)
|
}) {
|
||||||
.emit();
|
wfcx.register_obligations(autoderef.into_obligations());
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Without `feature(arbitrary_self_types)`, we require that each step in the
|
||||||
|
// deref chain implement `receiver`.
|
||||||
|
if !arbitrary_self_types_enabled {
|
||||||
|
if !receiver_is_implemented(
|
||||||
|
wfcx,
|
||||||
|
receiver_trait_def_id,
|
||||||
|
cause.clone(),
|
||||||
|
potential_self_ty,
|
||||||
|
) {
|
||||||
|
// We cannot proceed.
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
// Without `feature(arbitrary_self_types)`, we require that each step in the
|
|
||||||
// deref chain implement `receiver`
|
|
||||||
if !arbitrary_self_types_enabled
|
|
||||||
&& !receiver_is_implemented(
|
|
||||||
wfcx,
|
|
||||||
receiver_trait_def_id,
|
|
||||||
cause.clone(),
|
|
||||||
potential_self_ty,
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty);
|
// Register the bound, in case it has any region side-effects.
|
||||||
return false;
|
wfcx.register_bound(
|
||||||
|
cause.clone(),
|
||||||
|
wfcx.param_env,
|
||||||
|
potential_self_ty,
|
||||||
|
receiver_trait_def_id,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Without `feature(arbitrary_self_types)`, we require that `receiver_ty` implements `Receiver`.
|
debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty);
|
||||||
if !arbitrary_self_types_enabled
|
false
|
||||||
&& !receiver_is_implemented(wfcx, receiver_trait_def_id, cause.clone(), receiver_ty)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receiver_is_implemented<'tcx>(
|
fn receiver_is_implemented<'tcx>(
|
||||||
|
|
Loading…
Reference in New Issue