Skip to content

Commit 8a33de8

Browse files
committed
auto merge of #20073 : nikomatsakis/rust/generalized-where-clause-parser, r=nikomatsakis
This is the same branch as #20002 but with the pretty-printing test fixed.
2 parents f8f2c7a + acd31db commit 8a33de8

26 files changed

+561
-150
lines changed

src/librustc/middle/privacy.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1505,6 +1505,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
15051505
self.check_ty_param_bound(bound_pred.span, bound)
15061506
}
15071507
}
1508+
&ast::WherePredicate::RegionPredicate(_) => {}
15081509
&ast::WherePredicate::EqPredicate(ref eq_pred) => {
15091510
self.visit_ty(&*eq_pred.ty);
15101511
}

src/librustc/middle/resolve_lifetime.rs

+24-4
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,21 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
206206
}
207207
for predicate in generics.where_clause.predicates.iter() {
208208
match predicate {
209-
&ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ ident,
209+
&ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ ref bounded_ty,
210210
ref bounds,
211-
span,
212211
.. }) => {
213-
self.visit_ident(span, ident);
212+
self.visit_ty(&**bounded_ty);
214213
visit::walk_ty_param_bounds_helper(self, bounds);
215214
}
215+
&ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
216+
ref bounds,
217+
.. }) => {
218+
219+
self.visit_lifetime_ref(lifetime);
220+
for bound in bounds.iter() {
221+
self.visit_lifetime_ref(bound);
222+
}
223+
}
216224
&ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ id,
217225
ref path,
218226
ref ty,
@@ -545,9 +553,21 @@ fn early_bound_lifetime_names(generics: &ast::Generics) -> Vec<ast::Name> {
545553
}
546554
for predicate in generics.where_clause.predicates.iter() {
547555
match predicate {
548-
&ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bounds, ..}) => {
556+
&ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bounds,
557+
ref bounded_ty,
558+
..}) => {
559+
collector.visit_ty(&**bounded_ty);
549560
visit::walk_ty_param_bounds_helper(&mut collector, bounds);
550561
}
562+
&ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
563+
ref bounds,
564+
..}) => {
565+
collector.visit_lifetime_ref(lifetime);
566+
567+
for bound in bounds.iter() {
568+
collector.visit_lifetime_ref(bound);
569+
}
570+
}
551571
&ast::WherePredicate::EqPredicate(_) => unimplemented!()
552572
}
553573
}

src/librustc_resolve/lib.rs

