Skip to content

Commit a3f5866

Browse files
committed
Fix the lifetime error in ExplicitSelf
Had to take the infer context as a parameter instead of the type context, so that the function can be called during inference
1 parent 7dff08d commit a3f5866

File tree

3 files changed

+24
-25
lines changed

3 files changed

+24
-25
lines changed

src/librustc_typeck/astconv.rs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use hir::def::Def;
1919
use hir::def_id::DefId;
2020
use middle::resolve_lifetime as rl;
2121
use namespace::Namespace;
22+
use rustc::infer::InferCtxt;
2223
use rustc::ty::subst::{Kind, Subst, Substs};
2324
use rustc::traits;
2425
use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
@@ -1433,26 +1434,21 @@ impl<'tcx> ExplicitSelf<'tcx> {
14331434
/// ```
14341435
///
14351436
pub fn determine<'a, 'gcx>(
1436-
tcx: TyCtxt<'a, 'gcx, 'tcx>,
1437+
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
14371438
param_env: ty::ParamEnv<'tcx>,
1438-
self_ty: Ty<'a>,
1439-
self_arg_ty: Ty<'a>
1439+
self_ty: Ty<'tcx>,
1440+
self_arg_ty: Ty<'tcx>
14401441
) -> ExplicitSelf<'tcx>
14411442
{
14421443
use self::ExplicitSelf::*;
14431444

1444-
tcx.infer_ctxt().enter(|infcx| {
1445-
let can_eq = |expected, actual| {
1446-
let cause = traits::ObligationCause::dummy();
1447-
infcx.at(&cause, param_env).eq(expected, actual).is_ok()
1448-
};
1445+
let can_eq = |expected, actual| infcx.can_eq(param_env, expected, actual).is_ok();
14491446

1450-
match self_arg_ty.sty {
1451-
_ if can_eq(self_arg_ty, self_ty) => ByValue,
1452-
ty::TyRef(region, ty::TypeAndMut { ty, mutbl}) if can_eq(ty, self_ty) => ByReference(region, mutbl),
1453-
ty::TyAdt(def, _) if def.is_box() && can_eq(self_arg_ty.boxed_ty(), self_ty) => ByBox,
1454-
_ => Other
1455-
}
1456-
})
1447+
match self_arg_ty.sty {
1448+
_ if can_eq(self_arg_ty, self_ty) => ByValue,
1449+
ty::TyRef(region, ty::TypeAndMut { ty, mutbl}) if can_eq(ty, self_ty) => ByReference(region, mutbl),
1450+
ty::TyAdt(def, _) if def.is_box() && can_eq(self_arg_ty.boxed_ty(), self_ty) => ByBox,
1451+
_ => Other
1452+
}
14571453
}
14581454
}

src/librustc_typeck/check/compare_method.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -505,12 +505,14 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
505505
let self_arg_ty = *tcx.fn_sig(method.def_id).input(0).skip_binder();
506506
let param_env = ty::ParamEnv::empty(Reveal::All);
507507

508-
match ExplicitSelf::determine(tcx, param_env, untransformed_self_ty, self_arg_ty) {
509-
ExplicitSelf::ByValue => "self".to_string(),
510-
ExplicitSelf::ByReference(_, hir::MutImmutable) => "&self".to_string(),
511-
ExplicitSelf::ByReference(_, hir::MutMutable) => "&mut self".to_string(),
512-
_ => format!("self: {}", self_arg_ty)
513-
}
508+
tcx.infer_ctxt().enter(|infcx| {
509+
match ExplicitSelf::determine(&infcx, param_env, untransformed_self_ty, self_arg_ty) {
510+
ExplicitSelf::ByValue => "self".to_string(),
511+
ExplicitSelf::ByReference(_, hir::MutImmutable) => "&self".to_string(),
512+
ExplicitSelf::ByReference(_, hir::MutMutable) => "&mut self".to_string(),
513+
_ => format!("self: {}", self_arg_ty)
514+
}
515+
})
514516
};
515517

516518
match (trait_m.method_has_self_argument, impl_m.method_has_self_argument) {

src/librustc_typeck/check/wfcheck.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -471,25 +471,26 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
471471
let self_arg_ty = sig.inputs()[0];
472472

473473
let cause = fcx.cause(span, ObligationCauseCode::MethodReceiver);
474-
let at = fcx.at(&cause, fcx.param_env);
474+
let eq = |expected, actual| fcx.at(&cause, fcx.param_env).eq(expected, actual);
475475
let mut autoderef = fcx.autoderef(span, self_arg_ty);
476476

477477
loop {
478478
if let Some((potential_self_ty, _)) = autoderef.next() {
479479
debug!("check_method_receiver: potential self type `{:?}` to match `{:?}`", potential_self_ty, self_ty);
480480

481-
if let Ok(InferOk { obligations, value: () }) = at.eq(self_ty, potential_self_ty) {
481+
if let Ok(InferOk { obligations, value: () }) = eq(self_ty, potential_self_ty) {
482482
fcx.register_predicates(obligations);
483483
autoderef.finalize();
484484
break;
485485
}
486486

487487
} else {
488-
span_err!(fcx.tcx.sess, span, E0307, "invalid self type: {:?}", self_arg_ty);
488+
span_err!(fcx.tcx.sess, span, E0307, "invalid `self` type: {:?}", self_arg_ty);
489+
return;
489490
}
490491
}
491492

492-
if let ExplicitSelf::Other = ExplicitSelf::determine(fcx.tcx, fcx.param_env, self_ty, self_arg_ty) {
493+
if let ExplicitSelf::Other = ExplicitSelf::determine(fcx, fcx.param_env, self_ty, self_arg_ty) {
493494
if !fcx.tcx.sess.features.borrow().arbitrary_self_types {
494495
fcx.tcx.sess.span_err(span, "Arbitrary `self` types are experimental");
495496
}

0 commit comments

Comments
 (0)