Skip to content

Commit 997bd33

Browse files
committed
Auto merge of #26354 - jroesch:remove-param-bounds-take-n, r=nikomatsakis
This pull request removes `ParamBounds` a old holdover in the type checker that we (@nikomatsakis and I) had wanted to remove. I'm not sure if the current form is the best possible refactor but I figured we can use this as a place to discuss it. r? @nikomatsakis
2 parents 699315e + 81e5c1f commit 997bd33

File tree

9 files changed

+100
-226
lines changed

9 files changed

+100
-226
lines changed

src/librustc/metadata/tydecode.rs

Lines changed: 17 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -195,15 +195,6 @@ pub fn parse_substs_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: us
195195
parse_substs(&mut st, conv)
196196
}
197197

198-
pub fn parse_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum,
199-
pos: usize, tcx: &ty::ctxt<'tcx>, conv: F)
200-
-> ty::ParamBounds<'tcx> where
201-
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
202-
{
203-
let mut st = parse_state_from_data(data, crate_num, pos, tcx);
204-
parse_bounds(&mut st, conv)
205-
}
206-
207198
pub fn parse_existential_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum,
208199
pos: usize, tcx: &ty::ctxt<'tcx>, conv: F)
209200
-> ty::ExistentialBounds<'tcx> where
@@ -879,11 +870,23 @@ fn parse_existential_bounds_<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
879870
-> ty::ExistentialBounds<'tcx> where
880871
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
881872
{
882-
let ty::ParamBounds { trait_bounds, mut region_bounds, builtin_bounds, projection_bounds } =
883-
parse_bounds_(st, conv);
884-
assert_eq!(region_bounds.len(), 1);
885-
assert_eq!(trait_bounds.len(), 0);
886-
let region_bound = region_bounds.pop().unwrap();
873+
let builtin_bounds = parse_builtin_bounds_(st, conv);
874+
let region_bound = parse_region_(st, conv);
875+
let mut projection_bounds = Vec::new();
876+
877+
loop {
878+
match next(st) {
879+
'P' => {
880+
projection_bounds.push(
881+
ty::Binder(parse_projection_predicate_(st, conv)));
882+
}
883+
'.' => { break; }
884+
c => {
885+
panic!("parse_bounds: bad bounds ('{}')", c)
886+
}
887+
}
888+
}
889+
887890
return ty::ExistentialBounds { region_bound: region_bound,
888891
builtin_bounds: builtin_bounds,
889892
projection_bounds: projection_bounds };
@@ -923,60 +926,3 @@ fn parse_builtin_bounds_<F>(st: &mut PState, _conv: &mut F) -> ty::BuiltinBounds
923926
}
924927
}
925928
}
926-
927-
fn parse_bounds<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
928-
-> ty::ParamBounds<'tcx> where
929-
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
930-
{
931-
parse_bounds_(st, &mut conv)
932-
}
933-
934-
fn parse_bounds_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
935-
-> ty::ParamBounds<'tcx> where
936-
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
937-
{
938-
let builtin_bounds = parse_builtin_bounds_(st, conv);
939-
940-
let region_bounds = parse_region_bounds_(st, conv);
941-
942-
let mut param_bounds = ty::ParamBounds {
943-
region_bounds: region_bounds,
944-
builtin_bounds: builtin_bounds,
945-
trait_bounds: Vec::new(),
946-
projection_bounds: Vec::new(),
947-
};
948-
949-
950-
loop {
951-
match next(st) {
952-
'I' => {
953-
param_bounds.trait_bounds.push(
954-
ty::Binder(parse_trait_ref_(st, conv)));
955-
}
956-
'P' => {
957-
param_bounds.projection_bounds.push(
958-
ty::Binder(parse_projection_predicate_(st, conv)));
959-
}
960-
'.' => {
961-
return param_bounds;
962-
}
963-
c => {
964-
panic!("parse_bounds: bad bounds ('{}')", c)
965-
}
966-
}
967-
}
968-
}
969-
970-
fn parse_region_bounds_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
971-
-> Vec<ty::Region> where
972-
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
973-
{
974-
let mut region_bounds = Vec::new();
975-
loop {
976-
match next(st) {
977-
'R' => { region_bounds.push(parse_region_(st, conv)); }
978-
'.' => { return region_bounds; }
979-
c => { panic!("parse_bounds: bad bounds ('{}')", c); }
980-
}
981-
}
982-
}

