suggest_borrow_generic_arg
: instantiate clauses properly · rust-lang/rust@546ba3d (original) (raw)
`@@ -27,7 +27,7 @@ use rustc_middle::mir::{
`
27
27
`};
`
28
28
`use rustc_middle::ty::print::PrintTraitRefExt as _;
`
29
29
`use rustc_middle::ty::{
`
30
``
`-
self, ClauseKind, PredicateKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, Upcast,
`
``
30
`+
self, PredicateKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, Upcast,
`
31
31
` suggest_constraining_type_params,
`
32
32
`};
`
33
33
`use rustc_middle::util::CallKind;
`
`@@ -649,11 +649,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
`
649
649
`) -> Optionty::Mutability {
`
650
650
`let tcx = self.infcx.tcx;
`
651
651
`let sig = tcx.fn_sig(callee_did).instantiate_identity().skip_binder();
`
652
``
`-
let clauses = tcx.predicates_of(callee_did).instantiate_identity(self.infcx.tcx).predicates;
`
``
652
`+
let clauses = tcx.predicates_of(callee_did);
`
653
653
``
654
654
`` // First, is there at least one method on one of param
's trait bounds?
``
655
655
`` // This keeps us from suggesting borrowing the argument to mem::drop
, e.g.
``
656
``
`-
if !clauses.iter().any(|clause| {
`
``
656
`+
if !clauses.instantiate_identity(tcx).predicates.iter().any(|clause| {
`
657
657
` clause.as_trait_clause().is_some_and(|tc| {
`
658
658
` tc.self_ty().skip_binder().is_param(param.index)
`
659
659
` && tc.polarity() == ty::PredicatePolarity::Positive
`
`@@ -700,23 +700,17 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
`
700
700
`return false;
`
701
701
`}
`
702
702
``
703
``
`-
// Test the callee's predicates, substituting a reference in for the self ty
`
704
``
`` -
// in bounds on param
.
``
705
``
`-
clauses.iter().all(|&clause| {
`
706
``
`-
let clause_for_ref = clause.kind().map_bound(|kind| match kind {
`
707
``
`-
ClauseKind::Trait(c) if c.self_ty().is_param(param.index) => {
`
708
``
`-
ClauseKind::Trait(c.with_self_ty(tcx, ref_ty))
`
709
``
`-
}
`
710
``
`-
ClauseKind::Projection(c) if c.self_ty().is_param(param.index) => {
`
711
``
`-
ClauseKind::Projection(c.with_self_ty(tcx, ref_ty))
`
712
``
`-
}
`
713
``
`-
_ => kind,
`
714
``
`-
});
`
``
703
`` +
// Test the callee's predicates, substituting in ref_ty
for the moved argument type.
``
``
704
`+
clauses.instantiate(tcx, new_args).predicates.iter().all(|&(mut clause)| {
`
``
705
`+
// Normalize before testing to see through type aliases and projections.
`
``
706
`+
if let Ok(normalized) = tcx.try_normalize_erasing_regions(self.param_env, clause) {
`
``
707
`+
clause = normalized;
`
``
708
`+
}
`
715
709
`self.infcx.predicate_must_hold_modulo_regions(&Obligation::new(
`
716
710
` tcx,
`
717
711
`ObligationCause::dummy(),
`
718
712
`self.param_env,
`
719
``
`-
ty::EarlyBinder::bind(clause_for_ref).instantiate(tcx, generic_args),
`
``
713
`+
clause,
`
720
714
`))
`
721
715
`})
`
722
716
`}) {
`