+3-16
Original file line numberDiff line numberDiff line change
@@ -4360,27 +4360,14 @@ impl<'a> Resolver<'a> {
43604360
for predicate in where_clause.predicates.iter() {
43614361
match predicate {
43624362
&ast::WherePredicate::BoundPredicate(ref bound_pred) => {
4363-
match self.resolve_identifier(bound_pred.ident,
4364-
TypeNS,
4365-
true,
4366-
bound_pred.span) {
4367-
Some((def @ DefTyParam(..), last_private)) => {
4368-
self.record_def(bound_pred.id, (def, last_private));
4369-
}
4370-
_ => {
4371-
self.resolve_error(
4372-
bound_pred.span,
4373-
format!("undeclared type parameter `{}`",
4374-
token::get_ident(
4375-
bound_pred.ident)).as_slice());
4376-
}
4377-
}
4363+
self.resolve_type(&*bound_pred.bounded_ty);
43784364

43794365
for bound in bound_pred.bounds.iter() {
4380-
self.resolve_type_parameter_bound(bound_pred.id, bound,
4366+
self.resolve_type_parameter_bound(bound_pred.bounded_ty.id, bound,
43814367
TraitBoundingTypeParameter);
43824368
}
43834369
}
4370+
&ast::WherePredicate::RegionPredicate(_) => {}
43844371
&ast::WherePredicate::EqPredicate(ref eq_pred) => {
43854372
match self.resolve_path(eq_pred.id, &eq_pred.path, TypeNS, true) {
43864373
Some((def @ DefTyParam(..), last_private)) => {

src/librustc_typeck/astconv.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -1437,11 +1437,8 @@ pub fn conv_existential_bounds<'tcx, AC: AstConv<'tcx>, RS:RegionScope>(
14371437
ast_bounds: &[ast::TyParamBound])
14381438
-> ty::ExistentialBounds
14391439
{
1440-
let ast_bound_refs: Vec<&ast::TyParamBound> =
1441-
ast_bounds.iter().collect();
1442-
14431440
let partitioned_bounds =
1444-
partition_bounds(this.tcx(), span, ast_bound_refs.as_slice());
1441+
partition_bounds(this.tcx(), span, ast_bounds);
14451442

14461443
conv_existential_bounds_from_partitioned_bounds(
14471444
this, rscope, span, principal_trait_ref, partitioned_bounds)
@@ -1455,7 +1452,6 @@ fn conv_ty_poly_trait_ref<'tcx, AC, RS>(
14551452
-> Ty<'tcx>
14561453
where AC: AstConv<'tcx>, RS:RegionScope
14571454
{
1458-
let ast_bounds: Vec<&ast::TyParamBound> = ast_bounds.iter().collect();
14591455
let mut partitioned_bounds = partition_bounds(this.tcx(), span, ast_bounds[]);
14601456

14611457
let main_trait_bound = match partitioned_bounds.trait_bounds.remove(0) {
@@ -1620,14 +1616,14 @@ pub struct PartitionedBounds<'a> {
16201616
/// general trait bounds, and region bounds.
16211617
pub fn partition_bounds<'a>(tcx: &ty::ctxt,
16221618
_span: Span,
1623-
ast_bounds: &'a [&ast::TyParamBound])
1619+
ast_bounds: &'a [ast::TyParamBound])
16241620
-> PartitionedBounds<'a>
16251621
{
16261622
let mut builtin_bounds = ty::empty_builtin_bounds();
16271623
let mut region_bounds = Vec::new();
16281624
let mut trait_bounds = Vec::new();
16291625
let mut trait_def_ids = DefIdMap::new();
1630-
for &ast_bound in ast_bounds.iter() {
1626+
for ast_bound in ast_bounds.iter() {
16311627
match *ast_bound {
16321628
ast::TraitTyParamBound(ref b) => {
16331629
match ::lookup_def_tcx(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) {

src/librustc_typeck/collect.rs

+56-54
Original file line numberDiff line numberDiff line change
@@ -1364,8 +1364,7 @@ pub fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
13641364
self_param_ty,
13651365
bounds.as_slice(),
13661366
unbound,
1367-
it.span,
1368-
&generics.where_clause);
1367+
it.span);
13691368

13701369
let substs = mk_item_substs(ccx, &ty_generics);
13711370
let trait_def = Rc::new(ty::TraitDef {
@@ -1619,7 +1618,6 @@ fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
16191618
subst::AssocSpace,
16201619
&associated_type.ty_param,
16211620
generics.types.len(subst::AssocSpace),
1622-
&ast_generics.where_clause,
16231621
Some(local_def(trait_id)));
16241622
ccx.tcx.ty_param_defs.borrow_mut().insert(associated_type.ty_param.id,
16251623
def.clone());
@@ -1774,7 +1772,6 @@ fn ty_generics<'tcx,AC>(this: &AC,
17741772
space,
17751773
param,
17761774
i,
1777-
where_clause,
17781775
None);
17791776
debug!("ty_generics: def for type param: {}, {}",
17801777
def.repr(this.tcx()),
@@ -1798,6 +1795,54 @@ fn ty_generics<'tcx,AC>(this: &AC,
17981795
// into the predicates list. This is currently kind of non-DRY.
17991796
create_predicates(this.tcx(), &mut result, space);
18001797

1798+
// Add the bounds not associated with a type parameter
1799+
for predicate in where_clause.predicates.iter() {
1800+
match predicate {
1801+
&ast::WherePredicate::BoundPredicate(ref bound_pred) => {
1802+
let ty = ast_ty_to_ty(this, &ExplicitRscope, &*bound_pred.bounded_ty);
1803+
1804+
for bound in bound_pred.bounds.iter() {
1805+
match bound {
1806+
&ast::TyParamBound::TraitTyParamBound(ref poly_trait_ref) => {
1807+
let trait_ref = astconv::instantiate_poly_trait_ref(
1808+
this,
1809+
&ExplicitRscope,
1810+
//@jroesch: for now trait_ref, poly_trait_ref?
1811+
poly_trait_ref,
1812+
Some(ty),
1813+
AllowEqConstraints::Allow
1814+
);
1815+
1816+
result.predicates.push(space, ty::Predicate::Trait(trait_ref));
1817+
}
1818+
1819+
&ast::TyParamBound::RegionTyParamBound(ref lifetime) => {
1820+
let region = ast_region_to_region(this.tcx(), lifetime);
1821+
let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
1822+
result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
1823+
}
1824+
}
1825+
}
1826+
}
1827+
1828+
&ast::WherePredicate::RegionPredicate(ref region_pred) => {
1829+
let r1 = ast_region_to_region(this.tcx(), &region_pred.lifetime);
1830+
for bound in region_pred.bounds.iter() {
1831+
let r2 = ast_region_to_region(this.tcx(), bound);
1832+
let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
1833+
result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
1834+
}
1835+
}
1836+
1837+
&ast::WherePredicate::EqPredicate(ref eq_pred) => {
1838+
// FIXME(#20041)
1839+
this.tcx().sess.span_bug(eq_pred.span,
1840+
"Equality constraints are not yet \
1841+
implemented (#20041)")
1842+
}
1843+
}
1844+
}
1845+
18011846
return result;
18021847

18031848
fn create_type_parameters_for_associated_types<'tcx, AC>(
@@ -1915,7 +1960,6 @@ fn get_or_create_type_parameter_def<'tcx,AC>(this: &AC,
19151960
space: subst::ParamSpace,
19161961
param: &ast::TyParam,
19171962
index: uint,
1918-
where_clause: &ast::WhereClause,
19191963
associated_with: Option<ast::DefId>)
19201964
-> ty::TypeParameterDef<'tcx>
19211965
where AC: AstConv<'tcx>
@@ -1931,8 +1975,7 @@ fn get_or_create_type_parameter_def<'tcx,AC>(this: &AC,
19311975
param_ty,
19321976
param.bounds.as_slice(),
19331977
&param.unbound,
1934-
param.span,
1935-
where_clause);
1978+
param.span);
19361979
let default = match param.default {
19371980
None => None,
19381981
Some(ref path) => {
@@ -1977,15 +2020,13 @@ fn compute_bounds<'tcx,AC>(this: &AC,
19772020
param_ty: ty::ParamTy,
19782021
ast_bounds: &[ast::TyParamBound],
19792022
unbound: &Option<ast::TraitRef>,
1980-
span: Span,
1981-
where_clause: &ast::WhereClause)
2023+
span: Span)
19822024
-> ty::ParamBounds<'tcx>
19832025
where AC: AstConv<'tcx> {
19842026
let mut param_bounds = conv_param_bounds(this,
19852027
span,
19862028
param_ty,
1987-
ast_bounds,
1988-
where_clause);
2029+
ast_bounds);
19892030

19902031

19912032
add_unsized_bound(this,
@@ -2031,16 +2072,14 @@ fn check_bounds_compatible<'tcx>(tcx: &ty::ctxt<'tcx>,
20312072
fn conv_param_bounds<'tcx,AC>(this: &AC,
20322073
span: Span,
20332074
param_ty: ty::ParamTy,
2034-
ast_bounds: &[ast::TyParamBound],
2035-
where_clause: &ast::WhereClause)
2075+
ast_bounds: &[ast::TyParamBound])
20362076
-> ty::ParamBounds<'tcx>
2037-
where AC: AstConv<'tcx> {
2038-
let all_bounds =
2039-
merge_param_bounds(this.tcx(), param_ty, ast_bounds, where_clause);
2077+
where AC: AstConv<'tcx>
2078+
{
20402079
let astconv::PartitionedBounds { builtin_bounds,
20412080
trait_bounds,
20422081
region_bounds } =
2043-
astconv::partition_bounds(this.tcx(), span, all_bounds.as_slice());
2082+
astconv::partition_bounds(this.tcx(), span, ast_bounds.as_slice());
20442083
let trait_bounds: Vec<Rc<ty::PolyTraitRef>> =
20452084
trait_bounds.into_iter()
20462085
.map(|bound| {
@@ -2062,43 +2101,6 @@ fn conv_param_bounds<'tcx,AC>(this: &AC,
20622101
}
20632102
}
20642103

2065-
/// Merges the bounds declared on a type parameter with those found from where clauses into a
2066-
/// single list.
2067-
fn merge_param_bounds<'a>(tcx: &ty::ctxt,
2068-
param_ty: ty::ParamTy,
2069-
ast_bounds: &'a [ast::TyParamBound],
2070-
where_clause: &'a ast::WhereClause)
2071-
-> Vec<&'a ast::TyParamBound> {
2072-
let mut result = Vec::new();
2073-
2074-
for ast_bound in ast_bounds.iter() {
2075-
result.push(ast_bound);
2076-
}
2077-
2078-
for predicate in where_clause.predicates.iter() {
2079-
match predicate {
2080-
&ast::WherePredicate::BoundPredicate(ref bound_pred) => {
2081-
let predicate_param_id =
2082-
tcx.def_map
2083-
.borrow()
2084-
.get(&bound_pred.id)
2085-
.expect("merge_param_bounds(): resolve didn't resolve the \
2086-
type parameter identifier in a `where` clause")
2087-
.def_id();
2088-
if param_ty.def_id != predicate_param_id {
2089-
continue
2090-
}
2091-
for bound in bound_pred.bounds.iter() {
2092-
result.push(bound);
2093-
}
2094-
}
2095-
&ast::WherePredicate::EqPredicate(_) => panic!("not implemented")
2096-
}
2097-
}
2098-
2099-
result
2100-
}
2101-
21022104
pub fn ty_of_foreign_fn_decl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
21032105
decl: &ast::FnDecl,
21042106
def_id: ast::DefId,

src/librustdoc/clean/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ impl Clean<Option<Lifetime>> for ty::Region {
693693

694694
#[deriving(Clone, Encodable, Decodable, PartialEq)]
695695
pub struct WherePredicate {
696-
pub name: String,
696+
pub ty: Type,
697697
pub bounds: Vec<TyParamBound>
698698
}
699699

@@ -702,11 +702,12 @@ impl Clean<WherePredicate> for ast::WherePredicate {
702702
match *self {
703703
ast::WherePredicate::BoundPredicate(ref wbp) => {
704704
WherePredicate {
705-
name: wbp.ident.clean(cx),
705+
ty: wbp.bounded_ty.clean(cx),
706706
bounds: wbp.bounds.clean(cx)
707707
}
708708
}
709-
ast::WherePredicate::EqPredicate(_) => {
709+
// FIXME(#20048)
710+
_ => {
710711
unimplemented!();
711712
}
712713
}

src/librustdoc/html/format.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ impl<'a> fmt::Show for WhereClause<'a> {
129129
try!(f.write(", ".as_bytes()));
130130
}
131131
let bounds = pred.bounds.as_slice();
132-
try!(write!(f, "{}: {}", pred.name, TyParamBounds(bounds)));
132+
try!(write!(f, "{}: {}", pred.ty, TyParamBounds(bounds)));
133133
}
134134
Ok(())
135135
}

src/libsyntax/ast.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -415,17 +415,24 @@ pub struct WhereClause {
415415
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
416416
pub enum WherePredicate {
417417
BoundPredicate(WhereBoundPredicate),
418+
RegionPredicate(WhereRegionPredicate),
418419
EqPredicate(WhereEqPredicate)
419420
}
420421

421422
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
422423
pub struct WhereBoundPredicate {
423-
pub id: NodeId,
424424
pub span: Span,
425-
pub ident: Ident,
425+
pub bounded_ty: P<Ty>,
426426
pub bounds: OwnedSlice<TyParamBound>,
427427
}
428428

429+
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
430+
pub struct WhereRegionPredicate {
431+
pub span: Span,
432+
pub lifetime: Lifetime,
433+
pub bounds: Vec<Lifetime>,
434+
}
435+
429436
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
430437
pub struct WhereEqPredicate {
431438
pub id: NodeId,

src/libsyntax/ext/deriving/generic/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -426,12 +426,18 @@ impl<'a> TraitDef<'a> {
426426
match *clause {
427427
ast::WherePredicate::BoundPredicate(ref wb) => {
428428
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
429-
id: ast::DUMMY_NODE_ID,
430429
span: self.span,
431-
ident: wb.ident,
430+
bounded_ty: wb.bounded_ty.clone(),
432431
bounds: OwnedSlice::from_vec(wb.bounds.iter().map(|b| b.clone()).collect())
433432
})
434433
}
434+
ast::WherePredicate::RegionPredicate(ref rb) => {
435+
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
436+
span: self.span,
437+
lifetime: rb.lifetime,
438+
bounds: rb.bounds.iter().map(|b| b.clone()).collect()
439+
})
440+
}
435441
ast::WherePredicate::EqPredicate(ref we) => {
436442
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
437443
id: ast::DUMMY_NODE_ID,

0 commit comments

Comments
 (0)