Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 26199f0

Browse files
committed
ty/walk: switch walk_shallow from Ty to GenericArg.
1 parent 0d4705b commit 26199f0

File tree

5 files changed

+58
-80
lines changed

5 files changed

+58
-80
lines changed

src/librustc_infer/infer/outlives/verify.rs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@ use crate::infer::{GenericKind, VerifyBound};
33
use crate::traits;
44
use rustc_data_structures::captures::Captures;
55
use rustc_hir::def_id::DefId;
6-
use rustc_middle::ty::subst::{InternalSubsts, Subst};
6+
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst};
77
use rustc_middle::ty::{self, Ty, TyCtxt};
88

9-
use smallvec::smallvec;
10-
119
/// The `TypeOutlives` struct has the job of "lowering" a `T: 'a`
1210
/// obligation into a series of `'a: 'b` constraints and "verifys", as
1311
/// described on the module comment. The final constraints are emitted
@@ -44,7 +42,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
4442
match ty.kind {
4543
ty::Param(p) => self.param_bound(p),
4644
ty::Projection(data) => self.projection_bound(data),
47-
_ => self.recursive_type_bound(ty),
45+
_ => self.recursive_bound(ty.into()),
4846
}
4947
}
5048

@@ -144,25 +142,33 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
144142

145143
// see the extensive comment in projection_must_outlive
146144
let ty = self.tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs);
147-
let recursive_bound = self.recursive_type_bound(ty);
145+
let recursive_bound = self.recursive_bound(ty.into());
148146

149147
VerifyBound::AnyBound(env_bounds.chain(trait_bounds).collect()).or(recursive_bound)
150148
}
151149

152-
fn recursive_type_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> {
153-
let mut bounds = ty.walk_shallow().map(|subty| self.type_bound(subty)).collect::<Vec<_>>();
154-
155-
let mut regions = smallvec![];
156-
ty.push_regions(&mut regions);
157-
regions.retain(|r| !r.is_late_bound()); // ignore late-bound regions
158-
bounds.push(VerifyBound::AllBounds(
159-
regions.into_iter().map(|r| VerifyBound::OutlivedBy(r)).collect(),
160-
));
161-
162-
// remove bounds that must hold, since they are not interesting
163-
bounds.retain(|b| !b.must_hold());
150+
fn recursive_bound(&self, parent: GenericArg<'tcx>) -> VerifyBound<'tcx> {
151+
let mut bounds = parent
152+
.walk_shallow()
153+
.filter_map(|child| match child.unpack() {
154+
GenericArgKind::Type(ty) => Some(self.type_bound(ty)),
155+
GenericArgKind::Lifetime(lt) => {
156+
// Ignore late-bound regions.
157+
if !lt.is_late_bound() { Some(VerifyBound::OutlivedBy(lt)) } else { None }
158+
}
159+
GenericArgKind::Const(_) => Some(self.recursive_bound(child)),
160+
})
161+
.filter(|bound| {
162+
// Remove bounds that must hold, since they are not interesting.
163+
!bound.must_hold()
164+
});
164165

165-
if bounds.len() == 1 { bounds.pop().unwrap() } else { VerifyBound::AllBounds(bounds) }
166+
match (bounds.next(), bounds.next()) {
167+
(Some(first), None) => first,
168+
(first, second) => {
169+
VerifyBound::AllBounds(first.into_iter().chain(second).chain(bounds).collect())
170+
}
171+
}
166172
}
167173

168174
/// Searches the environment for where-clauses like `G: 'a` where

src/librustc_middle/ty/mod.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2701,13 +2701,6 @@ impl<'tcx> TyS<'tcx> {
27012701
TypeWalker::new(self.into())
27022702
}
27032703

2704-
/// Iterator that walks the immediate children of `self`. Hence
2705-
/// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
2706-
/// (but not `i32`, like `walk`).
2707-
pub fn walk_shallow(&'tcx self) -> impl Iterator<Item = Ty<'tcx>> {
2708-
walk::walk_shallow(self.into())
2709-
}
2710-
27112704
/// Walks `ty` and any types appearing within `ty`, invoking the
27122705
/// callback `f` on each type. If the callback returns `false`, then the
27132706
/// children of the current type are ignored.

src/librustc_middle/ty/outlives.rs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// refers to rules defined in RFC 1214 (`OutlivesFooBar`), so see that
33
// RFC for reference.
44

5+
use crate::ty::subst::{GenericArg, GenericArgKind};
56
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
67
use smallvec::SmallVec;
78

@@ -107,8 +108,9 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo
107108
// fallback case: hard code
108109
// OutlivesProjectionComponents. Continue walking
109110
// through and constrain Pi.
110-
let subcomponents = capture_components(tcx, ty);
111-
out.push(Component::EscapingProjection(subcomponents));
111+
let mut subcomponents = smallvec![];
112+
compute_components_recursive(tcx, ty.into(), &mut subcomponents);
113+
out.push(Component::EscapingProjection(subcomponents.into_iter().collect()));
112114
}
113115
}
114116

@@ -153,26 +155,30 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo
153155
// "bound regions list". In our representation, no such
154156
// list is maintained explicitly, because bound regions
155157
// themselves can be readily identified.
156-
157-
push_region_constraints(ty, out);
158-
for subty in ty.walk_shallow() {
159-
compute_components(tcx, subty, out);
160-
}
158+
compute_components_recursive(tcx, ty.into(), out);
161159
}
162160
}
163161
}
164162

