Skip to content

Commit 0bc3382

Browse files
committed
Introduce traits::util::elaborate_predicates_of
1 parent 9506a24 commit 0bc3382

File tree

3 files changed

+87
-107
lines changed

3 files changed

+87
-107
lines changed

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+23-29
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ use rustc_infer::infer::{
1919
error_reporting::unexpected_hidden_region_diagnostic,
2020
BoundRegionConversionTime, NllRegionVariableOrigin, RelateParamBound,
2121
};
22+
use rustc_infer::traits::util::elaborate_predicates_of;
2223
use rustc_middle::hir::place::PlaceBase;
2324
use rustc_middle::mir::{ConstraintCategory, ReturnConstraint};
2425
use rustc_middle::traits::ObligationCauseCode;
2526
use rustc_middle::ty::{self, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeVisitor};
2627
use rustc_span::symbol::{kw, Ident};
2728
use rustc_span::Span;
28-
use rustc_trait_selection::traits;
2929

3030
use crate::borrowck_errors;
3131
use crate::session_diagnostics::{
@@ -646,10 +646,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
646646
let def_id = instance.def_id();
647647
let mut parent = tcx.parent(def_id);
648648
debug!(?def_id, ?parent);
649-
let trait_preds = match tcx.def_kind(parent) {
650-
hir::def::DefKind::Impl { .. } => {
651-
tcx.trait_id_of_impl(parent).map_or(&[][..], |id| tcx.predicates_of(id).predicates)
652-
}
649+
let trait_preds: Vec<_> = match tcx.def_kind(parent) {
650+
hir::def::DefKind::Impl { .. } => tcx
651+
.trait_id_of_impl(parent)
652+
.map_or(vec![], |id| elaborate_predicates_of(tcx, id).collect()),
653653
hir::def::DefKind::Trait => {
654654
let Some(ty) = args.get(0).and_then(|arg| arg.as_type()) else {
655655
return;
@@ -661,9 +661,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
661661
if let [def_id] = impls[..] {
662662
// The method we have is on the trait, but for `parent` we want to analyze the
663663
// relevant impl instead.
664-
let preds = tcx.predicates_of(parent).predicates;
664+
let preds = elaborate_predicates_of(tcx, parent);
665665
parent = def_id;
666-
preds
666+
preds.collect()
667667
} else {
668668
return;
669669
}
@@ -689,30 +689,24 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
689689
// fn foo(&self) where Self: 'static {}
690690
// }
691691
// ```
692-
let mut predicates: Vec<Span> = traits::elaborate(
693-
tcx,
694-
tcx.predicates_of(def_id).predicates.iter().map(|(p, sp)| (p.as_predicate(), *sp)),
695-
)
696-
.chain(traits::elaborate(
697-
tcx,
698-
tcx.predicates_of(parent).predicates.iter().map(|(p, sp)| (p.as_predicate(), *sp)),
699-
))
700-
.chain(traits::elaborate(tcx, trait_preds.iter().map(|(p, sp)| (p.as_predicate(), *sp))))
701-
.filter_map(|(pred, pred_span)| {
702-
if let ty::PredicateKind::Clause(clause) = pred.kind().skip_binder()
703-
&& let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(pred_ty, r)) = clause
704-
&& r.kind() == ty::ReStatic
705-
&& (self.infcx.can_eq(self.param_env, ty, pred_ty)
706-
|| matches!(
692+
let mut predicates: Vec<Span> = elaborate_predicates_of(tcx, def_id)
693+
.chain(elaborate_predicates_of(tcx, parent))
694+
.chain(trait_preds)
695+
.filter_map(|(pred, pred_span)| {
696+
if let ty::PredicateKind::Clause(clause) = pred.kind().skip_binder()
697+
&& let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(pred_ty, r)) = clause
698+
&& r.kind() == ty::ReStatic
699+
&& (self.infcx.can_eq(self.param_env, ty, pred_ty)
700+
|| matches!(
707701
pred_ty.kind(),
708702
ty::Param(name) if name.name == kw::SelfUpper))
709-
{
710-
Some(pred_span)
711-
} else {
712-
None
713-
}
714-
})
715-
.collect();
703+
{
704+
Some(pred_span)
705+
} else {
706+
None
707+
}
708+
})
709+
.collect();
716710
debug!(?predicates);
717711

718712
// Look at the receiver for `&'static self`, which introduces a `'static` obligation.

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+53-78
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ use crate::errors::{self, ObligationCauseFailureCode, TypeErrorAdditionalDiags};
5353
use crate::infer;
5454
use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
5555
use crate::infer::ExpectedFound;
56-
use crate::traits::util::elaborate;
56+
use crate::traits::util::elaborate_predicates_of;
5757
use crate::traits::{
5858
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
5959
PredicateObligation,
@@ -493,36 +493,26 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
493493
// Collect all the `Span`s corresponding to the predicates introducing
494494
// the `sub` lifetime that couldn't be met (sometimes `'static`) on
495495
// both the `trait` and the `impl`.
496-
let spans: Vec<Span> = elaborate(
497-
self.tcx,
498-
self.tcx
499-
.predicates_of(def_id)
500-
.predicates
501-
.iter()
502-
.map(|(p, sp)| (p.as_predicate(), *sp)),
503-
)
504-
.chain(elaborate(
505-
self.tcx,
506-
self.tcx
507-
.predicates_of(generic_param_scope)
508-
.predicates
509-
.iter()
510-
.map(|(p, sp)| (p.as_predicate(), *sp)),
511-
))
512-
.filter_map(|(pred, pred_span)| {
513-
if let ty::PredicateKind::Clause(clause) = pred.kind().skip_binder()
514-
&& let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
515-
_pred_ty,
516-
r,
517-
)) = clause
518-
&& r.kind() == ty::ReStatic
519-
{
520-
Some(pred_span)
521-
} else {
522-
None
523-
}
524-
})
525-
.collect();
496+
let spans: Vec<Span> = elaborate_predicates_of(self.tcx, def_id)
497+
.chain(elaborate_predicates_of(
498+
self.tcx,
499+
generic_param_scope.into(),
500+
))
501+
.filter_map(|(pred, pred_span)| {
502+
if let ty::PredicateKind::Clause(clause) =
503+
pred.kind().skip_binder()
504+
&& let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
505+
_pred_ty,
506+
r,
507+
)) = clause
508+
&& r.kind() == ty::ReStatic
509+
{
510+
Some(pred_span)
511+
} else {
512+
None
513+
}
514+
})
515+
.collect();
526516

527517
if !spans.is_empty() {
528518
let spans_len = spans.len();
@@ -2759,29 +2749,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
27592749
for ptr in poly_trait_refs {
27602750
if let Some(def_id) = ptr.trait_ref.trait_def_id() {
27612751
// Find the bounds on the trait with the lifetime that couldn't be met.
2762-
let bindings: Vec<Span> = elaborate(
2763-
self.tcx,
2764-
self.tcx
2765-
.predicates_of(def_id)
2766-
.predicates
2767-
.iter()
2768-
.map(|(p, sp)| (p.as_predicate(), *sp)),
2769-
)
2770-
.filter_map(|(pred, pred_span)| {
2771-
if let ty::PredicateKind::Clause(clause) =
2772-
pred.kind().skip_binder()
2773-
&& let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
2774-
_pred_ty,
2775-
r,
2776-
)) = clause
2777-
&& r == self.found_region
2778-
{
2779-
Some(pred_span)
2780-
} else {
2781-
None
2782-
}
2783-
})
2784-
.collect();
2752+
let bindings: Vec<Span> = elaborate_predicates_of(self.tcx, def_id)
2753+
.filter_map(|(pred, pred_span)| {
2754+
if let ty::PredicateKind::Clause(clause) =
2755+
pred.kind().skip_binder()
2756+
&& let ty::ClauseKind::TypeOutlives(
2757+
ty::OutlivesPredicate(_pred_ty, r),
2758+
) = clause
2759+
&& r == self.found_region
2760+
{
2761+
Some(pred_span)
2762+
} else {
2763+
None
2764+
}
2765+
})
2766+
.collect();
27852767
if !bindings.is_empty() {
27862768
self.lifetime_spans.insert(ptr.span);
27872769
self.pred_spans.extend(bindings);
@@ -2792,30 +2774,23 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
27922774
// Detect when an associated item is given a lifetime restriction that the
27932775
// definition of that associated item couldn't meet.
27942776
hir::TyKind::Path(hir::QPath::Resolved(Some(_), path)) => {
2795-
self.pred_spans = elaborate(
2796-
self.tcx,
2797-
self.tcx
2798-
.predicates_of(path.res.def_id())
2799-
.predicates
2800-
.iter()
2801-
.map(|(p, sp)| (p.as_predicate(), *sp)),
2802-
)
2803-
.filter_map(|(pred, pred_span)| {
2804-
match pred.kind().skip_binder() {
2805-
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
2806-
ty::OutlivesPredicate(
2807-
// What should I filter this with?
2808-
_pred_ty,
2809-
r,
2810-
),
2811-
)) if r == self.found_region => Some(pred_span),
2812-
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(
2813-
ty::OutlivesPredicate(_, r),
2814-
)) if r == self.found_region => Some(pred_span),
2815-
_ => None,
2816-
}
2817-
})
2818-
.collect();
2777+
self.pred_spans = elaborate_predicates_of(self.tcx, path.res.def_id())
2778+
.filter_map(|(pred, pred_span)| {
2779+
match pred.kind().skip_binder() {
2780+
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
2781+
ty::OutlivesPredicate(
2782+
// What should I filter this with?
2783+
_pred_ty,
2784+
r,
2785+
),
2786+
)) if r == self.found_region => Some(pred_span),
2787+
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(
2788+
ty::OutlivesPredicate(_, r),
2789+
)) if r == self.found_region => Some(pred_span),
2790+
_ => None,
2791+
}
2792+
})
2793+
.collect();
28192794
}
28202795
_ => {}
28212796
}

compiler/rustc_infer/src/traits/util.rs

+11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::infer::outlives::components::{push_outlives_components, Component};
44
use crate::traits::{self, Obligation, PredicateObligation};
55
use rustc_data_structures::fx::FxHashSet;
66
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
7+
use rustc_span::def_id::DefId;
78
use rustc_span::symbol::Ident;
89
use rustc_span::Span;
910

@@ -235,6 +236,16 @@ pub fn elaborate<'tcx, O: Elaboratable<'tcx>>(
235236
elaborator
236237
}
237238

239+
pub fn elaborate_predicates_of<'tcx>(
240+
tcx: TyCtxt<'tcx>,
241+
def_id: DefId,
242+
) -> Elaborator<'tcx, (ty::Predicate<'tcx>, Span)> {
243+
elaborate(
244+
tcx,
245+
tcx.predicates_of(def_id).predicates.iter().map(|(p, sp)| (p.as_predicate(), *sp)),
246+
)
247+
}
248+
238249
impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
239250
fn extend_deduped(&mut self, obligations: impl IntoIterator<Item = O>) {
240251
// Only keep those bounds that we haven't already seen.

0 commit comments

Comments
 (0)