Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert outlives_components' return value to a SmallVec outparam. #55745

Merged
merged 1 commit into from
Nov 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/librustc/infer/opaque_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let mut types = vec![concrete_ty];
let bound_region = |r| self.sub_regions(infer::CallReturn(span), least_region, r);
while let Some(ty) = types.pop() {
let mut components = self.tcx.outlives_components(ty);
let mut components = smallvec![];
self.tcx.push_outlives_components(ty, &mut components);
while let Some(component) = components.pop() {
match component {
Component::Region(r) => {
Expand Down
17 changes: 9 additions & 8 deletions src/librustc/infer/outlives/obligations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// except according to those terms.

//! Code that handles "type-outlives" constraints like `T: 'a`. This
//! is based on the `outlives_components` function defined on the tcx,
//! is based on the `push_outlives_components` function defined on the tcx,
//! but it adds a bit of heuristics on top, in particular to deal with
//! associated types and projections.
//!
Expand Down Expand Up @@ -307,31 +307,32 @@ where

assert!(!ty.has_escaping_bound_vars());

let components = self.tcx.outlives_components(ty);
self.components_must_outlive(origin, components, region);
let mut components = smallvec![];
self.tcx.push_outlives_components(ty, &mut components);
self.components_must_outlive(origin, &components, region);
}

fn components_must_outlive(
&mut self,
origin: infer::SubregionOrigin<'tcx>,
components: Vec<Component<'tcx>>,
components: &[Component<'tcx>],
region: ty::Region<'tcx>,
) {
for component in components {
for component in components.iter() {
let origin = origin.clone();
match component {
Component::Region(region1) => {
self.delegate
.push_sub_region_constraint(origin, region, region1);
}
Component::Param(param_ty) => {
self.param_ty_must_outlive(origin, region, param_ty);
self.param_ty_must_outlive(origin, region, *param_ty);
}
Component::Projection(projection_ty) => {
self.projection_must_outlive(origin, region, projection_ty);
self.projection_must_outlive(origin, region, *projection_ty);
}
Component::EscapingProjection(subcomponents) => {
self.components_must_outlive(origin, subcomponents, region);
self.components_must_outlive(origin, &subcomponents, region);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

& looks unnecessary

}
Component::UnresolvedInferenceVariable(v) => {
// ignore this, we presume it will yield an error
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/infer/outlives/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> {
.map(|subty| self.type_bound(subty))
.collect::<Vec<_>>();

let mut regions = ty.regions();
let mut regions = smallvec![];
ty.push_regions(&mut regions);
regions.retain(|r| !r.is_late_bound()); // ignore late-bound regions
bounds.push(VerifyBound::AllBounds(
regions
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,10 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> {
}

let visited = &mut self.visited;
let mut components = smallvec![];
tcx.push_outlives_components(ty_max, &mut components);
self.stack.extend(
tcx.outlives_components(ty_max)
components
.into_iter()
.filter_map(|component| match component {
Component::Region(r) => if r.is_late_bound() {
Expand Down
27 changes: 14 additions & 13 deletions src/librustc/ty/outlives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// refers to rules defined in RFC 1214 (`OutlivesFooBar`), so see that
// RFC for reference.

use smallvec::SmallVec;
use ty::{self, Ty, TyCtxt, TypeFoldable};

#[derive(Debug)]
Expand Down Expand Up @@ -55,17 +56,15 @@ pub enum Component<'tcx> {
}

impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// Returns all the things that must outlive `'a` for the condition
/// Push onto `out` all the things that must outlive `'a` for the condition
/// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**.
pub fn outlives_components(&self, ty0: Ty<'tcx>)
-> Vec<Component<'tcx>> {
let mut components = vec![];
self.compute_components(ty0, &mut components);
debug!("components({:?}) = {:?}", ty0, components);
components
pub fn push_outlives_components(&self, ty0: Ty<'tcx>,
out: &mut SmallVec<[Component<'tcx>; 4]>) {
self.compute_components(ty0, out);
debug!("components({:?}) = {:?}", ty0, out);
}

fn compute_components(&self, ty: Ty<'tcx>, out: &mut Vec<Component<'tcx>>) {
fn compute_components(&self, ty: Ty<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>) {
// Descend through the types, looking for the various "base"
// components and collecting them into `out`. This is not written
// with `collect()` because of the need to sometimes skip subtrees
Expand Down Expand Up @@ -164,7 +163,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// list is maintained explicitly, because bound regions
// themselves can be readily identified.

push_region_constraints(out, ty.regions());
push_region_constraints(ty, out);
for subty in ty.walk_shallow() {
self.compute_components(subty, out);
}
Expand All @@ -173,15 +172,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}

fn capture_components(&self, ty: Ty<'tcx>) -> Vec<Component<'tcx>> {
let mut temp = vec![];
push_region_constraints(&mut temp, ty.regions());
let mut temp = smallvec![];
push_region_constraints(ty, &mut temp);
for subty in ty.walk_shallow() {
self.compute_components(subty, &mut temp);
}
temp
temp.into_iter().collect()
}
}

fn push_region_constraints<'tcx>(out: &mut Vec<Component<'tcx>>, regions: Vec<ty::Region<'tcx>>) {
fn push_region_constraints<'tcx>(ty: Ty<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>) {
let mut regions = smallvec![];
ty.push_regions(&mut regions);
out.extend(regions.iter().filter(|&r| !r.is_late_bound()).map(|r| Component::Region(r)));
}
26 changes: 12 additions & 14 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use ty::{List, TyS, ParamEnvAnd, ParamEnv};
use util::captures::Captures;
use mir::interpret::{Scalar, Pointer};

use smallvec::SmallVec;
use std::iter;
use std::cmp::Ordering;
use rustc_target::spec::abi;
Expand Down Expand Up @@ -1846,28 +1847,27 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
}
}

/// Returns the regions directly referenced from this type (but
/// not types reachable from this type via `walk_tys`). This
/// ignores late-bound regions binders.
pub fn regions(&self) -> Vec<ty::Region<'tcx>> {
/// Push onto `out` the regions directly referenced from this type (but not
/// types reachable from this type via `walk_tys`). This ignores late-bound
/// regions binders.
pub fn push_regions(&self, out: &mut SmallVec<[ty::Region<'tcx>; 4]>) {
match self.sty {
Ref(region, _, _) => {
vec![region]
out.push(region);
}
Dynamic(ref obj, region) => {
let mut v = vec![region];
v.extend(obj.principal().skip_binder().substs.regions());
v
out.push(region);
out.extend(obj.principal().skip_binder().substs.regions());
}
Adt(_, substs) | Opaque(_, substs) => {
substs.regions().collect()
out.extend(substs.regions())
}
Closure(_, ClosureSubsts { ref substs }) |
Generator(_, GeneratorSubsts { ref substs }, _) => {
substs.regions().collect()
out.extend(substs.regions())
}
Projection(ref data) | UnnormalizedProjection(ref data) => {
data.substs.regions().collect()
out.extend(data.substs.regions())
}
FnDef(..) |
FnPtr(_) |
Expand All @@ -1887,9 +1887,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
Param(_) |
Bound(..) |
Infer(_) |
Error => {
vec![]
}
Error => {}
}
}

Expand Down
7 changes: 6 additions & 1 deletion src/librustc_mir/transform/cleanup_post_borrowck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use rustc::mir::{BasicBlock, FakeReadCause, Local, Location, Mir, Place};
use rustc::mir::{Rvalue, Statement, StatementKind};
use rustc::mir::visit::{MutVisitor, Visitor, TyContext};
use rustc::ty::{Ty, RegionKind, TyCtxt};
use smallvec::smallvec;
use transform::{MirPass, MirSource};

pub struct CleanEndRegions;
Expand Down Expand Up @@ -80,7 +81,11 @@ impl<'tcx> Visitor<'tcx> for GatherBorrowedRegions {

fn visit_ty(&mut self, ty: &Ty<'tcx>, _: TyContext) {
// Gather regions that occur in types
for re in ty.walk().flat_map(|t| t.regions()) {
let mut regions = smallvec![];
for t in ty.walk() {
t.push_regions(&mut regions);
}
for re in regions {
match *re {
RegionKind::ReScope(ce) => { self.seen_regions.insert(ce); }
_ => {},
Expand Down
6 changes: 4 additions & 2 deletions src/librustc_traits/implied_outlives_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::ty::outlives::Component;
use rustc::ty::query::Providers;
use rustc::ty::wf;
use smallvec::{SmallVec, smallvec};
use syntax::ast::DUMMY_NODE_ID;
use syntax::source_map::DUMMY_SP;
use rustc::traits::FulfillmentContext;
Expand Down Expand Up @@ -133,7 +134,8 @@ fn compute_implied_outlives_bounds<'tcx>(
None => vec![],
Some(ty::OutlivesPredicate(ty_a, r_b)) => {
let ty_a = infcx.resolve_type_vars_if_possible(&ty_a);
let components = tcx.outlives_components(ty_a);
let mut components = smallvec![];
tcx.push_outlives_components(ty_a, &mut components);
implied_bounds_from_components(r_b, components)
}
},
Expand All @@ -155,7 +157,7 @@ fn compute_implied_outlives_bounds<'tcx>(
/// those relationships.
fn implied_bounds_from_components(
sub_region: ty::Region<'tcx>,
sup_components: Vec<Component<'tcx>>,
sup_components: SmallVec<[Component<'tcx>; 4]>,
) -> Vec<OutlivesBound<'tcx>> {
sup_components
.into_iter()
Expand Down
5 changes: 4 additions & 1 deletion src/librustc_typeck/outlives/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use rustc::ty::outlives::Component;
use rustc::ty::subst::{Kind, UnpackedKind};
use rustc::ty::{self, Region, RegionKind, Ty, TyCtxt};
use smallvec::smallvec;
use std::collections::BTreeSet;

/// Tracks the `T: 'a` or `'a: 'a` predicates that we have inferred
Expand Down Expand Up @@ -40,7 +41,9 @@ pub fn insert_outlives_predicate<'tcx>(
//
// Or if within `struct Foo<U>` you had `T = Vec<U>`, then
// we would want to add `U: 'outlived_region`
for component in tcx.outlives_components(ty) {
let mut components = smallvec![];
tcx.push_outlives_components(ty, &mut components);
for component in components {
match component {
Component::Region(r) => {
// This would arise from something like:
Expand Down