Skip to content

Commit 752961b

Browse files
authored
Rollup merge of #70641 - estebank:dedup-code, r=nikomatsakis
Remove duplicated code in trait selection
2 parents a928f64 + 8bedb7e commit 752961b

File tree

3 files changed

+81
-298
lines changed

3 files changed

+81
-298
lines changed

src/librustc_infer/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mod engine;
66
pub mod error_reporting;
77
mod project;
88
mod structural_impls;
9-
mod util;
9+
pub mod util;
1010

1111
use rustc_hir as hir;
1212
use rustc_middle::ty::error::{ExpectedFound, TypeError};

src/librustc_infer/traits/util.rs

+78-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ use smallvec::smallvec;
22

33
use rustc_data_structures::fx::FxHashSet;
44
use rustc_middle::ty::outlives::Component;
5-
use rustc_middle::ty::{self, ToPolyTraitRef, TyCtxt};
5+
use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, TyCtxt, WithConstness};
66

7-
fn anonymize_predicate<'tcx>(tcx: TyCtxt<'tcx>, pred: &ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
7+
pub fn anonymize_predicate<'tcx>(
8+
tcx: TyCtxt<'tcx>,
9+
pred: &ty::Predicate<'tcx>,
10+
) -> ty::Predicate<'tcx> {
811
match *pred {
912
ty::Predicate::Trait(ref data, constness) => {
1013
ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data), constness)
@@ -88,6 +91,21 @@ pub struct Elaborator<'tcx> {
8891
visited: PredicateSet<'tcx>,
8992
}
9093

94+
pub fn elaborate_trait_ref<'tcx>(
95+
tcx: TyCtxt<'tcx>,
96+
trait_ref: ty::PolyTraitRef<'tcx>,
97+
) -> Elaborator<'tcx> {
98+
elaborate_predicates(tcx, vec![trait_ref.without_const().to_predicate()])
99+
}
100+
101+
pub fn elaborate_trait_refs<'tcx>(
102+
tcx: TyCtxt<'tcx>,
103+
trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
104+
) -> Elaborator<'tcx> {
105+
let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate()).collect();
106+
elaborate_predicates(tcx, predicates)
107+
}
108+
91109
pub fn elaborate_predicates<'tcx>(
92110
tcx: TyCtxt<'tcx>,
93111
mut predicates: Vec<ty::Predicate<'tcx>>,
@@ -98,6 +116,10 @@ pub fn elaborate_predicates<'tcx>(
98116
}
99117

100118
impl Elaborator<'tcx> {
119+
pub fn filter_to_traits(self) -> FilterToTraits<Self> {
120+
FilterToTraits::new(self)
121+
}
122+
101123
fn elaborate(&mut self, predicate: &ty::Predicate<'tcx>) {
102124
let tcx = self.visited.tcx;
103125
match *predicate {
@@ -223,3 +245,57 @@ impl Iterator for Elaborator<'tcx> {
223245
}
224246
}
225247
}
248+
249+
///////////////////////////////////////////////////////////////////////////
250+
// Supertrait iterator
251+
///////////////////////////////////////////////////////////////////////////
252+
253+
pub type Supertraits<'tcx> = FilterToTraits<Elaborator<'tcx>>;
254+
255+
pub fn supertraits<'tcx>(
256+
tcx: TyCtxt<'tcx>,
257+
trait_ref: ty::PolyTraitRef<'tcx>,
258+
) -> Supertraits<'tcx> {
259+
elaborate_trait_ref(tcx, trait_ref).filter_to_traits()
260+
}
261+
262+
pub fn transitive_bounds<'tcx>(
263+
tcx: TyCtxt<'tcx>,
264+
bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
265+
) -> Supertraits<'tcx> {
266+
elaborate_trait_refs(tcx, bounds).filter_to_traits()
267+
}
268+
269+
///////////////////////////////////////////////////////////////////////////
270+
// Other
271+
///////////////////////////////////////////////////////////////////////////
272+
273+
/// A filter around an iterator of predicates that makes it yield up
274+
/// just trait references.
275+
pub struct FilterToTraits<I> {
276+
base_iterator: I,
277+
}
278+
279+
impl<I> FilterToTraits<I> {
280+
fn new(base: I) -> FilterToTraits<I> {
281+
FilterToTraits { base_iterator: base }
282+
}
283+
}
284+
285+
impl<'tcx, I: Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
286+
type Item = ty::PolyTraitRef<'tcx>;
287+
288+
fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
289+
while let Some(pred) = self.base_iterator.next() {
290+
if let ty::Predicate::Trait(data, _) = pred {
291+
return Some(data.to_poly_trait_ref());
292+
}
293+
}
294+
None
295+
}
296+
297+
fn size_hint(&self) -> (usize, Option<usize>) {
298+
let (_, upper) = self.base_iterator.size_hint();
299+
(0, upper)
300+
}
301+
}

0 commit comments

Comments
 (0)