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() {
                    if !t.has_escaping_bound_vars() {
                        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,
                            ));
                        }
                    }
                }

Review comment (refactor):
can you move this out of the for loop? I think it'd read nicer as we don't care about anything to do with wf of the trait object if it has bound vars, whereas currently it sort of reads like this check is dependent on information about each project (which is not true)

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,
                            ));
                        }
                    }
                }