Skip to content

Commit a539a0e

Browse files
committed
Introduce traits::util::elaborate_predicates_of
1 parent fefce2f commit a539a0e

File tree

3 files changed

+87
-107
lines changed

3 files changed

+87
-107
lines changed

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

Lines changed: 23 additions & 29 deletions
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::{
@@ -645,10 +645,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
645645
let def_id = instance.def_id();
646646
let mut parent = tcx.parent(def_id);
647647
debug!(?def_id, ?parent);
648-
let trait_preds = match tcx.def_kind(parent) {
649-
hir::def::DefKind::Impl { .. } => {
650-
tcx.trait_id_of_impl(parent).map_or(&[][..], |id| tcx.predicates_of(id).predicates)
651-
}
648+
let trait_preds: Vec<_> = match tcx.def_kind(parent) {
649+
hir::def::DefKind::Impl { .. } => tcx
650+
.trait_id_of_impl(parent)
651+
.map_or(vec![], |id| elaborate_predicates_of(tcx, id).collect()),
652652
hir::def::DefKind::Trait => {
653653
let Some(ty) = args.get(0).and_then(|arg| arg.as_type()) else {
654654
return;
@@ -660,9 +660,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
660660
if let [def_id] = impls[..] {
661661
// The method we have is on the trait, but for `parent` we want to analyze the
662662
// relevant impl instead.
663-
let preds = tcx.predicates_of(parent).predicates;
663+
let preds = elaborate_predicates_of(tcx, parent);
664664
parent = def_id;
665-
preds
665+
preds.collect()
666666
} else {
667667
return;
668668
}
@@ -688,30 +688,24 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
688688
// fn foo(&self) where Self: 'static {}
689689
// }
690690
// ```
691-
let mut predicates: Vec<Span> = traits::elaborate(
692-
tcx,
693-
tcx.predicates_of(def_id).predicates.iter().map(|(p, sp)| (p.as_predicate(), *sp)),
694-
)
695-
.chain(traits::elaborate(
696-
tcx,
697-
tcx.predicates_of(parent).predicates.iter().map(|(p, sp)| (p.as_predicate(), *sp)),
698-
))
699-
.chain(traits::elaborate(tcx, trait_preds.iter().map(|(p, sp)| (p.as_predicate(), *sp))))
700-
.filter_map(|(pred, pred_span)| {
701-
if let ty::PredicateKind::Clause(clause) = pred.kind().skip_binder()
702-
&& let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(pred_ty, r)) = clause
703-
&& r.kind() == ty::ReStatic
704-
&& (self.infcx.can_eq(self.param_env, ty, pred_ty)
705-
|| matches!(
691+
let mut predicates: Vec<Span> = elaborate_predicates_of(tcx, def_id)
692+
.chain(elaborate_predicates_of(tcx, parent))
693+
.chain(trait_preds)
694+
.filter_map(|(pred, pred_span)| {
695+
if let ty::PredicateKind::Clause(clause) = pred.kind().skip_binder()
696+
&& let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(pred_ty, r)) = clause
697+
&& r.kind() == ty::ReStatic
698+
&& (self.infcx.can_eq(self.param_env, ty, pred_ty)
699+
|| matches!(
706700
pred_ty.kind(),
707701
ty::Param(name) if name.name == kw::SelfUpper))
708-
{
709-
Some(pred_span)
710-
} else {
711-
None
712-
}
713-
})
714-
.collect();
702+
{
703+
Some(pred_span)
704+
} else {
705+
None
706+
}
707+
})
708+
.collect();
715709
debug!(?predicates);
716710

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

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

Lines changed: 53 additions & 78 deletions
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();
@@ -2770,29 +2760,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
27702760
for ptr in poly_trait_refs {
27712761
if let Some(def_id) = ptr.trait_ref.trait_def_id() {
27722762
// Find the bounds on the trait with the lifetime that couldn't be met.
2773-
let bindings: Vec<Span> = elaborate(
2774-
self.tcx,
2775-
self.tcx
2776-
.predicates_of(def_id)
2777-
.predicates
2778-
.iter()
2779-
.map(|(p, sp)| (p.as_predicate(), *sp)),
2780-
)
2781-
.filter_map(|(pred, pred_span)| {
2782-
if let ty::PredicateKind::Clause(clause) =
2783-
pred.kind().skip_binder()
2784-
&& let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
2785-
_pred_ty,
2786-
r,
2787-
)) = clause
2788-
&& r == self.found_region
2789-
{
2790-
Some(pred_span)
2791-
} else {
2792-
None
2793-
}
2794-
})
2795-
.collect();
2763+
let bindings: Vec<Span> = elaborate_predicates_of(self.tcx, def_id)
2764+
.filter_map(|(pred, pred_span)| {
2765+
if let ty::PredicateKind::Clause(clause) =
2766+
pred.kind().skip_binder()
2767+
&& let ty::ClauseKind::TypeOutlives(
2768+
ty::OutlivesPredicate(_pred_ty, r),
2769+
) = clause
2770+
&& r == self.found_region
2771+
{
2772+
Some(pred_span)
2773+
} else {
2774+
None
2775+
}
2776+
})
2777+
.collect();
27962778
if !bindings.is_empty() {
27972779
self.lifetime_spans.insert(ptr.span);
27982780
self.pred_spans.extend(bindings);
@@ -2803,30 +2785,23 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
28032785
// Detect when an associated item is given a lifetime restriction that the
28042786
// definition of that associated item couldn't meet.
28052787
hir::TyKind::Path(hir::QPath::Resolved(Some(_), path)) => {
2806-
self.pred_spans = elaborate(
2807-
self.tcx,
2808-
self.tcx
2809-
.predicates_of(path.res.def_id())
2810-
.predicates
2811-
.iter()
2812-
.map(|(p, sp)| (p.as_predicate(), *sp)),
2813-
)
2814-
.filter_map(|(pred, pred_span)| {
2815-
match pred.kind().skip_binder() {
2816-
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
2817-
ty::OutlivesPredicate(
2818-
// What should I filter this with?
2819-
_pred_ty,
2820-
r,
2821-
),
2822-
)) if r == self.found_region => Some(pred_span),
2823-
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(
2824-
ty::OutlivesPredicate(_, r),
2825-
)) if r == self.found_region => Some(pred_span),
2826-
_ => None,
2827-
}
2828-
})
2829-
.collect();
2788+
self.pred_spans = elaborate_predicates_of(self.tcx, path.res.def_id())
2789+
.filter_map(|(pred, pred_span)| {
2790+
match pred.kind().skip_binder() {
2791+
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
2792+
ty::OutlivesPredicate(
2793+
// What should I filter this with?
2794+
_pred_ty,
2795+
r,
2796+
),
2797+
)) if r == self.found_region => Some(pred_span),
2798+
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(
2799+
ty::OutlivesPredicate(_, r),
2800+
)) if r == self.found_region => Some(pred_span),
2801+
_ => None,
2802+
}
2803+
})
2804+
.collect();
28302805
}
28312806
_ => {}
28322807
}

compiler/rustc_infer/src/traits/util.rs

Lines changed: 11 additions & 0 deletions
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)