1 use crate::infer
::InferCtxt
;
2 use crate::opaque_types
::required_region_bounds
;
5 use rustc_hir
::def_id
::DefId
;
6 use rustc_hir
::lang_items
::LangItem
;
7 use rustc_middle
::ty
::subst
::{GenericArg, GenericArgKind, SubstsRef}
;
8 use rustc_middle
::ty
::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}
;
13 /// Returns the set of obligations needed to make `arg` well-formed.
14 /// If `arg` contains unresolved inference variables, this may include
15 /// further WF obligations. However, if `arg` IS an unresolved
16 /// inference variable, returns `None`, because we are not able to
17 /// make any progress at all. This is to prevent "livelock" where we
18 /// say "$0 is WF if $0 is WF".
19 pub fn obligations
<'a
, 'tcx
>(
20 infcx
: &InferCtxt
<'a
, 'tcx
>,
21 param_env
: ty
::ParamEnv
<'tcx
>,
23 recursion_depth
: usize,
24 arg
: GenericArg
<'tcx
>,
26 ) -> Option
<Vec
<traits
::PredicateObligation
<'tcx
>>> {
27 // Handle the "livelock" case (see comment above) by bailing out if necessary.
28 let arg
= match arg
.unpack() {
29 GenericArgKind
::Type(ty
) => {
31 ty
::Infer(ty
::TyVar(_
)) => {
32 let resolved_ty
= infcx
.shallow_resolve(ty
);
33 if resolved_ty
== ty
{
34 // No progress, bail out to prevent "livelock".
44 GenericArgKind
::Const(ct
) => {
46 ty
::ConstKind
::Infer(infer
) => {
47 let resolved
= infcx
.shallow_resolve(infer
);
48 if resolved
== infer
{
53 infcx
.tcx
.mk_const(ty
::Const { val: ty::ConstKind::Infer(resolved), ty: ct.ty }
)
59 // There is nothing we have to do for lifetimes.
60 GenericArgKind
::Lifetime(..) => return Some(Vec
::new()),
64 WfPredicates { infcx, param_env, body_id, span, out: vec![], recursion_depth, item: None }
;
66 debug
!("wf::obligations({:?}, body_id={:?}) = {:?}", arg
, body_id
, wf
.out
);
68 let result
= wf
.normalize();
69 debug
!("wf::obligations({:?}, body_id={:?}) ~~> {:?}", arg
, body_id
, result
);
73 /// Returns the obligations that make this trait reference
74 /// well-formed. For example, if there is a trait `Set` defined like
75 /// `trait Set<K:Eq>`, then the trait reference `Foo: Set<Bar>` is WF
77 pub fn trait_obligations
<'a
, 'tcx
>(
78 infcx
: &InferCtxt
<'a
, 'tcx
>,
79 param_env
: ty
::ParamEnv
<'tcx
>,
81 trait_ref
: &ty
::TraitRef
<'tcx
>,
83 item
: Option
<&'tcx hir
::Item
<'tcx
>>,
84 ) -> Vec
<traits
::PredicateObligation
<'tcx
>> {
86 WfPredicates { infcx, param_env, body_id, span, out: vec![], recursion_depth: 0, item }
;
87 wf
.compute_trait_ref(trait_ref
, Elaborate
::All
);
91 pub fn predicate_obligations
<'a
, 'tcx
>(
92 infcx
: &InferCtxt
<'a
, 'tcx
>,
93 param_env
: ty
::ParamEnv
<'tcx
>,
95 predicate
: ty
::Predicate
<'tcx
>,
97 ) -> Vec
<traits
::PredicateObligation
<'tcx
>> {
98 let mut wf
= WfPredicates
{
108 // It's ok to skip the binder here because wf code is prepared for it
109 match predicate
.skip_binders() {
110 ty
::PredicateAtom
::Trait(t
, _
) => {
111 wf
.compute_trait_ref(&t
.trait_ref
, Elaborate
::None
);
113 ty
::PredicateAtom
::RegionOutlives(..) => {}
114 ty
::PredicateAtom
::TypeOutlives(ty
::OutlivesPredicate(ty
, _reg
)) => {
115 wf
.compute(ty
.into());
117 ty
::PredicateAtom
::Projection(t
) => {
118 wf
.compute_projection(t
.projection_ty
);
119 wf
.compute(t
.ty
.into());
121 ty
::PredicateAtom
::WellFormed(arg
) => {
124 ty
::PredicateAtom
::ObjectSafe(_
) => {}
125 ty
::PredicateAtom
::ClosureKind(..) => {}
126 ty
::PredicateAtom
::Subtype(ty
::SubtypePredicate { a, b, a_is_expected: _ }
) => {
127 wf
.compute(a
.into());
128 wf
.compute(b
.into());
130 ty
::PredicateAtom
::ConstEvaluatable(def
, substs
) => {
131 let obligations
= wf
.nominal_obligations(def
.did
, substs
);
132 wf
.out
.extend(obligations
);
134 for arg
in substs
.iter() {
138 ty
::PredicateAtom
::ConstEquate(c1
, c2
) => {
139 wf
.compute(c1
.into());
140 wf
.compute(c2
.into());
142 ty
::PredicateAtom
::TypeWellFormedFromEnv(..) => {
143 bug
!("TypeWellFormedFromEnv is only used for Chalk")
150 struct WfPredicates
<'a
, 'tcx
> {
151 infcx
: &'a InferCtxt
<'a
, 'tcx
>,
152 param_env
: ty
::ParamEnv
<'tcx
>,
155 out
: Vec
<traits
::PredicateObligation
<'tcx
>>,
156 recursion_depth
: usize,
157 item
: Option
<&'tcx hir
::Item
<'tcx
>>,
160 /// Controls whether we "elaborate" supertraits and so forth on the WF
161 /// predicates. This is a kind of hack to address #43784. The
162 /// underlying problem in that issue was a trait structure like:
165 /// trait Foo: Copy { }
166 /// trait Bar: Foo { }
167 /// impl<T: Bar> Foo for T { }
168 /// impl<T> Bar for T { }
171 /// Here, in the `Foo` impl, we will check that `T: Copy` holds -- but
172 /// we decide that this is true because `T: Bar` is in the
173 /// where-clauses (and we can elaborate that to include `T:
174 /// Copy`). This wouldn't be a problem, except that when we check the
175 /// `Bar` impl, we decide that `T: Foo` must hold because of the `Foo`
176 /// impl. And so nowhere did we check that `T: Copy` holds!
178 /// To resolve this, we elaborate the WF requirements that must be
179 /// proven when checking impls. This means that (e.g.) the `impl Bar
180 /// for T` will be forced to prove not only that `T: Foo` but also `T:
181 /// Copy` (which it won't be able to do, because there is no `Copy`
183 #[derive(Debug, PartialEq, Eq, Copy, Clone)]
189 fn extend_cause_with_original_assoc_item_obligation
<'tcx
>(
191 trait_ref
: &ty
::TraitRef
<'tcx
>,
192 item
: Option
<&hir
::Item
<'tcx
>>,
193 cause
: &mut traits
::ObligationCause
<'tcx
>,
194 pred
: &ty
::Predicate
<'tcx
>,
195 mut trait_assoc_items
: impl Iterator
<Item
= &'tcx ty
::AssocItem
>,
198 "extended_cause_with_original_assoc_item_obligation {:?} {:?} {:?} {:?}",
199 trait_ref
, item
, cause
, pred
201 let items
= match item
{
202 Some(hir
::Item { kind: hir::ItemKind::Impl { items, .. }
, .. }) => items
,
206 |impl_item_ref
: &hir
::ImplItemRef
<'_
>| match tcx
.hir().impl_item(impl_item_ref
.id
).kind
{
207 hir
::ImplItemKind
::Const(ty
, _
) | hir
::ImplItemKind
::TyAlias(ty
) => ty
.span
,
208 _
=> impl_item_ref
.span
,
211 // It is fine to skip the binder as we don't care about regions here.
212 match pred
.skip_binders() {
213 ty
::PredicateAtom
::Projection(proj
) => {
214 // The obligation comes not from the current `impl` nor the `trait` being implemented,
215 // but rather from a "second order" obligation, where an associated type has a
216 // projection coming from another associated type. See
217 // `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs` and
218 // `traits-assoc-type-in-supertrait-bad.rs`.
219 if let ty
::Projection(projection_ty
) = proj
.ty
.kind() {
220 let trait_assoc_item
= tcx
.associated_item(projection_ty
.item_def_id
);
221 if let Some(impl_item_span
) =
222 items
.iter().find(|item
| item
.ident
== trait_assoc_item
.ident
).map(fix_span
)
224 cause
.make_mut().span
= impl_item_span
;
228 ty
::PredicateAtom
::Trait(pred
, _
) => {
229 // An associated item obligation born out of the `trait` failed to be met. An example
230 // can be seen in `ui/associated-types/point-at-type-on-obligation-failure-2.rs`.
231 debug
!("extended_cause_with_original_assoc_item_obligation trait proj {:?}", pred
);
232 if let ty
::Projection(ty
::ProjectionTy { item_def_id, .. }
) = *pred
.self_ty().kind() {
233 if let Some(impl_item_span
) = trait_assoc_items
234 .find(|i
| i
.def_id
== item_def_id
)
235 .and_then(|trait_assoc_item
| {
236 items
.iter().find(|i
| i
.ident
== trait_assoc_item
.ident
).map(fix_span
)
239 cause
.make_mut().span
= impl_item_span
;
247 impl<'a
, 'tcx
> WfPredicates
<'a
, 'tcx
> {
248 fn tcx(&self) -> TyCtxt
<'tcx
> {
252 fn cause(&self, code
: traits
::ObligationCauseCode
<'tcx
>) -> traits
::ObligationCause
<'tcx
> {
253 traits
::ObligationCause
::new(self.span
, self.body_id
, code
)
256 fn normalize(mut self) -> Vec
<traits
::PredicateObligation
<'tcx
>> {
257 let cause
= self.cause(traits
::MiscObligation
);
258 let infcx
= &mut self.infcx
;
259 let param_env
= self.param_env
;
260 let mut obligations
= Vec
::with_capacity(self.out
.len());
261 for mut obligation
in self.out
{
262 assert
!(!obligation
.has_escaping_bound_vars());
263 let mut selcx
= traits
::SelectionContext
::new(infcx
);
264 // Don't normalize the whole obligation, the param env is either
265 // already normalized, or we're currently normalizing the
266 // param_env. Either way we should only normalize the predicate.
267 let normalized_predicate
= traits
::project
::normalize_with_depth_to(
271 self.recursion_depth
,
272 obligation
.predicate
,
275 obligation
.predicate
= normalized_predicate
;
276 obligations
.push(obligation
);
281 /// Pushes the obligations required for `trait_ref` to be WF into `self.out`.
282 fn compute_trait_ref(&mut self, trait_ref
: &ty
::TraitRef
<'tcx
>, elaborate
: Elaborate
) {
283 let tcx
= self.infcx
.tcx
;
284 let obligations
= self.nominal_obligations(trait_ref
.def_id
, trait_ref
.substs
);
286 debug
!("compute_trait_ref obligations {:?}", obligations
);
287 let cause
= self.cause(traits
::MiscObligation
);
288 let param_env
= self.param_env
;
289 let depth
= self.recursion_depth
;
291 let item
= self.item
;
293 let extend
= |obligation
: traits
::PredicateObligation
<'tcx
>| {
294 let mut cause
= cause
.clone();
295 if let Some(parent_trait_ref
) = obligation
.predicate
.to_opt_poly_trait_ref() {
296 let derived_cause
= traits
::DerivedObligationCause
{
297 parent_trait_ref
: parent_trait_ref
.value
,
298 parent_code
: Rc
::new(obligation
.cause
.code
.clone()),
300 cause
.make_mut().code
=
301 traits
::ObligationCauseCode
::DerivedObligation(derived_cause
);
303 extend_cause_with_original_assoc_item_obligation(
308 &obligation
.predicate
,
309 tcx
.associated_items(trait_ref
.def_id
).in_definition_order(),
311 traits
::Obligation
::with_depth(cause
, depth
, param_env
, obligation
.predicate
)
314 if let Elaborate
::All
= elaborate
{
315 let implied_obligations
= traits
::util
::elaborate_obligations(tcx
, obligations
);
316 let implied_obligations
= implied_obligations
.map(extend
);
317 self.out
.extend(implied_obligations
);
319 self.out
.extend(obligations
);
322 let tcx
= self.tcx();
329 matches
!(arg
.unpack(), GenericArgKind
::Type(..) | GenericArgKind
::Const(..))
331 .filter(|(_
, arg
)| !arg
.has_escaping_bound_vars())
333 let mut new_cause
= cause
.clone();
334 // The first subst is the self ty - use the correct span for it.
336 if let Some(hir
::ItemKind
::Impl { self_ty, .. }
) = item
.map(|i
| &i
.kind
) {
337 new_cause
.make_mut().span
= self_ty
.span
;
340 traits
::Obligation
::with_depth(
344 ty
::PredicateAtom
::WellFormed(arg
).to_predicate(tcx
),
350 /// Pushes the obligations required for `trait_ref::Item` to be WF
352 fn compute_projection(&mut self, data
: ty
::ProjectionTy
<'tcx
>) {
353 // A projection is well-formed if
355 // (a) its predicates hold (*)
356 // (b) its substs are wf
358 // (*) The predicates of an associated type include the predicates of
359 // the trait that it's contained in. For example, given
361 // trait A<T>: Clone {
362 // type X where T: Copy;
365 // The predicates of `<() as A<i32>>::X` are:
374 let obligations
= self.nominal_obligations(data
.item_def_id
, data
.substs
);
375 self.out
.extend(obligations
);
377 let tcx
= self.tcx();
378 let cause
= self.cause(traits
::MiscObligation
);
379 let param_env
= self.param_env
;
380 let depth
= self.recursion_depth
;
386 matches
!(arg
.unpack(), GenericArgKind
::Type(..) | GenericArgKind
::Const(..))
388 .filter(|arg
| !arg
.has_escaping_bound_vars())
390 traits
::Obligation
::with_depth(
394 ty
::PredicateAtom
::WellFormed(arg
).to_predicate(tcx
),
400 fn require_sized(&mut self, subty
: Ty
<'tcx
>, cause
: traits
::ObligationCauseCode
<'tcx
>) {
401 if !subty
.has_escaping_bound_vars() {
402 let cause
= self.cause(cause
);
403 let trait_ref
= ty
::TraitRef
{
404 def_id
: self.infcx
.tcx
.require_lang_item(LangItem
::Sized
, None
),
405 substs
: self.infcx
.tcx
.mk_substs_trait(subty
, &[]),
407 self.out
.push(traits
::Obligation
::with_depth(
409 self.recursion_depth
,
411 trait_ref
.without_const().to_predicate(self.infcx
.tcx
),
416 /// Pushes all the predicates needed to validate that `ty` is WF into `out`.
417 fn compute(&mut self, arg
: GenericArg
<'tcx
>) {
418 let mut walker
= arg
.walk();
419 let param_env
= self.param_env
;
420 let depth
= self.recursion_depth
;
421 while let Some(arg
) = walker
.next() {
422 let ty
= match arg
.unpack() {
423 GenericArgKind
::Type(ty
) => ty
,
425 // No WF constraints for lifetimes being present, any outlives
426 // obligations are handled by the parent (e.g. `ty::Ref`).
427 GenericArgKind
::Lifetime(_
) => continue,
429 GenericArgKind
::Const(constant
) => {
431 ty
::ConstKind
::Unevaluated(def
, substs
, promoted
) => {
432 assert
!(promoted
.is_none());
434 let obligations
= self.nominal_obligations(def
.did
, substs
);
435 self.out
.extend(obligations
);
437 let predicate
= ty
::PredicateAtom
::ConstEvaluatable(def
, substs
)
438 .to_predicate(self.tcx());
439 let cause
= self.cause(traits
::MiscObligation
);
440 self.out
.push(traits
::Obligation
::with_depth(
442 self.recursion_depth
,
447 ty
::ConstKind
::Infer(infer
) => {
448 let resolved
= self.infcx
.shallow_resolve(infer
);
449 // the `InferConst` changed, meaning that we made progress.
450 if resolved
!= infer
{
451 let cause
= self.cause(traits
::MiscObligation
);
453 let resolved_constant
= self.infcx
.tcx
.mk_const(ty
::Const
{
454 val
: ty
::ConstKind
::Infer(resolved
),
457 self.out
.push(traits
::Obligation
::with_depth(
459 self.recursion_depth
,
461 ty
::PredicateAtom
::WellFormed(resolved_constant
.into())
462 .to_predicate(self.tcx()),
466 ty
::ConstKind
::Error(_
)
467 | ty
::ConstKind
::Param(_
)
468 | ty
::ConstKind
::Bound(..)
469 | ty
::ConstKind
::Placeholder(..) => {
470 // These variants are trivially WF, so nothing to do here.
472 ty
::ConstKind
::Value(..) => {
473 // FIXME: Enforce that values are structurally-matchable.
488 | ty
::GeneratorWitness(..)
492 | ty
::Placeholder(..)
493 | ty
::Foreign(..) => {
494 // WfScalar, WfParameter, etc
497 // Can only infer to `ty::Int(_) | ty::Uint(_)`.
498 ty
::Infer(ty
::IntVar(_
)) => {}
500 // Can only infer to `ty::Float(_)`.
501 ty
::Infer(ty
::FloatVar(_
)) => {}
503 ty
::Slice(subty
) => {
504 self.require_sized(subty
, traits
::SliceOrArrayElem
);
507 ty
::Array(subty
, _
) => {
508 self.require_sized(subty
, traits
::SliceOrArrayElem
);
509 // Note that we handle the len is implicitly checked while walking `arg`.
512 ty
::Tuple(ref tys
) => {
513 if let Some((_last
, rest
)) = tys
.split_last() {
515 self.require_sized(elem
.expect_ty(), traits
::TupleElem
);
521 // Simple cases that are WF if their type args are WF.
524 ty
::Projection(data
) => {
525 walker
.skip_current_subtree(); // Subtree handled by compute_projection.
526 self.compute_projection(data
);
529 ty
::Adt(def
, substs
) => {
531 let obligations
= self.nominal_obligations(def
.did
, substs
);
532 self.out
.extend(obligations
);
535 ty
::FnDef(did
, substs
) => {
536 let obligations
= self.nominal_obligations(did
, substs
);
537 self.out
.extend(obligations
);
540 ty
::Ref(r
, rty
, _
) => {
542 if !r
.has_escaping_bound_vars() && !rty
.has_escaping_bound_vars() {
543 let cause
= self.cause(traits
::ReferenceOutlivesReferent(ty
));
544 self.out
.push(traits
::Obligation
::with_depth(
548 ty
::PredicateAtom
::TypeOutlives(ty
::OutlivesPredicate(rty
, r
))
549 .to_predicate(self.tcx()),
554 ty
::Generator(..) => {
555 // Walk ALL the types in the generator: this will
556 // include the upvar types as well as the yield
557 // type. Note that this is mildly distinct from
558 // the closure case, where we have to be careful
559 // about the signature of the closure. We don't
560 // have the problem of implied bounds here since
561 // generators don't take arguments.
564 ty
::Closure(_
, substs
) => {
565 // Only check the upvar types for WF, not the rest
566 // of the types within. This is needed because we
567 // capture the signature and it may not be WF
568 // without the implied bounds. Consider a closure
569 // like `|x: &'a T|` -- it may be that `T: 'a` is
570 // not known to hold in the creator's context (and
571 // indeed the closure may not be invoked by its
572 // creator, but rather turned to someone who *can*
575 // The special treatment of closures here really
576 // ought not to be necessary either; the problem
577 // is related to #25860 -- there is no way for us
578 // to express a fn type complete with the implied
579 // bounds that it is assuming. I think in reality
580 // the WF rules around fn are a bit messed up, and
581 // that is the rot problem: `fn(&'a T)` should
582 // probably always be WF, because it should be
583 // shorthand for something like `where(T: 'a) {
584 // fn(&'a T) }`, as discussed in #25860.
586 // Note that we are also skipping the generic
587 // types. This is consistent with the `outlives`
588 // code, but anyway doesn't matter: within the fn
589 // body where they are created, the generics will
590 // always be WF, and outside of that fn body we
591 // are not directly inspecting closure types
592 // anyway, except via auto trait matching (which
593 // only inspects the upvar types).
594 walker
.skip_current_subtree(); // subtree handled below
595 // FIXME(eddyb) add the type to `walker` instead of recursing.
596 self.compute(substs
.as_closure().tupled_upvars_ty().into());
600 // let the loop iterate into the argument/return
601 // types appearing in the fn signature
604 ty
::Opaque(did
, substs
) => {
605 // all of the requirements on type parameters
606 // should've been checked by the instantiation
607 // of whatever returned this exact `impl Trait`.
609 // for named opaque `impl Trait` types we still need to check them
610 if ty
::is_impl_trait_defn(self.infcx
.tcx
, did
).is_none() {
611 let obligations
= self.nominal_obligations(did
, substs
);
612 self.out
.extend(obligations
);
616 ty
::Dynamic(data
, r
) => {
619 // Here, we defer WF checking due to higher-ranked
620 // regions. This is perhaps not ideal.
621 self.from_object_ty(ty
, data
, r
);
623 // FIXME(#27579) RFC also considers adding trait
624 // obligations that don't refer to Self and
627 let defer_to_coercion
= self.tcx().features().object_safe_for_dispatch
;
629 if !defer_to_coercion
{
630 let cause
= self.cause(traits
::MiscObligation
);
631 let component_traits
= data
.auto_traits().chain(data
.principal_def_id());
632 let tcx
= self.tcx();
633 self.out
.extend(component_traits
.map(|did
| {
634 traits
::Obligation
::with_depth(
638 ty
::PredicateAtom
::ObjectSafe(did
).to_predicate(tcx
),
644 // Inference variables are the complicated case, since we don't
645 // know what type they are. We do two things:
647 // 1. Check if they have been resolved, and if so proceed with
649 // 2. If not, we've at least simplified things (e.g., we went
650 // from `Vec<$0>: WF` to `$0: WF`), so we can
651 // register a pending obligation and keep
652 // moving. (Goal is that an "inductive hypothesis"
653 // is satisfied to ensure termination.)
654 // See also the comment on `fn obligations`, describing "livelock"
655 // prevention, which happens before this can be reached.
657 let ty
= self.infcx
.shallow_resolve(ty
);
658 if let ty
::Infer(ty
::TyVar(_
)) = ty
.kind() {
659 // Not yet resolved, but we've made progress.
660 let cause
= self.cause(traits
::MiscObligation
);
661 self.out
.push(traits
::Obligation
::with_depth(
663 self.recursion_depth
,
665 ty
::PredicateAtom
::WellFormed(ty
.into()).to_predicate(self.tcx()),
668 // Yes, resolved, proceed with the result.
669 // FIXME(eddyb) add the type to `walker` instead of recursing.
670 self.compute(ty
.into());
677 fn nominal_obligations(
680 substs
: SubstsRef
<'tcx
>,
681 ) -> Vec
<traits
::PredicateObligation
<'tcx
>> {
682 let predicates
= self.infcx
.tcx
.predicates_of(def_id
);
683 let mut origins
= vec
![def_id
; predicates
.predicates
.len()];
684 let mut head
= predicates
;
685 while let Some(parent
) = head
.parent
{
686 head
= self.infcx
.tcx
.predicates_of(parent
);
687 origins
.extend(iter
::repeat(parent
).take(head
.predicates
.len()));
690 let predicates
= predicates
.instantiate(self.infcx
.tcx
, substs
);
691 debug_assert_eq
!(predicates
.predicates
.len(), origins
.len());
696 .zip(predicates
.spans
.into_iter())
697 .zip(origins
.into_iter().rev())
698 .map(|((pred
, span
), origin_def_id
)| {
699 let cause
= self.cause(traits
::BindingObligation(origin_def_id
, span
));
700 traits
::Obligation
::with_depth(cause
, self.recursion_depth
, self.param_env
, pred
)
702 .filter(|pred
| !pred
.has_escaping_bound_vars())
709 data
: &'tcx ty
::List
<ty
::Binder
<ty
::ExistentialPredicate
<'tcx
>>>,
710 region
: ty
::Region
<'tcx
>,
712 // Imagine a type like this:
715 // trait Bar<'c> : 'c { }
717 // &'b (Foo+'c+Bar<'d>)
720 // In this case, the following relationships must hold:
725 // The first conditions is due to the normal region pointer
726 // rules, which say that a reference cannot outlive its
729 // The final condition may be a bit surprising. In particular,
730 // you may expect that it would have been `'c <= 'd`, since
731 // usually lifetimes of outer things are conservative
732 // approximations for inner things. However, it works somewhat
733 // differently with trait objects: here the idea is that if the
734 // user specifies a region bound (`'c`, in this case) it is the
735 // "master bound" that *implies* that bounds from other traits are
736 // all met. (Remember that *all bounds* in a type like
737 // `Foo+Bar+Zed` must be met, not just one, hence if we write
738 // `Foo<'x>+Bar<'y>`, we know that the type outlives *both* 'x and
741 // Note: in fact we only permit builtin traits, not `Bar<'d>`, I
742 // am looking forward to the future here.
743 if !data
.has_escaping_bound_vars() && !region
.has_escaping_bound_vars() {
744 let implicit_bounds
= object_region_bounds(self.infcx
.tcx
, data
);
746 let explicit_bound
= region
;
748 self.out
.reserve(implicit_bounds
.len());
749 for implicit_bound
in implicit_bounds
{
750 let cause
= self.cause(traits
::ObjectTypeBound(ty
, explicit_bound
));
752 ty
::Binder
::dummy(ty
::OutlivesPredicate(explicit_bound
, implicit_bound
));
753 self.out
.push(traits
::Obligation
::with_depth(
755 self.recursion_depth
,
757 outlives
.to_predicate(self.infcx
.tcx
),
764 /// Given an object type like `SomeTrait + Send`, computes the lifetime
765 /// bounds that must hold on the elided self type. These are derived
766 /// from the declarations of `SomeTrait`, `Send`, and friends -- if
767 /// they declare `trait SomeTrait : 'static`, for example, then
768 /// `'static` would appear in the list. The hard work is done by
769 /// `infer::required_region_bounds`, see that for more information.
770 pub fn object_region_bounds
<'tcx
>(
772 existential_predicates
: &'tcx ty
::List
<ty
::Binder
<ty
::ExistentialPredicate
<'tcx
>>>,
773 ) -> Vec
<ty
::Region
<'tcx
>> {
774 // Since we don't actually *know* the self type for an object,
775 // this "open(err)" serves as a kind of dummy standin -- basically
776 // a placeholder type.
777 let open_ty
= tcx
.mk_ty_infer(ty
::FreshTy(0));
779 let predicates
= existential_predicates
.iter().filter_map(|predicate
| {
780 if let ty
::ExistentialPredicate
::Projection(_
) = predicate
.skip_binder() {
783 Some(predicate
.with_self_ty(tcx
, open_ty
))
787 required_region_bounds(tcx
, open_ty
, predicates
)