Repository: rust-lang/rust
File: compiler/rustc_hir_typeck/src/upvar.rs (Rust)

Code before:

            // Checks if a capture implements any of the auto traits
            let mut obligations_holds_for_capture = Vec::new();
            for check_trait in auto_traits_def_id.iter() {
                obligations_holds_for_capture.push(check_trait.is_some_and(|check_trait| {
                    self.infcx
                        .type_implements_trait(check_trait, [ty], self.param_env)
                        .must_apply_modulo_regions()
                }));
            }

            let mut capture_problems = UnordSet::default();

            // Checks if for any of the auto traits, one or more trait is implemented
            // by the root variable but not by the capture
            for (idx, _) in obligations_should_hold.iter().enumerate() {
                if !obligations_holds_for_capture[idx] && obligations_should_hold[idx] {
                    capture_problems.insert(AUTO_TRAITS[idx]);
                }
            }

            if !capture_problems.is_empty() {
                problematic_captures.insert(
                    UpvarMigrationInfo::CapturingPrecise {
                        source_expr: capture.info.path_expr_id,
                        var_name: self.place_to_string_for_migration(capture),
                    },
                    capture_problems,
                );
            }
        }
        if !problematic_captures.is_empty() {
            return Some(problematic_captures);
        }
        None
    }

    /// Figures out the list of root variables (and their types) that aren't completely
    /// captured by the closure when `capture_disjoint_fields` is enabled and drop order of
    /// some path starting at that root variable **might** be affected.
    ///
    /// The output list would include a root variable if:
    /// - It would have been moved into the closure when `capture_disjoint_fields` wasn't
    ///   enabled, **and**
    /// - It wasn't completely captured by the closure, **and**
    /// - One of the paths starting at this root variable, that is not captured needs Drop.
    ///
    /// This function only returns a HashSet of CapturesInfo for significant drops. If there
    /// are no significant drops than None is returned
    #[instrument(level = "debug", skip(self))]
    fn compute_2229_migrations_for_drop(

Review comment (refactor):
can we move this normalization even further up so that `catpure.place` is already deeply normalized and we don't have to do so here?

Code after:
            obligations_should_hold.push(check_trait.is_some_and(|check_trait| {
                self.infcx
                    .type_implements_trait(check_trait, [ty], self.param_env)
                    .must_apply_modulo_regions()
            }));
        }

        let mut problematic_captures = FxIndexMap::default();
        // Check whether captured fields also implement the trait
        for capture in root_var_min_capture_list.iter() {
            let ty = apply_capture_kind_on_capture_ty(
                self.tcx,
                capture.place.ty(),
                capture.info.capture_kind,
                self.tcx.lifetimes.re_erased,
            );

            // Checks if a capture implements any of the auto traits
            let mut obligations_holds_for_capture = Vec::new();
            for check_trait in auto_traits_def_id.iter() {
                obligations_holds_for_capture.push(check_trait.is_some_and(|check_trait| {
                    self.infcx
                        .type_implements_trait(check_trait, [ty], self.param_env)
                        .must_apply_modulo_regions()
                }));
            }

            let mut capture_problems = UnordSet::default();

            // Checks if for any of the auto traits, one or more trait is implemented
            // by the root variable but not by the capture
            for (idx, _) in obligations_should_hold.iter().enumerate() {
                if !obligations_holds_for_capture[idx] && obligations_should_hold[idx] {
                    capture_problems.insert(AUTO_TRAITS[idx]);
                }
            }

            if !capture_problems.is_empty() {
                problematic_captures.insert(
                    UpvarMigrationInfo::CapturingPrecise {
                        source_expr: capture.info.path_expr_id,
                        var_name: capture.to_string(self.tcx),
                    },
                    capture_problems,
                );
            }
        }
        if !problematic_captures.is_empty() {
            return Some(problematic_captures);
        }
        None