Repository: rust-lang/rust
File: compiler/rustc_trait_selection/src/traits/wf.rs (Rust)

Code before:
                // We recurse into the binder below.
            }

            ty::Dynamic(data, r) => {
                // WfObject
                //
                // Here, we defer WF checking due to higher-ranked
                // regions. This is perhaps not ideal.
                self.add_wf_preds_for_dyn_ty(t, data, r);

                // FIXME(#27579) RFC also considers adding trait
                // obligations that don't refer to Self and
                // checking those
                if let Some(principal) = data.principal_def_id() {
                    self.out.push(traits::Obligation::with_depth(
                        tcx,
                        self.cause(ObligationCauseCode::WellFormed(None)),
                        self.recursion_depth,
                        self.param_env,
                        ty::Binder::dummy(ty::PredicateKind::DynCompatible(principal)),
                    ));
                }

                for projection in data.projection_bounds() {
                    let pred_binder = projection
                        .with_self_ty(tcx, tcx.types.trait_object_dummy_self)
                        .map_bound(|p| {
                            p.term.as_const().map(|ct| {
                                let assoc_const_ty = tcx
                                    .type_of(p.projection_term.def_id)
                                    .instantiate(tcx, p.projection_term.args);
                                ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(
                                    ct,
                                    assoc_const_ty,
                                ))
                            })
                        })
                        .transpose();
                    if let Some(pred_binder) = pred_binder {
                        self.out.push(traits::Obligation::with_depth(
                            tcx,
                            self.cause(ObligationCauseCode::WellFormed(None)),
                            self.recursion_depth,
                            self.param_env,
                            pred_binder,
                        ));
                    }
                }
            }

            // Inference variables are the complicated case, since we don't

Review comment (bug):
```suggestion
                        .with_self_ty(tcx, t)
```

I expect using `trait_object_dummy_self` might lead to code on the error-path crashing so we should use the "actual" self type. It also might just lead to weird diagnostics, such as `Infer(FreshTy(0))` appearing in user facing text which we don't want.

Though eventually we'll also support assocaited constants such as `const ASSOC: <Self as Other>::Assoc` at which point `Self` will need to be a real type that implements `Trait` so that we can figure out the type of `Assoc`.

What's going on here is that we have the type `dyn Trait<T, ASSOC = 10>` (for example), and we want to construct `[dyn Trait<T, ASSOC = 10>, T]` as a list of generic arguments to `<T as Trait<U>>::ASSOC` for when we look at the type of `ASSOC`.

Code after:
                // We recurse into the binder below.
            }

            ty::Dynamic(data, r) => {
                // WfObject
                //
                // Here, we defer WF checking due to higher-ranked
                // regions. This is perhaps not ideal.
                self.add_wf_preds_for_dyn_ty(t, data, r);

                // FIXME(#27579) RFC also considers adding trait
                // obligations that don't refer to Self and
                // checking those
                if let Some(principal) = data.principal_def_id() {
                    self.out.push(traits::Obligation::with_depth(
                        tcx,
                        self.cause(ObligationCauseCode::WellFormed(None)),
                        self.recursion_depth,
                        self.param_env,
                        ty::Binder::dummy(ty::PredicateKind::DynCompatible(principal)),
                    ));
                }

                if !t.has_escaping_bound_vars() {
                    for projection in data.projection_bounds() {
                        let pred_binder = projection
                            .with_self_ty(tcx, t)
                            .map_bound(|p| {
                                p.term.as_const().map(|ct| {
                                    let assoc_const_ty = tcx
                                        .type_of(p.projection_term.def_id)
                                        .instantiate(tcx, p.projection_term.args);
                                    ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(
                                        ct,
                                        assoc_const_ty,
                                    ))
                                })
                            })
                            .transpose();
                        if let Some(pred_binder) = pred_binder {
                            self.out.push(traits::Obligation::with_depth(
                                tcx,
                                self.cause(ObligationCauseCode::WellFormed(None)),
                                self.recursion_depth,
                                self.param_env,
                                pred_binder,
                            ));
                        }
                    }
                }
            }