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

`}) {

`