165-
fn capture_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Vec<Component<'tcx>> {
166-
let mut temp = smallvec![];
167-
push_region_constraints(ty, &mut temp);
168-
for subty in ty.walk_shallow() {
169-
compute_components(tcx, subty, &mut temp);
163+
fn compute_components_recursive(
164+
tcx: TyCtxt<'tcx>,
165+
parent: GenericArg<'tcx>,
166+
out: &mut SmallVec<[Component<'tcx>; 4]>,
167+
) {
168+
for child in parent.walk_shallow() {
169+
match child.unpack() {
170+
GenericArgKind::Type(ty) => {
171+
compute_components(tcx, ty, out);
172+
}
173+
GenericArgKind::Lifetime(lt) => {
174+
// Ignore late-bound regions.
175+
if !lt.is_late_bound() {
176+
out.push(Component::Region(lt));
177+
}
178+
}
179+
GenericArgKind::Const(_) => {
180+
compute_components_recursive(tcx, child, out);
181+
}
182+
}
170183
}
171-
temp.into_iter().collect()
172-
}
173-
174-
fn push_region_constraints<'tcx>(ty: Ty<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>) {
175-
let mut regions = smallvec![];
176-
ty.push_regions(&mut regions);
177-
out.extend(regions.iter().filter(|&r| !r.is_late_bound()).map(|r| Component::Region(r)));
178184
}

src/librustc_middle/ty/sty.rs

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use rustc_macros::HashStable;
2525
use rustc_span::symbol::{kw, Symbol};
2626
use rustc_target::abi::{Size, VariantIdx};
2727
use rustc_target::spec::abi;
28-
use smallvec::SmallVec;
2928
use std::borrow::Cow;
3029
use std::cmp::Ordering;
3130
use std::marker::PhantomData;
@@ -2152,31 +2151,6 @@ impl<'tcx> TyS<'tcx> {
21522151
}
21532152
}
21542153

2155-
/// Pushes onto `out` the regions directly referenced from this type (but not
2156-
/// types reachable from this type via `walk_tys`). This ignores late-bound
2157-
/// regions binders.
2158-
pub fn push_regions(&self, out: &mut SmallVec<[ty::Region<'tcx>; 4]>) {
2159-
match self.kind {
2160-
Ref(region, _, _) => {
2161-
out.push(region);
2162-
}
2163-
Dynamic(ref obj, region) => {
2164-
out.push(region);
2165-
if let Some(principal) = obj.principal() {
2166-
out.extend(principal.skip_binder().substs.regions());
2167-
}
2168-
}
2169-
Adt(_, substs) | Opaque(_, substs) => out.extend(substs.regions()),
2170-
Closure(_, ref substs) | Generator(_, ref substs, _) => out.extend(substs.regions()),
2171-
Projection(ref data) | UnnormalizedProjection(ref data) => {
2172-
out.extend(data.substs.regions())
2173-
}
2174-
FnDef(..) | FnPtr(_) | GeneratorWitness(..) | Bool | Char | Int(_) | Uint(_)
2175-
| Float(_) | Str | Array(..) | Slice(_) | RawPtr(_) | Never | Tuple(..)
2176-
| Foreign(..) | Param(_) | Bound(..) | Placeholder(..) | Infer(_) | Error => {}
2177-
}
2178-
}
2179-
21802154
/// When we create a closure, we record its kind (i.e., what trait
21812155
/// it implements) into its `ClosureSubsts` using a type
21822156
/// parameter. This is kind of a phantom type, except that the

src/librustc_middle/ty/walk.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,15 @@ impl<'tcx> Iterator for TypeWalker<'tcx> {
5757
}
5858
}
5959

60-
pub fn walk_shallow(parent: GenericArg<'tcx>) -> impl Iterator<Item = Ty<'tcx>> {
61-
let mut stack = SmallVec::new();
62-
push_inner(&mut stack, parent);
63-
stack.into_iter().filter_map(|child| {
64-
// FIXME(eddyb) remove this filter and expose all `GenericArg`s.
65-
match child.unpack() {
66-
GenericArgKind::Type(ty) => Some(ty),
67-
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => None,
68-
}
69-
})
60+
impl GenericArg<'tcx> {
61+
/// Iterator that walks the immediate children of `self`. Hence
62+
/// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
63+
/// (but not `i32`, like `walk`).
64+
pub fn walk_shallow(self) -> impl Iterator<Item = GenericArg<'tcx>> {
65+
let mut stack = SmallVec::new();
66+
push_inner(&mut stack, self);
67+
stack.into_iter()
68+
}
7069
}
7170

7271
// We push `GenericArg`s on the stack in reverse order so as to

0 commit comments

Comments
 (0)