src/librustc/metadata/tyencode.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -380,23 +380,9 @@ pub fn enc_builtin_bounds(w: &mut Encoder, _cx: &ctxt, bs: &ty::BuiltinBounds) {
380380
pub fn enc_existential_bounds<'a,'tcx>(w: &mut Encoder,
381381
cx: &ctxt<'a,'tcx>,
382382
bs: &ty::ExistentialBounds<'tcx>) {
383-
let param_bounds = ty::ParamBounds { trait_bounds: vec!(),
384-
region_bounds: vec!(bs.region_bound),
385-
builtin_bounds: bs.builtin_bounds,
386-
projection_bounds: bs.projection_bounds.clone() };
387-
enc_bounds(w, cx, &param_bounds);
388-
}
389-
390-
pub fn enc_bounds<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
391-
bs: &ty::ParamBounds<'tcx>) {
392383
enc_builtin_bounds(w, cx, &bs.builtin_bounds);
393384

394-
enc_region_bounds(w, cx, &bs.region_bounds);
395-
396-
for tp in &bs.trait_bounds {
397-
mywrite!(w, "I");
398-
enc_trait_ref(w, cx, tp.0);
399-
}
385+
enc_region(w, cx, bs.region_bound);
400386

401387
for tp in &bs.projection_bounds {
402388
mywrite!(w, "P");

src/librustc/middle/implicator.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use middle::infer::{InferCtxt, GenericKind};
1414
use middle::subst::Substs;
1515
use middle::traits;
16-
use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty};
16+
use middle::ty::{self, RegionEscape, ToPolyTraitRef, AsPredicate, Ty};
1717
use middle::ty_fold::{TypeFoldable, TypeFolder};
1818

1919
use syntax::ast;
@@ -444,13 +444,8 @@ pub fn object_region_bounds<'tcx>(
444444
let substs = tcx.mk_substs(principal.0.substs.with_self_ty(open_ty));
445445
let trait_refs = vec!(ty::Binder(ty::TraitRef::new(principal.0.def_id, substs)));
446446

447-
let param_bounds = ty::ParamBounds {
448-
region_bounds: Vec::new(),
449-
builtin_bounds: others,
450-
trait_bounds: trait_refs,
451-
projection_bounds: Vec::new(), // not relevant to computing region bounds
452-
};
447+
let mut predicates = others.to_predicates(tcx, open_ty);
448+
predicates.extend(trait_refs.iter().map(|t| t.as_predicate()));
453449

454-
let predicates = ty::predicates(tcx, open_ty, &param_bounds);
455450
ty::required_region_bounds(tcx, open_ty, predicates)
456451
}

src/librustc/middle/ty.rs

Lines changed: 13 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,21 +1847,8 @@ pub enum type_err<'tcx> {
18471847
terr_projection_bounds_length(expected_found<usize>),
18481848
}
18491849

1850-
/// Bounds suitable for a named type parameter like `A` in `fn foo<A>`
1851-
/// as well as the existential type parameter in an object type.
1852-
#[derive(PartialEq, Eq, Hash, Clone)]
1853-
pub struct ParamBounds<'tcx> {
1854-
pub region_bounds: Vec<ty::Region>,
1855-
pub builtin_bounds: BuiltinBounds,
1856-
pub trait_bounds: Vec<PolyTraitRef<'tcx>>,
1857-
pub projection_bounds: Vec<PolyProjectionPredicate<'tcx>>,
1858-
}
1859-
18601850
/// Bounds suitable for an existentially quantified type parameter
1861-
/// such as those that appear in object types or closure types. The
1862-
/// major difference between this case and `ParamBounds` is that
1863-
/// general purpose trait bounds are omitted and there must be
1864-
/// *exactly one* region.
1851+
/// such as those that appear in object types or closure types.
18651852
#[derive(PartialEq, Eq, Hash, Clone)]
18661853
pub struct ExistentialBounds<'tcx> {
18671854
pub region_bound: ty::Region,
@@ -1873,13 +1860,24 @@ pub struct ExistentialBounds<'tcx> {
18731860
pub struct BuiltinBounds(EnumSet<BuiltinBound>);
18741861

