diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs index 8ab9686f6f8..3ecb5e6d296 100644 --- a/src/librustc_typeck/outlives/implicit_infer.rs +++ b/src/librustc_typeck/outlives/implicit_infer.rs @@ -12,7 +12,7 @@ use rustc::hir; use rustc::hir::def_id::DefId; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::subst::{Kind, Subst, UnpackedKind}; -use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; +use rustc::ty::{self, Ty, TyCtxt}; use rustc::util::nodemap::FxHashMap; use super::explicit::ExplicitPredicatesMap; @@ -191,7 +191,7 @@ fn insert_required_predicates_to_be_wf<'tcx>( substs, required_predicates, explicit_map, - false, + IgnoreSelfTy(false), ); } @@ -199,35 +199,27 @@ fn insert_required_predicates_to_be_wf<'tcx>( // This corresponds to `dyn Trait<..>`. In this case, we should // use the explicit predicates as well. - // We are passing type `ty` as a placeholder value with the function - // `with_self_ty`, since there is no concrete type `Self` for a - // `dyn Trait` at this stage. Therefore when checking explicit - // predicates in `check_explicit_predicates` we need to ignore - // checking the explicit_map for Self type. debug!("Dynamic"); debug!("field_ty = {}", &field_ty); debug!("ty in field = {}", &ty); if let Some(ex_trait_ref) = obj.principal() { - // The method `has_escaping_regions` checks if - // there are any late-bound regions, which is - // the lifetime `'r`. It is safe to ignore - // these since `'r` is not in scope for `Foo`. - // - // ``` - // struct Foo { - // bar: for<'r> Fn(usize, &'r FnMut()) - // } - // ``` - if !ty.has_escaping_regions() { - check_explicit_predicates( - tcx, - &ex_trait_ref.skip_binder().def_id, - ex_trait_ref.with_self_ty(tcx, ty).skip_binder().substs, - required_predicates, - explicit_map, - true, - ); - } + // Here, we are passing the type `usize` as a + // placeholder value with the function + // `with_self_ty`, since there is no concrete type + // `Self` for a `dyn Trait` at this + // stage. Therefore when checking explicit + // predicates in `check_explicit_predicates` we + // need to ignore checking the explicit_map for + // Self type. + let substs = ex_trait_ref.with_self_ty(tcx, tcx.types.usize).skip_binder().substs; + check_explicit_predicates( + tcx, + &ex_trait_ref.skip_binder().def_id, + substs, + required_predicates, + explicit_map, + IgnoreSelfTy(true), + ); } } @@ -241,7 +233,7 @@ fn insert_required_predicates_to_be_wf<'tcx>( obj.substs, required_predicates, explicit_map, - false, + IgnoreSelfTy(false), ); } @@ -250,6 +242,8 @@ fn insert_required_predicates_to_be_wf<'tcx>( } } +pub struct IgnoreSelfTy(bool); + /// We also have to check the explicit predicates /// declared on the type. /// @@ -271,7 +265,7 @@ pub fn check_explicit_predicates<'tcx>( substs: &[Kind<'tcx>], required_predicates: &mut RequiredPredicates<'tcx>, explicit_map: &mut ExplicitPredicatesMap<'tcx>, - ignore_self_ty: bool, + ignore_self_ty: IgnoreSelfTy, ) { debug!("def_id = {:?}", &def_id); debug!("substs = {:?}", &substs); @@ -309,7 +303,7 @@ pub fn check_explicit_predicates<'tcx>( // to apply the substs, and not filter this predicate, we might then falsely // conclude that e.g. `X: 'x` was a reasonable inferred requirement. if let UnpackedKind::Type(ty) = outlives_predicate.0.unpack() { - if ty.is_self() && ignore_self_ty { + if ty.is_self() && ignore_self_ty.0 { debug!("skipping self ty = {:?}", &ty); continue; } @@ -319,5 +313,4 @@ pub fn check_explicit_predicates<'tcx>( debug!("predicate = {:?}", &predicate); insert_outlives_predicate(tcx, predicate.0.into(), predicate.1, required_predicates); } - // } }