modify ExplicitSelf::determine to take an is_self_type
predicate closure, instead of infcx
This commit is contained in:
parent
1d29966d3b
commit
0b27dcc665
@ -19,7 +19,6 @@ use hir::def::Def;
|
||||
use hir::def_id::DefId;
|
||||
use middle::resolve_lifetime as rl;
|
||||
use namespace::Namespace;
|
||||
use rustc::infer::InferCtxt;
|
||||
use rustc::ty::subst::{Kind, Subst, Substs};
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
|
||||
@ -1415,9 +1414,10 @@ pub enum ExplicitSelf<'tcx> {
|
||||
impl<'tcx> ExplicitSelf<'tcx> {
|
||||
/// Categorizes an explicit self declaration like `self: SomeType`
|
||||
/// into either `self`, `&self`, `&mut self`, `Box<self>`, or
|
||||
/// `Other` (meaning the arbitrary_self_types feature is used).
|
||||
/// We do this here via a combination of pattern matching and
|
||||
/// `can_eq`. A more precise check is done in `check_method_receiver()`.
|
||||
/// `Other`.
|
||||
/// This is mainly used to require the arbitrary_self_types feature
|
||||
/// in the case of `Other`, to improve error messages in the common cases,
|
||||
/// and to make `Other` non-object-safe.
|
||||
///
|
||||
/// Examples:
|
||||
///
|
||||
@ -1436,21 +1436,19 @@ impl<'tcx> ExplicitSelf<'tcx> {
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
pub fn determine<'a, 'gcx>(
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
self_ty: Ty<'tcx>,
|
||||
self_arg_ty: Ty<'tcx>
|
||||
pub fn determine<'a, 'gcx, P>(
|
||||
self_arg_ty: Ty<'tcx>,
|
||||
is_self_ty: P
|
||||
) -> ExplicitSelf<'tcx>
|
||||
where
|
||||
P: Fn(Ty<'tcx>) -> bool
|
||||
{
|
||||
use self::ExplicitSelf::*;
|
||||
|
||||
let can_eq = |expected, actual| infcx.can_eq(param_env, expected, actual).is_ok();
|
||||
|
||||
match self_arg_ty.sty {
|
||||
_ if can_eq(self_arg_ty, self_ty) => ByValue,
|
||||
ty::TyRef(region, ty::TypeAndMut { ty, mutbl}) if can_eq(ty, self_ty) => ByReference(region, mutbl),
|
||||
ty::TyAdt(def, _) if def.is_box() && can_eq(self_arg_ty.boxed_ty(), self_ty) => ByBox,
|
||||
_ if is_self_ty(self_arg_ty) => ByValue,
|
||||
ty::TyRef(region, ty::TypeAndMut { ty, mutbl}) if is_self_ty(ty) => ByReference(region, mutbl),
|
||||
ty::TyAdt(def, _) if def.is_box() && is_self_ty(self_arg_ty.boxed_ty()) => ByBox,
|
||||
_ => Other
|
||||
}
|
||||
}
|
||||
|
@ -506,7 +506,8 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
let param_env = ty::ParamEnv::empty(Reveal::All);
|
||||
|
||||
tcx.infer_ctxt().enter(|infcx| {
|
||||
match ExplicitSelf::determine(&infcx, param_env, untransformed_self_ty, self_arg_ty) {
|
||||
let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty).is_ok();
|
||||
match ExplicitSelf::determine(self_arg_ty, can_eq_self) {
|
||||
ExplicitSelf::ByValue => "self".to_string(),
|
||||
ExplicitSelf::ByReference(_, hir::MutImmutable) => "&self".to_string(),
|
||||
ExplicitSelf::ByReference(_, hir::MutMutable) => "&mut self".to_string(),
|
||||
|
@ -495,7 +495,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
||||
}
|
||||
}
|
||||
|
||||
let self_kind = ExplicitSelf::determine(fcx, fcx.param_env, self_ty, self_arg_ty);
|
||||
let is_self_ty = |ty| fcx.infcx.can_eq(fcx.param_env, self_ty, ty).is_ok();
|
||||
let self_kind = ExplicitSelf::determine(self_arg_ty, is_self_ty);
|
||||
|
||||
if let ExplicitSelf::Other = self_kind {
|
||||
if !fcx.tcx.sess.features.borrow().arbitrary_self_types {
|
||||
|
Loading…
x
Reference in New Issue
Block a user