18751862
impl BuiltinBounds {
1876-
pub fn empty() -> BuiltinBounds {
1863+
pub fn empty() -> BuiltinBounds {
18771864
BuiltinBounds(EnumSet::new())
18781865
}
18791866

18801867
pub fn iter(&self) -> enum_set::Iter<BuiltinBound> {
18811868
self.into_iter()
18821869
}
1870+
1871+
pub fn to_predicates<'tcx>(&self,
1872+
tcx: &ty::ctxt<'tcx>,
1873+
self_ty: Ty<'tcx>) -> Vec<Predicate<'tcx>> {
1874+
self.iter().filter_map(|builtin_bound|
1875+
match traits::trait_ref_for_builtin_bound(tcx, builtin_bound, self_ty) {
1876+
Ok(trait_ref) => Some(trait_ref.as_predicate()),
1877+
Err(ErrorReported) => { None }
1878+
}
1879+
).collect()
1880+
}
18831881
}
18841882

18851883
impl ops::Deref for BuiltinBounds {
@@ -3704,17 +3702,6 @@ impl<'tcx> ItemSubsts<'tcx> {
37043702
}
37053703
}
37063704

3707-
impl<'tcx> ParamBounds<'tcx> {
3708-
pub fn empty() -> ParamBounds<'tcx> {
3709-
ParamBounds {
3710-
builtin_bounds: BuiltinBounds::empty(),
3711-
trait_bounds: Vec::new(),
3712-
region_bounds: Vec::new(),
3713-
projection_bounds: Vec::new(),
3714-
}
3715-
}
3716-
}
3717-
37183705
// Type utilities
37193706

37203707
pub fn type_is_nil(ty: Ty) -> bool {
@@ -6143,39 +6130,6 @@ pub fn lookup_super_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
61436130
|| csearch::get_super_predicates(cx, did))
61446131
}
61456132

6146-
pub fn predicates<'tcx>(
6147-
tcx: &ctxt<'tcx>,
6148-
param_ty: Ty<'tcx>,
6149-
bounds: &ParamBounds<'tcx>)
6150-
-> Vec<Predicate<'tcx>>
6151-
{
6152-
let mut vec = Vec::new();
6153-
6154-
for builtin_bound in &bounds.builtin_bounds {
6155-
match traits::trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty) {
6156-
Ok(trait_ref) => { vec.push(trait_ref.as_predicate()); }
6157-
Err(ErrorReported) => { }
6158-
}
6159-
}
6160-
6161-
for &region_bound in &bounds.region_bounds {
6162-
// account for the binder being introduced below; no need to shift `param_ty`
6163-
// because, at present at least, it can only refer to early-bound regions
6164-
let region_bound = ty_fold::shift_region(region_bound, 1);
6165-
vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).as_predicate());
6166-
}
6167-
6168-
for bound_trait_ref in &bounds.trait_bounds {
6169-
vec.push(bound_trait_ref.as_predicate());
6170-
}
6171-
6172-
for projection in &bounds.projection_bounds {
6173-
vec.push(projection.as_predicate());
6174-
}
6175-
6176-
vec
6177-
}
6178-
61796133
/// Get the attributes of a definition.
61806134
pub fn get_attrs<'tcx>(tcx: &'tcx ctxt, did: DefId)
61816135
-> Cow<'tcx, [ast::Attribute]> {

src/librustc/middle/ty_fold.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -350,17 +350,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialBounds<'tcx> {
350350
}
351351
}
352352

