rustc_trait_selection/traits/
wf.rs

1use std::iter;
2
3use rustc_hir as hir;
4use rustc_hir::lang_items::LangItem;
5use rustc_infer::traits::{ObligationCauseCode, PredicateObligations};
6use rustc_middle::bug;
7use rustc_middle::ty::{
8    self, GenericArg, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable,
9    TypeVisitable, TypeVisitableExt, TypeVisitor,
10};
11use rustc_session::parse::feature_err;
12use rustc_span::def_id::{DefId, LocalDefId};
13use rustc_span::{Span, sym};
14use tracing::{debug, instrument, trace};
15
16use crate::infer::InferCtxt;
17use crate::traits;
18/// Returns the set of obligations needed to make `arg` well-formed.
19/// If `arg` contains unresolved inference variables, this may include
20/// further WF obligations. However, if `arg` IS an unresolved
21/// inference variable, returns `None`, because we are not able to
22/// make any progress at all. This is to prevent "livelock" where we
23/// say "$0 is WF if $0 is WF".
24pub fn obligations<'tcx>(
25    infcx: &InferCtxt<'tcx>,
26    param_env: ty::ParamEnv<'tcx>,
27    body_id: LocalDefId,
28    recursion_depth: usize,
29    arg: GenericArg<'tcx>,
30    span: Span,
31) -> Option<PredicateObligations<'tcx>> {
32    // Handle the "livelock" case (see comment above) by bailing out if necessary.
33    let arg = match arg.unpack() {
34        GenericArgKind::Type(ty) => {
35            match ty.kind() {
36                ty::Infer(ty::TyVar(_)) => {
37                    let resolved_ty = infcx.shallow_resolve(ty);
38                    if resolved_ty == ty {
39                        // No progress, bail out to prevent "livelock".
40                        return None;
41                    } else {
42                        resolved_ty
43                    }
44                }
45                _ => ty,
46            }
47            .into()
48        }
49        GenericArgKind::Const(ct) => {
50            match ct.kind() {
51                ty::ConstKind::Infer(_) => {
52                    let resolved = infcx.shallow_resolve_const(ct);
53                    if resolved == ct {
54                        // No progress.
55                        return None;
56                    } else {
57                        resolved
58                    }
59                }
60                _ => ct,
61            }
62            .into()
63        }
64        // There is nothing we have to do for lifetimes.
65        GenericArgKind::Lifetime(..) => return Some(PredicateObligations::new()),
66    };
67
68    let mut wf = WfPredicates {
69        infcx,
70        param_env,
71        body_id,
72        span,
73        out: PredicateObligations::new(),
74        recursion_depth,
75        item: None,
76    };
77    wf.compute(arg);
78    debug!("wf::obligations({:?}, body_id={:?}) = {:?}", arg, body_id, wf.out);
79
80    let result = wf.normalize(infcx);
81    debug!("wf::obligations({:?}, body_id={:?}) ~~> {:?}", arg, body_id, result);
82    Some(result)
83}
84
85/// Compute the predicates that are required for a type to be well-formed.
86///
87/// This is only intended to be used in the new solver, since it does not
88/// take into account recursion depth or proper error-reporting spans.
89pub fn unnormalized_obligations<'tcx>(
90    infcx: &InferCtxt<'tcx>,
91    param_env: ty::ParamEnv<'tcx>,
92    arg: GenericArg<'tcx>,
93    span: Span,
94    body_id: LocalDefId,
95) -> Option<PredicateObligations<'tcx>> {
96    debug_assert_eq!(arg, infcx.resolve_vars_if_possible(arg));
97
98    // However, if `arg` IS an unresolved inference variable, returns `None`,
99    // because we are not able to make any progress at all. This is to prevent
100    // "livelock" where we say "$0 is WF if $0 is WF".
101    if arg.is_non_region_infer() {
102        return None;
103    }
104
105    if let ty::GenericArgKind::Lifetime(..) = arg.unpack() {
106        return Some(PredicateObligations::new());
107    }
108
109    let mut wf = WfPredicates {
110        infcx,
111        param_env,
112        body_id,
113        span,
114        out: PredicateObligations::new(),
115        recursion_depth: 0,
116        item: None,
117    };
118    wf.compute(arg);
119    Some(wf.out)
120}
121
122/// Returns the obligations that make this trait reference
123/// well-formed. For example, if there is a trait `Set` defined like
124/// `trait Set<K: Eq>`, then the trait bound `Foo: Set<Bar>` is WF
125/// if `Bar: Eq`.
126pub fn trait_obligations<'tcx>(
127    infcx: &InferCtxt<'tcx>,
128    param_env: ty::ParamEnv<'tcx>,
129    body_id: LocalDefId,
130    trait_pred: ty::TraitPredicate<'tcx>,
131    span: Span,
132    item: &'tcx hir::Item<'tcx>,
133) -> PredicateObligations<'tcx> {
134    let mut wf = WfPredicates {
135        infcx,
136        param_env,
137        body_id,
138        span,
139        out: PredicateObligations::new(),
140        recursion_depth: 0,
141        item: Some(item),
142    };
143    wf.compute_trait_pred(trait_pred, Elaborate::All);
144    debug!(obligations = ?wf.out);
145    wf.normalize(infcx)
146}
147
148/// Returns the requirements for `clause` to be well-formed.
149///
150/// For example, if there is a trait `Set` defined like
151/// `trait Set<K: Eq>`, then the trait bound `Foo: Set<Bar>` is WF
152/// if `Bar: Eq`.
153#[instrument(skip(infcx), ret)]
154pub fn clause_obligations<'tcx>(
155    infcx: &InferCtxt<'tcx>,
156    param_env: ty::ParamEnv<'tcx>,
157    body_id: LocalDefId,
158    clause: ty::Clause<'tcx>,
159    span: Span,
160) -> PredicateObligations<'tcx> {
161    let mut wf = WfPredicates {
162        infcx,
163        param_env,
164        body_id,
165        span,
166        out: PredicateObligations::new(),
167        recursion_depth: 0,
168        item: None,
169    };
170
171    // It's ok to skip the binder here because wf code is prepared for it
172    match clause.kind().skip_binder() {
173        ty::ClauseKind::Trait(t) => {
174            wf.compute_trait_pred(t, Elaborate::None);
175        }
176        ty::ClauseKind::HostEffect(..) => {
177            // Technically the well-formedness of this predicate is implied by
178            // the corresponding trait predicate it should've been generated beside.
179        }
180        ty::ClauseKind::RegionOutlives(..) => {}
181        ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
182            wf.compute(ty.into());
183        }
184        ty::ClauseKind::Projection(t) => {
185            wf.compute_alias_term(t.projection_term);
186            wf.compute(t.term.into_arg());
187        }
188        ty::ClauseKind::ConstArgHasType(ct, ty) => {
189            wf.compute(ct.into());
190            wf.compute(ty.into());
191        }
192        ty::ClauseKind::WellFormed(arg) => {
193            wf.compute(arg);
194        }
195
196        ty::ClauseKind::ConstEvaluatable(ct) => {
197            wf.compute(ct.into());
198        }
199    }
200
201    wf.normalize(infcx)
202}
203
204struct WfPredicates<'a, 'tcx> {
205    infcx: &'a InferCtxt<'tcx>,
206    param_env: ty::ParamEnv<'tcx>,
207    body_id: LocalDefId,
208    span: Span,
209    out: PredicateObligations<'tcx>,
210    recursion_depth: usize,
211    item: Option<&'tcx hir::Item<'tcx>>,
212}
213
214/// Controls whether we "elaborate" supertraits and so forth on the WF
215/// predicates. This is a kind of hack to address #43784. The
216/// underlying problem in that issue was a trait structure like:
217///
218/// ```ignore (illustrative)
219/// trait Foo: Copy { }
220/// trait Bar: Foo { }
221/// impl<T: Bar> Foo for T { }
222/// impl<T> Bar for T { }
223/// ```
224///
225/// Here, in the `Foo` impl, we will check that `T: Copy` holds -- but
226/// we decide that this is true because `T: Bar` is in the
227/// where-clauses (and we can elaborate that to include `T:
228/// Copy`). This wouldn't be a problem, except that when we check the
229/// `Bar` impl, we decide that `T: Foo` must hold because of the `Foo`
230/// impl. And so nowhere did we check that `T: Copy` holds!
231///
232/// To resolve this, we elaborate the WF requirements that must be
233/// proven when checking impls. This means that (e.g.) the `impl Bar
234/// for T` will be forced to prove not only that `T: Foo` but also `T:
235/// Copy` (which it won't be able to do, because there is no `Copy`
236/// impl for `T`).
237#[derive(Debug, PartialEq, Eq, Copy, Clone)]
238enum Elaborate {
239    All,
240    None,
241}
242
243/// Points the cause span of a super predicate at the relevant associated type.
244///
245/// Given a trait impl item:
246///
247/// ```ignore (incomplete)
248/// impl TargetTrait for TargetType {
249///    type Assoc = SomeType;
250/// }
251/// ```
252///
253/// And a super predicate of `TargetTrait` that has any of the following forms:
254///
255/// 1. `<OtherType as OtherTrait>::Assoc == <TargetType as TargetTrait>::Assoc`
256/// 2. `<<TargetType as TargetTrait>::Assoc as OtherTrait>::Assoc == OtherType`
257/// 3. `<TargetType as TargetTrait>::Assoc: OtherTrait`
258///
259/// Replace the span of the cause with the span of the associated item:
260///
261/// ```ignore (incomplete)
262/// impl TargetTrait for TargetType {
263///     type Assoc = SomeType;
264/// //               ^^^^^^^^ this span
265/// }
266/// ```
267///
268/// Note that bounds that can be expressed as associated item bounds are **not**
269/// super predicates. This means that form 2 and 3 from above are only relevant if
270/// the [`GenericArgsRef`] of the projection type are not its identity arguments.
271fn extend_cause_with_original_assoc_item_obligation<'tcx>(
272    tcx: TyCtxt<'tcx>,
273    item: Option<&hir::Item<'tcx>>,
274    cause: &mut traits::ObligationCause<'tcx>,
275    pred: ty::Predicate<'tcx>,
276) {
277    debug!(?item, ?cause, ?pred, "extended_cause_with_original_assoc_item_obligation");
278    let (items, impl_def_id) = match item {
279        Some(hir::Item { kind: hir::ItemKind::Impl(impl_), owner_id, .. }) => {
280            (impl_.items, *owner_id)
281        }
282        _ => return,
283    };
284
285    let ty_to_impl_span = |ty: Ty<'_>| {
286        if let ty::Alias(ty::Projection, projection_ty) = ty.kind()
287            && let Some(&impl_item_id) =
288                tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.def_id)
289            && let Some(impl_item) =
290                items.iter().find(|item| item.id.owner_id.to_def_id() == impl_item_id)
291        {
292            Some(tcx.hir().impl_item(impl_item.id).expect_type().span)
293        } else {
294            None
295        }
296    };
297
298    // It is fine to skip the binder as we don't care about regions here.
299    match pred.kind().skip_binder() {
300        ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) => {
301            // Form 1: The obligation comes not from the current `impl` nor the `trait` being
302            // implemented, but rather from a "second order" obligation, where an associated
303            // type has a projection coming from another associated type.
304            // See `tests/ui/traits/assoc-type-in-superbad.rs` for an example.
305            if let Some(term_ty) = proj.term.as_type()
306                && let Some(impl_item_span) = ty_to_impl_span(term_ty)
307            {
308                cause.span = impl_item_span;
309            }
310
311            // Form 2: A projection obligation for an associated item failed to be met.
312            // We overwrite the span from above to ensure that a bound like
313            // `Self::Assoc1: Trait<OtherAssoc = Self::Assoc2>` gets the same
314            // span for both obligations that it is lowered to.
315            if let Some(impl_item_span) = ty_to_impl_span(proj.self_ty()) {
316                cause.span = impl_item_span;
317            }
318        }
319
320        ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
321            // Form 3: A trait obligation for an associated item failed to be met.
322            debug!("extended_cause_with_original_assoc_item_obligation trait proj {:?}", pred);
323            if let Some(impl_item_span) = ty_to_impl_span(pred.self_ty()) {
324                cause.span = impl_item_span;
325            }
326        }
327        _ => {}
328    }
329}
330
331impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
332    fn tcx(&self) -> TyCtxt<'tcx> {
333        self.infcx.tcx
334    }
335
336    fn cause(&self, code: traits::ObligationCauseCode<'tcx>) -> traits::ObligationCause<'tcx> {
337        traits::ObligationCause::new(self.span, self.body_id, code)
338    }
339
340    fn normalize(self, infcx: &InferCtxt<'tcx>) -> PredicateObligations<'tcx> {
341        // Do not normalize `wf` obligations with the new solver.
342        //
343        // The current deep normalization routine with the new solver does not
344        // handle ambiguity and the new solver correctly deals with unnnormalized goals.
345        // If the user relies on normalized types, e.g. for `fn implied_outlives_bounds`,
346        // it is their responsibility to normalize while avoiding ambiguity.
347        if infcx.next_trait_solver() {
348            return self.out;
349        }
350
351        let cause = self.cause(ObligationCauseCode::WellFormed(None));
352        let param_env = self.param_env;
353        let mut obligations = PredicateObligations::with_capacity(self.out.len());
354        for mut obligation in self.out {
355            assert!(!obligation.has_escaping_bound_vars());
356            let mut selcx = traits::SelectionContext::new(infcx);
357            // Don't normalize the whole obligation, the param env is either
358            // already normalized, or we're currently normalizing the
359            // param_env. Either way we should only normalize the predicate.
360            let normalized_predicate = traits::normalize::normalize_with_depth_to(
361                &mut selcx,
362                param_env,
363                cause.clone(),
364                self.recursion_depth,
365                obligation.predicate,
366                &mut obligations,
367            );
368            obligation.predicate = normalized_predicate;
369            obligations.push(obligation);
370        }
371        obligations
372    }
373
374    /// Pushes the obligations required for `trait_ref` to be WF into `self.out`.
375    fn compute_trait_pred(&mut self, trait_pred: ty::TraitPredicate<'tcx>, elaborate: Elaborate) {
376        let tcx = self.tcx();
377        let trait_ref = trait_pred.trait_ref;
378
379        // Negative trait predicates don't require supertraits to hold, just
380        // that their args are WF.
381        if trait_pred.polarity == ty::PredicatePolarity::Negative {
382            self.compute_negative_trait_pred(trait_ref);
383            return;
384        }
385
386        // if the trait predicate is not const, the wf obligations should not be const as well.
387        let obligations = self.nominal_obligations(trait_ref.def_id, trait_ref.args);
388
389        debug!("compute_trait_pred obligations {:?}", obligations);
390        let param_env = self.param_env;
391        let depth = self.recursion_depth;
392
393        let item = self.item;
394
395        let extend = |traits::PredicateObligation { predicate, mut cause, .. }| {
396            if let Some(parent_trait_pred) = predicate.as_trait_clause() {
397                cause = cause.derived_cause(
398                    parent_trait_pred,
399                    traits::ObligationCauseCode::WellFormedDerived,
400                );
401            }
402            extend_cause_with_original_assoc_item_obligation(tcx, item, &mut cause, predicate);
403            traits::Obligation::with_depth(tcx, cause, depth, param_env, predicate)
404        };
405
406        if let Elaborate::All = elaborate {
407            let implied_obligations = traits::util::elaborate(tcx, obligations);
408            let implied_obligations = implied_obligations.map(extend);
409            self.out.extend(implied_obligations);
410        } else {
411            self.out.extend(obligations);
412        }
413
414        self.out.extend(
415            trait_ref
416                .args
417                .iter()
418                .enumerate()
419                .filter(|(_, arg)| {
420                    matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
421                })
422                .filter(|(_, arg)| !arg.has_escaping_bound_vars())
423                .map(|(i, arg)| {
424                    let mut cause = traits::ObligationCause::misc(self.span, self.body_id);
425                    // The first arg is the self ty - use the correct span for it.
426                    if i == 0 {
427                        if let Some(hir::ItemKind::Impl(hir::Impl { self_ty, .. })) =
428                            item.map(|i| &i.kind)
429                        {
430                            cause.span = self_ty.span;
431                        }
432                    }
433                    traits::Obligation::with_depth(
434                        tcx,
435                        cause,
436                        depth,
437                        param_env,
438                        ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
439                            arg,
440                        ))),
441                    )
442                }),
443        );
444    }
445
446    // Compute the obligations that are required for `trait_ref` to be WF,
447    // given that it is a *negative* trait predicate.
448    fn compute_negative_trait_pred(&mut self, trait_ref: ty::TraitRef<'tcx>) {
449        for arg in trait_ref.args {
450            self.compute(arg);
451        }
452    }
453
454    /// Pushes the obligations required for an alias (except inherent) to be WF
455    /// into `self.out`.
456    fn compute_alias_term(&mut self, data: ty::AliasTerm<'tcx>) {
457        // A projection is well-formed if
458        //
459        // (a) its predicates hold (*)
460        // (b) its args are wf
461        //
462        // (*) The predicates of an associated type include the predicates of
463        //     the trait that it's contained in. For example, given
464        //
465        // trait A<T>: Clone {
466        //     type X where T: Copy;
467        // }
468        //
469        // The predicates of `<() as A<i32>>::X` are:
470        // [
471        //     `(): Sized`
472        //     `(): Clone`
473        //     `(): A<i32>`
474        //     `i32: Sized`
475        //     `i32: Clone`
476        //     `i32: Copy`
477        // ]
478        let obligations = self.nominal_obligations(data.def_id, data.args);
479        self.out.extend(obligations);
480
481        self.compute_projection_args(data.args);
482    }
483
484    /// Pushes the obligations required for an inherent alias to be WF
485    /// into `self.out`.
486    // FIXME(inherent_associated_types): Merge this function with `fn compute_alias`.
487    fn compute_inherent_projection(&mut self, data: ty::AliasTy<'tcx>) {
488        // An inherent projection is well-formed if
489        //
490        // (a) its predicates hold (*)
491        // (b) its args are wf
492        //
493        // (*) The predicates of an inherent associated type include the
494        //     predicates of the impl that it's contained in.
495
496        if !data.self_ty().has_escaping_bound_vars() {
497            // FIXME(inherent_associated_types): Should this happen inside of a snapshot?
498            // FIXME(inherent_associated_types): This is incompatible with the new solver and lazy norm!
499            let args = traits::project::compute_inherent_assoc_ty_args(
500                &mut traits::SelectionContext::new(self.infcx),
501                self.param_env,
502                data,
503                self.cause(ObligationCauseCode::WellFormed(None)),
504                self.recursion_depth,
505                &mut self.out,
506            );
507            let obligations = self.nominal_obligations(data.def_id, args);
508            self.out.extend(obligations);
509        }
510
511        data.args.visit_with(self);
512    }
513
514    fn compute_projection_args(&mut self, args: GenericArgsRef<'tcx>) {
515        let tcx = self.tcx();
516        let cause = self.cause(ObligationCauseCode::WellFormed(None));
517        let param_env = self.param_env;
518        let depth = self.recursion_depth;
519
520        self.out.extend(
521            args.iter()
522                .filter(|arg| {
523                    matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
524                })
525                .filter(|arg| !arg.has_escaping_bound_vars())
526                .map(|arg| {
527                    traits::Obligation::with_depth(
528                        tcx,
529                        cause.clone(),
530                        depth,
531                        param_env,
532                        ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
533                            arg,
534                        ))),
535                    )
536                }),
537        );
538    }
539
540    fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) {
541        if !subty.has_escaping_bound_vars() {
542            let cause = self.cause(cause);
543            let trait_ref = ty::TraitRef::new(
544                self.tcx(),
545                self.tcx().require_lang_item(LangItem::Sized, Some(cause.span)),
546                [subty],
547            );
548            self.out.push(traits::Obligation::with_depth(
549                self.tcx(),
550                cause,
551                self.recursion_depth,
552                self.param_env,
553                ty::Binder::dummy(trait_ref),
554            ));
555        }
556    }
557
558    /// Pushes all the predicates needed to validate that `ty` is WF into `out`.
559    #[instrument(level = "debug", skip(self))]
560    fn compute(&mut self, arg: GenericArg<'tcx>) {
561        arg.visit_with(self);
562        debug!(?self.out);
563    }
564
565    #[instrument(level = "debug", skip(self))]
566    fn nominal_obligations(
567        &mut self,
568        def_id: DefId,
569        args: GenericArgsRef<'tcx>,
570    ) -> PredicateObligations<'tcx> {
571        let predicates = self.tcx().predicates_of(def_id);
572        let mut origins = vec![def_id; predicates.predicates.len()];
573        let mut head = predicates;
574        while let Some(parent) = head.parent {
575            head = self.tcx().predicates_of(parent);
576            origins.extend(iter::repeat(parent).take(head.predicates.len()));
577        }
578
579        let predicates = predicates.instantiate(self.tcx(), args);
580        trace!("{:#?}", predicates);
581        debug_assert_eq!(predicates.predicates.len(), origins.len());
582
583        iter::zip(predicates, origins.into_iter().rev())
584            .map(|((pred, span), origin_def_id)| {
585                let code = ObligationCauseCode::WhereClause(origin_def_id, span);
586                let cause = self.cause(code);
587                traits::Obligation::with_depth(
588                    self.tcx(),
589                    cause,
590                    self.recursion_depth,
591                    self.param_env,
592                    pred,
593                )
594            })
595            .filter(|pred| !pred.has_escaping_bound_vars())
596            .collect()
597    }
598
599    fn from_object_ty(
600        &mut self,
601        ty: Ty<'tcx>,
602        data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
603        region: ty::Region<'tcx>,
604    ) {
605        // Imagine a type like this:
606        //
607        //     trait Foo { }
608        //     trait Bar<'c> : 'c { }
609        //
610        //     &'b (Foo+'c+Bar<'d>)
611        //         ^
612        //
613        // In this case, the following relationships must hold:
614        //
615        //     'b <= 'c
616        //     'd <= 'c
617        //
618        // The first conditions is due to the normal region pointer
619        // rules, which say that a reference cannot outlive its
620        // referent.
621        //
622        // The final condition may be a bit surprising. In particular,
623        // you may expect that it would have been `'c <= 'd`, since
624        // usually lifetimes of outer things are conservative
625        // approximations for inner things. However, it works somewhat
626        // differently with trait objects: here the idea is that if the
627        // user specifies a region bound (`'c`, in this case) it is the
628        // "master bound" that *implies* that bounds from other traits are
629        // all met. (Remember that *all bounds* in a type like
630        // `Foo+Bar+Zed` must be met, not just one, hence if we write
631        // `Foo<'x>+Bar<'y>`, we know that the type outlives *both* 'x and
632        // 'y.)
633        //
634        // Note: in fact we only permit builtin traits, not `Bar<'d>`, I
635        // am looking forward to the future here.
636        if !data.has_escaping_bound_vars() && !region.has_escaping_bound_vars() {
637            let implicit_bounds = object_region_bounds(self.tcx(), data);
638
639            let explicit_bound = region;
640
641            self.out.reserve(implicit_bounds.len());
642            for implicit_bound in implicit_bounds {
643                let cause = self.cause(ObligationCauseCode::ObjectTypeBound(ty, explicit_bound));
644                let outlives =
645                    ty::Binder::dummy(ty::OutlivesPredicate(explicit_bound, implicit_bound));
646                self.out.push(traits::Obligation::with_depth(
647                    self.tcx(),
648                    cause,
649                    self.recursion_depth,
650                    self.param_env,
651                    outlives,
652                ));
653            }
654        }
655    }
656}
657
658impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
659    fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
660        debug!("wf bounds for t={:?} t.kind={:#?}", t, t.kind());
661
662        let tcx = self.tcx();
663
664        match *t.kind() {
665            ty::Bool
666            | ty::Char
667            | ty::Int(..)
668            | ty::Uint(..)
669            | ty::Float(..)
670            | ty::Error(_)
671            | ty::Str
672            | ty::CoroutineWitness(..)
673            | ty::Never
674            | ty::Param(_)
675            | ty::Bound(..)
676            | ty::Placeholder(..)
677            | ty::Foreign(..) => {
678                // WfScalar, WfParameter, etc
679            }
680
681            // Can only infer to `ty::Int(_) | ty::Uint(_)`.
682            ty::Infer(ty::IntVar(_)) => {}
683
684            // Can only infer to `ty::Float(_)`.
685            ty::Infer(ty::FloatVar(_)) => {}
686
687            ty::Slice(subty) => {
688                self.require_sized(subty, ObligationCauseCode::SliceOrArrayElem);
689            }
690
691            ty::Array(subty, len) => {
692                self.require_sized(subty, ObligationCauseCode::SliceOrArrayElem);
693                // Note that the len being WF is implicitly checked while visiting.
694                // Here we just check that it's of type usize.
695                let cause = self.cause(ObligationCauseCode::ArrayLen(t));
696                self.out.push(traits::Obligation::with_depth(
697                    tcx,
698                    cause,
699                    self.recursion_depth,
700                    self.param_env,
701                    ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(
702                        len,
703                        tcx.types.usize,
704                    ))),
705                ));
706            }
707
708            ty::Pat(subty, pat) => {
709                self.require_sized(subty, ObligationCauseCode::Misc);
710                match *pat {
711                    ty::PatternKind::Range { start, end, include_end: _ } => {
712                        let mut check = |c| {
713                            let cause = self.cause(ObligationCauseCode::Misc);
714                            self.out.push(traits::Obligation::with_depth(
715                                tcx,
716                                cause.clone(),
717                                self.recursion_depth,
718                                self.param_env,
719                                ty::Binder::dummy(ty::PredicateKind::Clause(
720                                    ty::ClauseKind::ConstArgHasType(c, subty),
721                                )),
722                            ));
723                            if !tcx.features().generic_pattern_types() {
724                                if c.has_param() {
725                                    if self.span.is_dummy() {
726                                        self.tcx().dcx().delayed_bug(
727                                            "feature error should be reported elsewhere, too",
728                                        );
729                                    } else {
730                                        feature_err(
731                                            &self.tcx().sess,
732                                            sym::generic_pattern_types,
733                                            self.span,
734                                            "wraparound pattern type ranges cause monomorphization time errors",
735                                        )
736                                        .emit();
737                                    }
738                                }
739                            }
740                        };
741                        if let Some(start) = start {
742                            check(start)
743                        }
744                        if let Some(end) = end {
745                            check(end)
746                        }
747                    }
748                }
749            }
750
751            ty::Tuple(tys) => {
752                if let Some((_last, rest)) = tys.split_last() {
753                    for &elem in rest {
754                        self.require_sized(elem, ObligationCauseCode::TupleElem);
755                    }
756                }
757            }
758
759            ty::RawPtr(_, _) => {
760                // Simple cases that are WF if their type args are WF.
761            }
762
763            ty::Alias(ty::Projection | ty::Opaque | ty::Weak, data) => {
764                let obligations = self.nominal_obligations(data.def_id, data.args);
765                self.out.extend(obligations);
766            }
767            ty::Alias(ty::Inherent, data) => {
768                self.compute_inherent_projection(data);
769                return; // Subtree handled by compute_inherent_projection.
770            }
771
772            ty::Adt(def, args) => {
773                // WfNominalType
774                let obligations = self.nominal_obligations(def.did(), args);
775                self.out.extend(obligations);
776            }
777
778            ty::FnDef(did, args) => {
779                // HACK: Check the return type of function definitions for
780                // well-formedness to mostly fix #84533. This is still not
781                // perfect and there may be ways to abuse the fact that we
782                // ignore requirements with escaping bound vars. That's a
783                // more general issue however.
784                let fn_sig = tcx.fn_sig(did).instantiate(tcx, args);
785                fn_sig.output().skip_binder().visit_with(self);
786
787                let obligations = self.nominal_obligations(did, args);
788                self.out.extend(obligations);
789            }
790
791            ty::Ref(r, rty, _) => {
792                // WfReference
793                if !r.has_escaping_bound_vars() && !rty.has_escaping_bound_vars() {
794                    let cause = self.cause(ObligationCauseCode::ReferenceOutlivesReferent(t));
795                    self.out.push(traits::Obligation::with_depth(
796                        tcx,
797                        cause,
798                        self.recursion_depth,
799                        self.param_env,
800                        ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
801                            ty::OutlivesPredicate(rty, r),
802                        ))),
803                    ));
804                }
805            }
806
807            ty::Coroutine(did, args, ..) => {
808                // Walk ALL the types in the coroutine: this will
809                // include the upvar types as well as the yield
810                // type. Note that this is mildly distinct from
811                // the closure case, where we have to be careful
812                // about the signature of the closure. We don't
813                // have the problem of implied bounds here since
814                // coroutines don't take arguments.
815                let obligations = self.nominal_obligations(did, args);
816                self.out.extend(obligations);
817            }
818
819            ty::Closure(did, args) => {
820                // Note that we cannot skip the generic types
821                // types. Normally, within the fn
822                // body where they are created, the generics will
823                // always be WF, and outside of that fn body we
824                // are not directly inspecting closure types
825                // anyway, except via auto trait matching (which
826                // only inspects the upvar types).
827                // But when a closure is part of a type-alias-impl-trait
828                // then the function that created the defining site may
829                // have had more bounds available than the type alias
830                // specifies. This may cause us to have a closure in the
831                // hidden type that is not actually well formed and
832                // can cause compiler crashes when the user abuses unsafe
833                // code to procure such a closure.
834                // See tests/ui/type-alias-impl-trait/wf_check_closures.rs
835                let obligations = self.nominal_obligations(did, args);
836                self.out.extend(obligations);
837                // Only check the upvar types for WF, not the rest
838                // of the types within. This is needed because we
839                // capture the signature and it may not be WF
840                // without the implied bounds. Consider a closure
841                // like `|x: &'a T|` -- it may be that `T: 'a` is
842                // not known to hold in the creator's context (and
843                // indeed the closure may not be invoked by its
844                // creator, but rather turned to someone who *can*
845                // verify that).
846                //
847                // The special treatment of closures here really
848                // ought not to be necessary either; the problem
849                // is related to #25860 -- there is no way for us
850                // to express a fn type complete with the implied
851                // bounds that it is assuming. I think in reality
852                // the WF rules around fn are a bit messed up, and
853                // that is the rot problem: `fn(&'a T)` should
854                // probably always be WF, because it should be
855                // shorthand for something like `where(T: 'a) {
856                // fn(&'a T) }`, as discussed in #25860.
857                let upvars = args.as_closure().tupled_upvars_ty();
858                return upvars.visit_with(self);
859            }
860
861            ty::CoroutineClosure(did, args) => {
862                // See the above comments. The same apply to coroutine-closures.
863                let obligations = self.nominal_obligations(did, args);
864                self.out.extend(obligations);
865                let upvars = args.as_coroutine_closure().tupled_upvars_ty();
866                return upvars.visit_with(self);
867            }
868
869            ty::FnPtr(..) => {
870                // Let the visitor iterate into the argument/return
871                // types appearing in the fn signature.
872            }
873            ty::UnsafeBinder(ty) => {
874                // FIXME(unsafe_binders): For now, we have no way to express
875                // that a type must be `ManuallyDrop` OR `Copy` (or a pointer).
876                if !ty.has_escaping_bound_vars() {
877                    self.out.push(traits::Obligation::new(
878                        self.tcx(),
879                        self.cause(ObligationCauseCode::Misc),
880                        self.param_env,
881                        ty.map_bound(|ty| {
882                            ty::TraitRef::new(
883                                self.tcx(),
884                                self.tcx().require_lang_item(
885                                    LangItem::BikeshedGuaranteedNoDrop,
886                                    Some(self.span),
887                                ),
888                                [ty],
889                            )
890                        }),
891                    ));
892                }
893
894                // We recurse into the binder below.
895            }
896
897            ty::Dynamic(data, r, _) => {
898                // WfObject
899                //
900                // Here, we defer WF checking due to higher-ranked
901                // regions. This is perhaps not ideal.
902                self.from_object_ty(t, data, r);
903
904                // FIXME(#27579) RFC also considers adding trait
905                // obligations that don't refer to Self and
906                // checking those
907
908                let defer_to_coercion = tcx.features().dyn_compatible_for_dispatch();
909
910                if !defer_to_coercion {
911                    if let Some(principal) = data.principal_def_id() {
912                        self.out.push(traits::Obligation::with_depth(
913                            tcx,
914                            self.cause(ObligationCauseCode::WellFormed(None)),
915                            self.recursion_depth,
916                            self.param_env,
917                            ty::Binder::dummy(ty::PredicateKind::DynCompatible(principal)),
918                        ));
919                    }
920                }
921            }
922
923            // Inference variables are the complicated case, since we don't
924            // know what type they are. We do two things:
925            //
926            // 1. Check if they have been resolved, and if so proceed with
927            //    THAT type.
928            // 2. If not, we've at least simplified things (e.g., we went
929            //    from `Vec<$0>: WF` to `$0: WF`), so we can
930            //    register a pending obligation and keep
931            //    moving. (Goal is that an "inductive hypothesis"
932            //    is satisfied to ensure termination.)
933            // See also the comment on `fn obligations`, describing "livelock"
934            // prevention, which happens before this can be reached.
935            ty::Infer(_) => {
936                let cause = self.cause(ObligationCauseCode::WellFormed(None));
937                self.out.push(traits::Obligation::with_depth(
938                    tcx,
939                    cause,
940                    self.recursion_depth,
941                    self.param_env,
942                    ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
943                        t.into(),
944                    ))),
945                ));
946            }
947        }
948
949        t.super_visit_with(self)
950    }
951
952    fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result {
953        let tcx = self.tcx();
954
955        match c.kind() {
956            ty::ConstKind::Unevaluated(uv) => {
957                if !c.has_escaping_bound_vars() {
958                    let obligations = self.nominal_obligations(uv.def, uv.args);
959                    self.out.extend(obligations);
960
961                    let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(
962                        ty::ClauseKind::ConstEvaluatable(c),
963                    ));
964                    let cause = self.cause(ObligationCauseCode::WellFormed(None));
965                    self.out.push(traits::Obligation::with_depth(
966                        tcx,
967                        cause,
968                        self.recursion_depth,
969                        self.param_env,
970                        predicate,
971                    ));
972                }
973            }
974            ty::ConstKind::Infer(_) => {
975                let cause = self.cause(ObligationCauseCode::WellFormed(None));
976
977                self.out.push(traits::Obligation::with_depth(
978                    tcx,
979                    cause,
980                    self.recursion_depth,
981                    self.param_env,
982                    ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
983                        c.into(),
984                    ))),
985                ));
986            }
987            ty::ConstKind::Expr(_) => {
988                // FIXME(generic_const_exprs): this doesn't verify that given `Expr(N + 1)` the
989                // trait bound `typeof(N): Add<typeof(1)>` holds. This is currently unnecessary
990                // as `ConstKind::Expr` is only produced via normalization of `ConstKind::Unevaluated`
991                // which means that the `DefId` would have been typeck'd elsewhere. However in
992                // the future we may allow directly lowering to `ConstKind::Expr` in which case
993                // we would not be proving bounds we should.
994
995                let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(
996                    ty::ClauseKind::ConstEvaluatable(c),
997                ));
998                let cause = self.cause(ObligationCauseCode::WellFormed(None));
999                self.out.push(traits::Obligation::with_depth(
1000                    tcx,
1001                    cause,
1002                    self.recursion_depth,
1003                    self.param_env,
1004                    predicate,
1005                ));
1006            }
1007
1008            ty::ConstKind::Error(_)
1009            | ty::ConstKind::Param(_)
1010            | ty::ConstKind::Bound(..)
1011            | ty::ConstKind::Placeholder(..) => {
1012                // These variants are trivially WF, so nothing to do here.
1013            }
1014            ty::ConstKind::Value(..) => {
1015                // FIXME: Enforce that values are structurally-matchable.
1016            }
1017        }
1018
1019        c.super_visit_with(self)
1020    }
1021
1022    fn visit_predicate(&mut self, _p: ty::Predicate<'tcx>) -> Self::Result {
1023        bug!("predicate should not be checked for well-formedness");
1024    }
1025}
1026
1027/// Given an object type like `SomeTrait + Send`, computes the lifetime
1028/// bounds that must hold on the elided self type. These are derived
1029/// from the declarations of `SomeTrait`, `Send`, and friends -- if
1030/// they declare `trait SomeTrait : 'static`, for example, then
1031/// `'static` would appear in the list.
1032///
1033/// N.B., in some cases, particularly around higher-ranked bounds,
1034/// this function returns a kind of conservative approximation.
1035/// That is, all regions returned by this function are definitely
1036/// required, but there may be other region bounds that are not
1037/// returned, as well as requirements like `for<'a> T: 'a`.
1038///
1039/// Requires that trait definitions have been processed so that we can
1040/// elaborate predicates and walk supertraits.
1041pub fn object_region_bounds<'tcx>(
1042    tcx: TyCtxt<'tcx>,
1043    existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
1044) -> Vec<ty::Region<'tcx>> {
1045    let erased_self_ty = tcx.types.trait_object_dummy_self;
1046
1047    let predicates =
1048        existential_predicates.iter().map(|predicate| predicate.with_self_ty(tcx, erased_self_ty));
1049
1050    traits::elaborate(tcx, predicates)
1051        .filter_map(|pred| {
1052            debug!(?pred);
1053            match pred.kind().skip_binder() {
1054                ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => {
1055                    // Search for a bound of the form `erased_self_ty
1056                    // : 'a`, but be wary of something like `for<'a>
1057                    // erased_self_ty : 'a` (we interpret a
1058                    // higher-ranked bound like that as 'static,
1059                    // though at present the code in `fulfill.rs`
1060                    // considers such bounds to be unsatisfiable, so
1061                    // it's kind of a moot point since you could never
1062                    // construct such an object, but this seems
1063                    // correct even if that code changes).
1064                    if t == &erased_self_ty && !r.has_escaping_bound_vars() {
1065                        Some(*r)
1066                    } else {
1067                        None
1068                    }
1069                }
1070                ty::ClauseKind::Trait(_)
1071                | ty::ClauseKind::HostEffect(..)
1072                | ty::ClauseKind::RegionOutlives(_)
1073                | ty::ClauseKind::Projection(_)
1074                | ty::ClauseKind::ConstArgHasType(_, _)
1075                | ty::ClauseKind::WellFormed(_)
1076                | ty::ClauseKind::ConstEvaluatable(_) => None,
1077            }
1078        })
1079        .collect()
1080}