From 81e5c1ff061d2538ce2c3832ad33202a0135558d Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Tue, 16 Jun 2015 15:53:13 -0700 Subject: [PATCH] Remove the mostly unecessary ParamBounds struct --- src/librustc/metadata/tydecode.rs | 88 ++++++------------------------- src/librustc/metadata/tyencode.rs | 16 +----- src/librustc/middle/implicator.rs | 11 ++-- src/librustc/middle/ty.rs | 72 +++++-------------------- src/librustc/middle/ty_fold.rs | 11 ---- src/librustc/util/ppaux.rs | 33 ------------ src/librustc_typeck/astconv.rs | 47 ++++++++++++++++- src/librustc_typeck/collect.rs | 35 ++++++------ src/librustdoc/clean/mod.rs | 13 ----- 9 files changed, 100 insertions(+), 226 deletions(-) diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 693ccc13f1e..3907b0624b4 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -195,15 +195,6 @@ pub fn parse_substs_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: us parse_substs(&mut st, conv) } -pub fn parse_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, - pos: usize, tcx: &ty::ctxt<'tcx>, conv: F) - -> ty::ParamBounds<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - let mut st = parse_state_from_data(data, crate_num, pos, tcx); - parse_bounds(&mut st, conv) -} - pub fn parse_existential_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, tcx: &ty::ctxt<'tcx>, conv: F) -> ty::ExistentialBounds<'tcx> where @@ -879,11 +870,23 @@ fn parse_existential_bounds_<'a,'tcx, F>(st: &mut PState<'a,'tcx>, -> ty::ExistentialBounds<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { - let ty::ParamBounds { trait_bounds, mut region_bounds, builtin_bounds, projection_bounds } = - parse_bounds_(st, conv); - assert_eq!(region_bounds.len(), 1); - assert_eq!(trait_bounds.len(), 0); - let region_bound = region_bounds.pop().unwrap(); + let builtin_bounds = parse_builtin_bounds_(st, conv); + let region_bound = parse_region_(st, conv); + let mut projection_bounds = Vec::new(); + + loop { + match next(st) { + 'P' => { + projection_bounds.push( + ty::Binder(parse_projection_predicate_(st, conv))); + } + '.' => { break; } + c => { + panic!("parse_bounds: bad bounds ('{}')", c) + } + } + } + return ty::ExistentialBounds { region_bound: region_bound, builtin_bounds: builtin_bounds, projection_bounds: projection_bounds }; @@ -923,60 +926,3 @@ fn parse_builtin_bounds_(st: &mut PState, _conv: &mut F) -> ty::BuiltinBounds } } } - -fn parse_bounds<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F) - -> ty::ParamBounds<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - parse_bounds_(st, &mut conv) -} - -fn parse_bounds_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) - -> ty::ParamBounds<'tcx> where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - let builtin_bounds = parse_builtin_bounds_(st, conv); - - let region_bounds = parse_region_bounds_(st, conv); - - let mut param_bounds = ty::ParamBounds { - region_bounds: region_bounds, - builtin_bounds: builtin_bounds, - trait_bounds: Vec::new(), - projection_bounds: Vec::new(), - }; - - - loop { - match next(st) { - 'I' => { - param_bounds.trait_bounds.push( - ty::Binder(parse_trait_ref_(st, conv))); - } - 'P' => { - param_bounds.projection_bounds.push( - ty::Binder(parse_projection_predicate_(st, conv))); - } - '.' => { - return param_bounds; - } - c => { - panic!("parse_bounds: bad bounds ('{}')", c) - } - } - } -} - -fn parse_region_bounds_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) - -> Vec where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - let mut region_bounds = Vec::new(); - loop { - match next(st) { - 'R' => { region_bounds.push(parse_region_(st, conv)); } - '.' => { return region_bounds; } - c => { panic!("parse_bounds: bad bounds ('{}')", c); } - } - } -} diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 72e96121a3a..c078b62dd2d 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -380,23 +380,9 @@ pub fn enc_builtin_bounds(w: &mut Encoder, _cx: &ctxt, bs: &ty::BuiltinBounds) { pub fn enc_existential_bounds<'a,'tcx>(w: &mut Encoder, cx: &ctxt<'a,'tcx>, bs: &ty::ExistentialBounds<'tcx>) { - let param_bounds = ty::ParamBounds { trait_bounds: vec!(), - region_bounds: vec!(bs.region_bound), - builtin_bounds: bs.builtin_bounds, - projection_bounds: bs.projection_bounds.clone() }; - enc_bounds(w, cx, ¶m_bounds); -} - -pub fn enc_bounds<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, - bs: &ty::ParamBounds<'tcx>) { enc_builtin_bounds(w, cx, &bs.builtin_bounds); - enc_region_bounds(w, cx, &bs.region_bounds); - - for tp in &bs.trait_bounds { - mywrite!(w, "I"); - enc_trait_ref(w, cx, tp.0); - } + enc_region(w, cx, bs.region_bound); for tp in &bs.projection_bounds { mywrite!(w, "P"); diff --git a/src/librustc/middle/implicator.rs b/src/librustc/middle/implicator.rs index d26df43286d..bbfa3c9fdfa 100644 --- a/src/librustc/middle/implicator.rs +++ b/src/librustc/middle/implicator.rs @@ -13,7 +13,7 @@ use middle::infer::{InferCtxt, GenericKind}; use middle::subst::Substs; use middle::traits; -use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty}; +use middle::ty::{self, RegionEscape, ToPolyTraitRef, AsPredicate, Ty}; use middle::ty_fold::{TypeFoldable, TypeFolder}; use syntax::ast; @@ -444,13 +444,8 @@ pub fn object_region_bounds<'tcx>( let substs = tcx.mk_substs(principal.0.substs.with_self_ty(open_ty)); let trait_refs = vec!(ty::Binder(ty::TraitRef::new(principal.0.def_id, substs))); - let param_bounds = ty::ParamBounds { - region_bounds: Vec::new(), - builtin_bounds: others, - trait_bounds: trait_refs, - projection_bounds: Vec::new(), // not relevant to computing region bounds - }; + let mut predicates = others.to_predicates(tcx, open_ty); + predicates.extend(trait_refs.iter().map(|t| t.as_predicate())); - let predicates = ty::predicates(tcx, open_ty, ¶m_bounds); ty::required_region_bounds(tcx, open_ty, predicates) } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 3497a8d6904..0e3b1375b87 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1847,21 +1847,8 @@ pub enum type_err<'tcx> { terr_projection_bounds_length(expected_found), } -/// Bounds suitable for a named type parameter like `A` in `fn foo` -/// as well as the existential type parameter in an object type. -#[derive(PartialEq, Eq, Hash, Clone)] -pub struct ParamBounds<'tcx> { - pub region_bounds: Vec, - pub builtin_bounds: BuiltinBounds, - pub trait_bounds: Vec>, - pub projection_bounds: Vec>, -} - /// Bounds suitable for an existentially quantified type parameter -/// such as those that appear in object types or closure types. The -/// major difference between this case and `ParamBounds` is that -/// general purpose trait bounds are omitted and there must be -/// *exactly one* region. +/// such as those that appear in object types or closure types. #[derive(PartialEq, Eq, Hash, Clone)] pub struct ExistentialBounds<'tcx> { pub region_bound: ty::Region, @@ -1873,13 +1860,24 @@ pub struct ExistentialBounds<'tcx> { pub struct BuiltinBounds(EnumSet); impl BuiltinBounds { - pub fn empty() -> BuiltinBounds { + pub fn empty() -> BuiltinBounds { BuiltinBounds(EnumSet::new()) } pub fn iter(&self) -> enum_set::Iter { self.into_iter() } + + pub fn to_predicates<'tcx>(&self, + tcx: &ty::ctxt<'tcx>, + self_ty: Ty<'tcx>) -> Vec> { + self.iter().filter_map(|builtin_bound| + match traits::trait_ref_for_builtin_bound(tcx, builtin_bound, self_ty) { + Ok(trait_ref) => Some(trait_ref.as_predicate()), + Err(ErrorReported) => { None } + } + ).collect() + } } impl ops::Deref for BuiltinBounds { @@ -3703,17 +3701,6 @@ pub fn is_noop(&self) -> bool { } } -impl<'tcx> ParamBounds<'tcx> { - pub fn empty() -> ParamBounds<'tcx> { - ParamBounds { - builtin_bounds: BuiltinBounds::empty(), - trait_bounds: Vec::new(), - region_bounds: Vec::new(), - projection_bounds: Vec::new(), - } - } -} - // Type utilities pub fn type_is_nil(ty: Ty) -> bool { @@ -6142,39 +6129,6 @@ pub fn lookup_super_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) || csearch::get_super_predicates(cx, did)) } -pub fn predicates<'tcx>( - tcx: &ctxt<'tcx>, - param_ty: Ty<'tcx>, - bounds: &ParamBounds<'tcx>) - -> Vec> -{ - let mut vec = Vec::new(); - - for builtin_bound in &bounds.builtin_bounds { - match traits::trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty) { - Ok(trait_ref) => { vec.push(trait_ref.as_predicate()); } - Err(ErrorReported) => { } - } - } - - for ®ion_bound in &bounds.region_bounds { - // account for the binder being introduced below; no need to shift `param_ty` - // because, at present at least, it can only refer to early-bound regions - let region_bound = ty_fold::shift_region(region_bound, 1); - vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).as_predicate()); - } - - for bound_trait_ref in &bounds.trait_bounds { - vec.push(bound_trait_ref.as_predicate()); - } - - for projection in &bounds.projection_bounds { - vec.push(projection.as_predicate()); - } - - vec -} - /// Get the attributes of a definition. pub fn get_attrs<'tcx>(tcx: &'tcx ctxt, did: DefId) -> Cow<'tcx, [ast::Attribute]> { diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 63c46032479..fe89ca751e7 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -350,17 +350,6 @@ fn fold_with>(&self, folder: &mut F) -> ty::ExistentialBound } } -impl<'tcx> TypeFoldable<'tcx> for ty::ParamBounds<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::ParamBounds<'tcx> { - ty::ParamBounds { - region_bounds: self.region_bounds.fold_with(folder), - builtin_bounds: self.builtin_bounds.fold_with(folder), - trait_bounds: self.trait_bounds.fold_with(folder), - projection_bounds: self.projection_bounds.fold_with(folder), - } - } -} - impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> { fn fold_with>(&self, folder: &mut F) -> ty::TypeParameterDef<'tcx> { ty::TypeParameterDef { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 485d856ac25..0ae089df50d 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -347,23 +347,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } - -impl<'tcx> fmt::Debug for ty::ParamBounds<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{:?}", self.builtin_bounds)); - let mut bounds = self.trait_bounds.iter(); - if self.builtin_bounds.is_empty() { - if let Some(bound) = bounds.next() { - try!(write!(f, "{:?}", bound)); - } - } - for bound in bounds { - try!(write!(f, " + {:?}", bound)); - } - Ok(()) - } -} - impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // when printing out the debug representation, we don't need @@ -539,22 +522,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -impl<'tcx> fmt::Display for ty::ParamBounds<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{}", self.builtin_bounds)); - let mut bounds = self.trait_bounds.iter(); - if self.builtin_bounds.is_empty() { - if let Some(bound) = bounds.next() { - try!(write!(f, "{}", bound)); - } - } - for bound in bounds { - try!(write!(f, " + {}", bound)); - } - Ok(()) - } -} - impl<'tcx> fmt::Debug for ty::ExistentialBounds<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut empty = true; diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index d42e4bc0834..72ff0792475 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -56,7 +56,8 @@ use middle::privacy::{AllPublic, LastMod}; use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs}; use middle::traits; -use middle::ty::{self, RegionEscape, Ty}; +use middle::ty::{self, RegionEscape, Ty, AsPredicate}; +use middle::ty_fold; use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ExplicitRscope, ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope}; use util::common::{ErrorReported, FN_OUTPUT_NAME}; @@ -2191,3 +2192,47 @@ fn report_lifetime_number_error(tcx: &ty::ctxt, span: Span, number: usize, expec "wrong number of lifetime parameters: expected {}, found {}", expected, number); } + +// A helper struct for conveniently grouping a set of bounds which we pass to +// and return from functions in multiple places. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct Bounds<'tcx> { + pub region_bounds: Vec, + pub builtin_bounds: ty::BuiltinBounds, + pub trait_bounds: Vec>, + pub projection_bounds: Vec>, +} + +impl<'tcx> Bounds<'tcx> { + pub fn predicates(&self, + tcx: &ty::ctxt<'tcx>, + param_ty: Ty<'tcx>) + -> Vec> + { + let mut vec = Vec::new(); + + for builtin_bound in &self.builtin_bounds { + match traits::trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty) { + Ok(trait_ref) => { vec.push(trait_ref.as_predicate()); } + Err(ErrorReported) => { } + } + } + + for ®ion_bound in &self.region_bounds { + // account for the binder being introduced below; no need to shift `param_ty` + // because, at present at least, it can only refer to early-bound regions + let region_bound = ty_fold::shift_region(region_bound, 1); + vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).as_predicate()); + } + + for bound_trait_ref in &self.trait_bounds { + vec.push(bound_trait_ref.as_predicate()); + } + + for projection in &self.projection_bounds { + vec.push(projection.as_predicate()); + } + + vec + } +} diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 13d2cf25e06..22926126f7a 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1178,9 +1178,13 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt, // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`. let self_param_ty = ty::mk_self_type(tcx); - let superbounds1 = compute_bounds(&ccx.icx(scope), self_param_ty, bounds, - SizedByDefault::No, item.span); - let superbounds1 = ty::predicates(tcx, self_param_ty, &superbounds1); + let superbounds1 = compute_bounds(&ccx.icx(scope), + self_param_ty, + bounds, + SizedByDefault::No, + item.span); + + let superbounds1 = superbounds1.predicates(tcx, self_param_ty); // Convert any explicit superbounds in the where clause, // e.g. `trait Foo where Self : Bar`: @@ -1395,7 +1399,7 @@ fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, SizedByDefault::Yes, trait_item.span); - ty::predicates(ccx.tcx, assoc_ty, &bounds).into_iter() + bounds.predicates(ccx.tcx, assoc_ty).into_iter() }).collect() } } @@ -1743,7 +1747,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, ¶m.bounds, SizedByDefault::Yes, param.span); - let predicates = ty::predicates(ccx.tcx, param_ty, &bounds); + let predicates = bounds.predicates(ccx.tcx, param_ty); result.predicates.extend(space, predicates.into_iter()); } @@ -1989,23 +1993,24 @@ fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>, ast_bounds: &[ast::TyParamBound], sized_by_default: SizedByDefault, span: Span) - -> ty::ParamBounds<'tcx> + -> astconv::Bounds<'tcx> { - let mut param_bounds = conv_param_bounds(astconv, - span, - param_ty, - ast_bounds); + let mut bounds = + conv_param_bounds(astconv, + span, + param_ty, + ast_bounds); if let SizedByDefault::Yes = sized_by_default { add_unsized_bound(astconv, - &mut param_bounds.builtin_bounds, + &mut bounds.builtin_bounds, ast_bounds, span); } - param_bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id())); + bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id())); - param_bounds + bounds } /// Converts a specific TyParamBound from the AST into a set of @@ -2055,7 +2060,7 @@ fn conv_param_bounds<'a,'tcx>(astconv: &AstConv<'tcx>, span: Span, param_ty: ty::Ty<'tcx>, ast_bounds: &[ast::TyParamBound]) - -> ty::ParamBounds<'tcx> + -> astconv::Bounds<'tcx> { let tcx = astconv.tcx(); let astconv::PartitionedBounds { @@ -2079,7 +2084,7 @@ fn conv_param_bounds<'a,'tcx>(astconv: &AstConv<'tcx>, .map(|r| ast_region_to_region(tcx, r)) .collect(); - ty::ParamBounds { + astconv::Bounds { region_bounds: region_bounds, builtin_bounds: builtin_bounds, trait_bounds: trait_bounds, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d40a9522f23..8ba4470c3ef 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -716,19 +716,6 @@ fn clean(&self, cx: &DocContext) -> TyParamBound { } } -impl<'tcx> Clean> for ty::ParamBounds<'tcx> { - fn clean(&self, cx: &DocContext) -> Vec { - let mut v = Vec::new(); - for t in &self.trait_bounds { - v.push(t.clean(cx)); - } - for r in self.region_bounds.iter().filter_map(|r| r.clean(cx)) { - v.push(RegionBound(r)); - } - v - } -} - impl<'tcx> Clean>> for subst::Substs<'tcx> { fn clean(&self, cx: &DocContext) -> Option> { let mut v = Vec::new(); -- GitLab