353-
impl<'tcx> TypeFoldable<'tcx> for ty::ParamBounds<'tcx> {
354-
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::ParamBounds<'tcx> {
355-
ty::ParamBounds {
356-
region_bounds: self.region_bounds.fold_with(folder),
357-
builtin_bounds: self.builtin_bounds.fold_with(folder),
358-
trait_bounds: self.trait_bounds.fold_with(folder),
359-
projection_bounds: self.projection_bounds.fold_with(folder),
360-
}
361-
}
362-
}
363-
364353
impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> {
365354
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::TypeParameterDef<'tcx> {
366355
ty::TypeParameterDef {

src/librustc/util/ppaux.rs

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -347,23 +347,6 @@ impl fmt::Debug for subst::RegionSubsts {
347347
}
348348
}
349349

350-
351-
impl<'tcx> fmt::Debug for ty::ParamBounds<'tcx> {
352-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
353-
try!(write!(f, "{:?}", self.builtin_bounds));
354-
let mut bounds = self.trait_bounds.iter();
355-
if self.builtin_bounds.is_empty() {
356-
if let Some(bound) = bounds.next() {
357-
try!(write!(f, "{:?}", bound));
358-
}
359-
}
360-
for bound in bounds {
361-
try!(write!(f, " + {:?}", bound));
362-
}
363-
Ok(())
364-
}
365-
}
366-
367350
impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
368351
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
369352
// when printing out the debug representation, we don't need
@@ -539,22 +522,6 @@ impl<'tcx> fmt::Debug for ty::MethodObject<'tcx> {
539522
}
540523
}
541524

542-
impl<'tcx> fmt::Display for ty::ParamBounds<'tcx> {
543-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
544-
try!(write!(f, "{}", self.builtin_bounds));
545-
let mut bounds = self.trait_bounds.iter();
546-
if self.builtin_bounds.is_empty() {
547-
if let Some(bound) = bounds.next() {
548-
try!(write!(f, "{}", bound));
549-
}
550-
}
551-
for bound in bounds {
552-
try!(write!(f, " + {}", bound));
553-
}
554-
Ok(())
555-
}
556-
}
557-
558525
impl<'tcx> fmt::Debug for ty::ExistentialBounds<'tcx> {
559526
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
560527
let mut empty = true;

src/librustc_typeck/astconv.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ use middle::resolve_lifetime as rl;
5656
use middle::privacy::{AllPublic, LastMod};
5757
use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
5858
use middle::traits;
59-
use middle::ty::{self, RegionEscape, Ty};
59+
use middle::ty::{self, RegionEscape, Ty, AsPredicate};
60+
use middle::ty_fold;
6061
use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ExplicitRscope,
6162
ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope};
6263
use util::common::{ErrorReported, FN_OUTPUT_NAME};
@@ -2191,3 +2192,47 @@ fn report_lifetime_number_error(tcx: &ty::ctxt, span: Span, number: usize, expec
21912192
"wrong number of lifetime parameters: expected {}, found {}",
21922193
expected, number);
21932194
}
2195+
2196+
// A helper struct for conveniently grouping a set of bounds which we pass to
2197+
// and return from functions in multiple places.
2198+
#[derive(PartialEq, Eq, Clone, Debug)]
2199+
pub struct Bounds<'tcx> {
2200+
pub region_bounds: Vec<ty::Region>,
2201+
pub builtin_bounds: ty::BuiltinBounds,
2202+
pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
2203+
pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
2204+
}
2205+
2206+
impl<'tcx> Bounds<'tcx> {
2207+
pub fn predicates(&self,
2208+
tcx: &ty::ctxt<'tcx>,
2209+
param_ty: Ty<'tcx>)
2210+
-> Vec<ty::Predicate<'tcx>>
2211+
{
2212+
let mut vec = Vec::new();
2213+
2214+
for builtin_bound in &self.builtin_bounds {
2215+
match traits::trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty) {
2216+
Ok(trait_ref) => { vec.push(trait_ref.as_predicate()); }
2217+
Err(ErrorReported) => { }
2218+
}
2219+
}
2220+
2221+
for &region_bound in &self.region_bounds {
2222+
// account for the binder being introduced below; no need to shift `param_ty`
2223+
// because, at present at least, it can only refer to early-bound regions
2224+
let region_bound = ty_fold::shift_region(region_bound, 1);
2225+
vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).as_predicate());
2226+
}
2227+
2228+
for bound_trait_ref in &self.trait_bounds {
2229+
vec.push(bound_trait_ref.as_predicate());
2230+
}
2231+
2232+
for projection in &self.projection_bounds {
2233+
vec.push(projection.as_predicate());
2234+
}
2235+
2236+
vec
2237+
}
2238+
}

0 commit comments

Comments
 (0)