Skip to content

Commit e21624d

Browse files
committed
Add bound_predicates_of and bound_explicit_predicates_of
1 parent 4493a0f commit e21624d

File tree

5 files changed

+58
-42
lines changed

5 files changed

+58
-42
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ use rustc_middle::mir::{
1616
FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
1717
ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
1818
};
19-
use rustc_middle::ty::{
20-
self, subst::Subst, suggest_constraining_type_params, EarlyBinder, PredicateKind, Ty,
21-
};
19+
use rustc_middle::ty::{self, subst::Subst, suggest_constraining_type_params, PredicateKind, Ty};
2220
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
2321
use rustc_span::def_id::LocalDefId;
2422
use rustc_span::hygiene::DesugaringKind;
@@ -461,35 +459,37 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
461459
let tcx = self.infcx.tcx;
462460

463461
// Find out if the predicates show that the type is a Fn or FnMut
464-
let find_fn_kind_from_did = |predicates: &[(ty::Predicate<'tcx>, Span)], substs| {
465-
predicates.iter().find_map(|(pred, _)| {
466-
let pred = if let Some(substs) = substs {
467-
EarlyBinder(*pred).subst(tcx, substs).kind().skip_binder()
468-
} else {
469-
pred.kind().skip_binder()
470-
};
471-
if let ty::PredicateKind::Trait(pred) = pred && pred.self_ty() == ty {
462+
let find_fn_kind_from_did =
463+
|predicates: ty::EarlyBinder<&[(ty::Predicate<'tcx>, Span)]>, substs| {
464+
predicates.0.iter().find_map(|(pred, _)| {
465+
let pred = if let Some(substs) = substs {
466+
predicates.rebind(*pred).subst(tcx, substs).kind().skip_binder()
467+
} else {
468+
pred.kind().skip_binder()
469+
};
470+
if let ty::PredicateKind::Trait(pred) = pred && pred.self_ty() == ty {
472471
if Some(pred.def_id()) == tcx.lang_items().fn_trait() {
473472
return Some(hir::Mutability::Not);
474473
} else if Some(pred.def_id()) == tcx.lang_items().fn_mut_trait() {
475474
return Some(hir::Mutability::Mut);
476475
}
477476
}
478-
None
479-
})
480-
};
477+
None
478+
})
479+
};
481480

482481
// If the type is opaque/param/closure, and it is Fn or FnMut, let's suggest (mutably)
483482
// borrowing the type, since `&mut F: FnMut` iff `F: FnMut` and similarly for `Fn`.
484483
// These types seem reasonably opaque enough that they could be substituted with their
485484
// borrowed variants in a function body when we see a move error.
486485
let borrow_level = match ty.kind() {
487486
ty::Param(_) => find_fn_kind_from_did(
488-
tcx.explicit_predicates_of(self.mir_def_id().to_def_id()).predicates,
487+
tcx.bound_explicit_predicates_of(self.mir_def_id().to_def_id())
488+
.map_bound(|p| p.predicates),
489489
None,
490490
),
491491
ty::Opaque(did, substs) => {
492-
find_fn_kind_from_did(tcx.explicit_item_bounds(*did), Some(*substs))
492+
find_fn_kind_from_did(tcx.bound_explicit_item_bounds(*did), Some(*substs))
493493
}
494494
ty::Closure(_, substs) => match substs.as_closure().kind() {
495495
ty::ClosureKind::Fn => Some(hir::Mutability::Not),

compiler/rustc_middle/src/ty/util.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,20 @@ impl<'tcx> TyCtxt<'tcx> {
680680
pub fn bound_const_param_default(self, def_id: DefId) -> ty::EarlyBinder<ty::Const<'tcx>> {
681681
ty::EarlyBinder(self.const_param_default(def_id))
682682
}
683+
684+
pub fn bound_predicates_of(
685+
self,
686+
def_id: DefId,
687+
) -> ty::EarlyBinder<ty::generics::GenericPredicates<'tcx>> {
688+
ty::EarlyBinder(self.predicates_of(def_id))
689+
}
690+
691+
pub fn bound_explicit_predicates_of(
692+
self,
693+
def_id: DefId,
694+
) -> ty::EarlyBinder<ty::generics::GenericPredicates<'tcx>> {
695+
ty::EarlyBinder(self.explicit_predicates_of(def_id))
696+
}
683697
}
684698

685699
struct OpaqueTypeExpander<'tcx> {

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2356,11 +2356,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
23562356
// obligation will normalize to `<$0 as Iterator>::Item = $1` and
23572357
// `$1: Copy`, so we must ensure the obligations are emitted in
23582358
// that order.
2359-
let predicates = tcx.predicates_of(def_id);
2359+
let predicates = tcx.bound_predicates_of(def_id);
23602360
debug!(?predicates);
2361-
assert_eq!(predicates.parent, None);
2362-
let mut obligations = Vec::with_capacity(predicates.predicates.len());
2363-
for (predicate, span) in predicates.predicates {
2361+
assert_eq!(predicates.0.parent, None);
2362+
let mut obligations = Vec::with_capacity(predicates.0.predicates.len());
2363+
for (predicate, span) in predicates.0.predicates {
23642364
let span = *span;
23652365
let cause = cause.clone().derived_cause(parent_trait_pred, |derived| {
23662366
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
@@ -2374,7 +2374,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
23742374
param_env,
23752375
cause.clone(),
23762376
recursion_depth,
2377-
EarlyBinder(*predicate).subst(tcx, substs),
2377+
predicates.rebind(*predicate).subst(tcx, substs),
23782378
&mut obligations,
23792379
);
23802380
obligations.push(Obligation { cause, recursion_depth, param_env, predicate });

compiler/rustc_traits/src/chalk/db.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ impl<'tcx> RustIrDatabase<'tcx> {
5151
where
5252
ty::Predicate<'tcx>: LowerInto<'tcx, std::option::Option<T>>,
5353
{
54-
self.interner
55-
.tcx
56-
.explicit_item_bounds(def_id)
54+
let bounds = self.interner.tcx.bound_explicit_item_bounds(def_id);
55+
bounds
56+
.0
5757
.iter()
58-
.map(|(bound, _)| EarlyBinder(*bound).subst(self.interner.tcx, &bound_vars))
58+
.map(|(bound, _)| bounds.rebind(*bound).subst(self.interner.tcx, &bound_vars))
5959
.filter_map(|bound| LowerInto::<Option<_>>::lower_into(bound, self.interner))
6060
.collect()
6161
}
@@ -268,21 +268,20 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
268268

269269
let where_clauses = self.where_clauses_for(def_id, bound_vars);
270270

271-
let sig = self.interner.tcx.fn_sig(def_id);
271+
let sig = self.interner.tcx.bound_fn_sig(def_id);
272272
let (inputs_and_output, iobinders, _) = crate::chalk::lowering::collect_bound_vars(
273273
self.interner,
274274
self.interner.tcx,
275-
EarlyBinder(sig.inputs_and_output()).subst(self.interner.tcx, bound_vars),
275+
sig.map_bound(|s| s.inputs_and_output()).subst(self.interner.tcx, bound_vars),
276276
);
277277

278278
let argument_types = inputs_and_output[..inputs_and_output.len() - 1]
279279
.iter()
280-
.map(|t| {
281-
EarlyBinder(*t).subst(self.interner.tcx, &bound_vars).lower_into(self.interner)
282-
})
280+
.map(|t| sig.rebind(*t).subst(self.interner.tcx, &bound_vars).lower_into(self.interner))
283281
.collect();
284282

285-
let return_type = EarlyBinder(inputs_and_output[inputs_and_output.len() - 1])
283+
let return_type = sig
284+
.rebind(inputs_and_output[inputs_and_output.len() - 1])
286285
.subst(self.interner.tcx, &bound_vars)
287286
.lower_into(self.interner);
288287

@@ -295,7 +294,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
295294
};
296295
Arc::new(chalk_solve::rust_ir::FnDefDatum {
297296
id: fn_def_id,
298-
sig: sig.lower_into(self.interner),
297+
sig: sig.0.lower_into(self.interner),
299298
binders: chalk_ir::Binders::new(binders, bound),
300299
})
301300
}
@@ -503,12 +502,14 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
503502

504503
let identity_substs = InternalSubsts::identity_for_item(self.interner.tcx, opaque_ty_id.0);
505504

505+
let explicit_item_bounds = self.interner.tcx.bound_explicit_item_bounds(opaque_ty_id.0);
506506
let bounds =
507-
self.interner
508-
.tcx
509-
.explicit_item_bounds(opaque_ty_id.0)
507+
explicit_item_bounds
508+
.0
510509
.iter()
511-
.map(|(bound, _)| EarlyBinder(*bound).subst(self.interner.tcx, &bound_vars))
510+
.map(|(bound, _)| {
511+
explicit_item_bounds.rebind(*bound).subst(self.interner.tcx, &bound_vars)
512+
})
512513
.map(|bound| {
513514
bound.fold_with(&mut ReplaceOpaqueTyFolder {
514515
tcx: self.interner.tcx,

compiler/rustc_typeck/src/check/wfcheck.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use rustc_middle::ty::query::Providers;
1515
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
1616
use rustc_middle::ty::trait_def::TraitSpecializationKind;
1717
use rustc_middle::ty::{
18-
self, AdtKind, DefIdTree, EarlyBinder, GenericParamDefKind, ToPredicate, Ty, TyCtxt,
19-
TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor,
18+
self, AdtKind, DefIdTree, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable,
19+
TypeSuperVisitable, TypeVisitable, TypeVisitor,
2020
};
2121
use rustc_session::parse::feature_err;
2222
use rustc_span::symbol::{sym, Ident, Symbol};
@@ -1295,7 +1295,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
12951295
let infcx = wfcx.infcx;
12961296
let tcx = wfcx.tcx();
12971297

1298-
let predicates = tcx.predicates_of(def_id);
1298+
let predicates = tcx.bound_predicates_of(def_id.to_def_id());
12991299
let generics = tcx.generics_of(def_id);
13001300

13011301
let is_our_default = |def: &ty::GenericParamDef| match def.kind {
@@ -1392,6 +1392,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
13921392

13931393
// Now we build the substituted predicates.
13941394
let default_obligations = predicates
1395+
.0
13951396
.predicates
13961397
.iter()
13971398
.flat_map(|&(pred, sp)| {
@@ -1422,15 +1423,15 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
14221423
}
14231424
let mut param_count = CountParams::default();
14241425
let has_region = pred.visit_with(&mut param_count).is_break();
1425-
let substituted_pred = EarlyBinder(pred).subst(tcx, substs);
1426+
let substituted_pred = predicates.rebind(pred).subst(tcx, substs);
14261427
// Don't check non-defaulted params, dependent defaults (including lifetimes)
14271428
// or preds with multiple params.
14281429
if substituted_pred.has_param_types_or_consts()
14291430
|| param_count.params.len() > 1
14301431
|| has_region
14311432
{
14321433
None
1433-
} else if predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) {
1434+
} else if predicates.0.predicates.iter().any(|&(p, _)| p == substituted_pred) {
14341435
// Avoid duplication of predicates that contain no parameters, for example.
14351436
None
14361437
} else {
@@ -1456,7 +1457,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
14561457
traits::Obligation::new(cause, wfcx.param_env, pred)
14571458
});
14581459

1459-
let predicates = predicates.instantiate_identity(tcx);
1460+
let predicates = predicates.0.instantiate_identity(tcx);
14601461

14611462
let predicates = wfcx.normalize(span, None, predicates);
14621463

0 commit comments

Comments
 (0)