Skip to content

Commit baa649e

Browse files
committed
auto merge of #8027 : nikomatsakis/rust/issue-4846-multiple-lifetime-parameters-1, r=pcwalton
Small step towards #4846. r? @msullivan
2 parents 4cf3072 + dc38e16 commit baa649e

File tree

19 files changed

+304
-179
lines changed

19 files changed

+304
-179
lines changed

src/librustc/metadata/tydecode.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ fn parse_trait_store(st: &mut PState) -> ty::TraitStore {
186186
}
187187

188188
fn parse_substs(st: &mut PState, conv: conv_did) -> ty::substs {
189-
let self_r = parse_opt(st, |st| parse_region(st) );
189+
let regions = parse_region_substs(st, |x,y| conv(x,y));
190190

191191
let self_ty = parse_opt(st, |st| parse_ty(st, |x,y| conv(x,y)) );
192192

@@ -196,12 +196,28 @@ fn parse_substs(st: &mut PState, conv: conv_did) -> ty::substs {
196196
st.pos = st.pos + 1u;
197197

198198
return ty::substs {
199-
self_r: self_r,
199+
regions: regions,
200200
self_ty: self_ty,
201201
tps: params
202202
};
203203
}
204204

205+
fn parse_region_substs(st: &mut PState, conv: conv_did) -> ty::RegionSubsts {
206+
match next(st) {
207+
'e' => ty::ErasedRegions,
208+
'n' => {
209+
let mut regions = opt_vec::Empty;
210+
while peek(st) != '.' {
211+
let r = parse_region(st);
212+
regions.push(r);
213+
}
214+
assert_eq!(next(st), '.');
215+
ty::NonerasedRegions(regions)
216+
}
217+
_ => fail!("parse_bound_region: bad input")
218+
}
219+
}
220+
205221
fn parse_bound_region(st: &mut PState) -> ty::bound_region {
206222
match next(st) {
207223
's' => ty::br_self,

src/librustc/metadata/tyencode.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,28 @@ fn enc_opt<T>(w: @io::Writer, t: Option<T>, enc_f: &fn(T)) {
120120
}
121121

122122
fn enc_substs(w: @io::Writer, cx: @ctxt, substs: &ty::substs) {
123-
do enc_opt(w, substs.self_r) |r| { enc_region(w, cx, r) }
123+
enc_region_substs(w, cx, &substs.regions);
124124
do enc_opt(w, substs.self_ty) |t| { enc_ty(w, cx, t) }
125125
w.write_char('[');
126126
for substs.tps.iter().advance |t| { enc_ty(w, cx, *t); }
127127
w.write_char(']');
128128
}
129129

130+
fn enc_region_substs(w: @io::Writer, cx: @ctxt, substs: &ty::RegionSubsts) {
131+
match *substs {
132+
ty::ErasedRegions => {
133+
w.write_char('e');
134+
}
135+
ty::NonerasedRegions(ref regions) => {
136+
w.write_char('n');
137+
for regions.iter().advance |&r| {
138+
enc_region(w, cx, r);
139+
}
140+
w.write_char('.');
141+
}
142+
}
143+
}
144+
130145
fn enc_region(w: @io::Writer, cx: @ctxt, r: ty::Region) {
131146
match r {
132147
ty::re_bound(br) => {

src/librustc/middle/kind.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use util::ppaux::UserString;
1919
use syntax::ast::*;
2020
use syntax::attr;
2121
use syntax::codemap::span;
22+
use syntax::opt_vec;
2223
use syntax::print::pprust::expr_to_str;
2324
use syntax::{visit, ast_util};
2425

@@ -83,7 +84,7 @@ fn check_struct_safe_for_destructor(cx: Context,
8384
let struct_tpt = ty::lookup_item_type(cx.tcx, struct_did);
8485
if !struct_tpt.generics.has_type_params() {
8586
let struct_ty = ty::mk_struct(cx.tcx, struct_did, ty::substs {
86-
self_r: None,
87+
regions: ty::NonerasedRegions(opt_vec::Empty),
8788
self_ty: None,
8889
tps: ~[]
8990
});

src/librustc/middle/subst.rs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313

1414
use middle::ty;
15+
use syntax::opt_vec::OptVec;
1516
use util::ppaux::Repr;
1617

1718
///////////////////////////////////////////////////////////////////////////
@@ -79,6 +80,12 @@ impl<T:Subst> Subst for ~[T] {
7980
}
8081
}
8182

83+
impl<T:Subst> Subst for OptVec<T> {
84+
fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> OptVec<T> {
85+
self.map(|t| t.subst(tcx, substs))
86+
}
87+
}
88+
8289
impl<T:Subst + 'static> Subst for @T {
8390
fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> @T {
8491
match self {
@@ -105,13 +112,26 @@ impl Subst for ty::TraitRef {
105112
impl Subst for ty::substs {
106113
fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> ty::substs {
107114
ty::substs {
108-
self_r: self.self_r.subst(tcx, substs),
115+
regions: self.regions.subst(tcx, substs),
109116
self_ty: self.self_ty.map(|typ| typ.subst(tcx, substs)),
110117
tps: self.tps.map(|typ| typ.subst(tcx, substs))
111118
}
112119
}
113120
}
114121

122+
impl Subst for ty::RegionSubsts {
123+
fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> ty::RegionSubsts {
124+
match *self {
125+
ty::ErasedRegions => {
126+
ty::ErasedRegions
127+
}
128+
ty::NonerasedRegions(ref regions) => {
129+
ty::NonerasedRegions(regions.subst(tcx, substs))
130+
}
131+
}
132+
}
133+
}
134+
115135
impl Subst for ty::BareFnTy {
116136
fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> ty::BareFnTy {
117137
ty::fold_bare_fn_ty(self, |t| t.subst(tcx, substs))
@@ -158,15 +178,18 @@ impl Subst for ty::Region {
158178
// will most likely disappear.
159179
match self {
160180
&ty::re_bound(ty::br_self) => {
161-
match substs.self_r {
162-
None => {
163-
tcx.sess.bug(
164-
fmt!("ty::Region#subst(): \
165-
Reference to self region when \
166-
given substs with no self region: %s",
167-
substs.repr(tcx)));
181+
match substs.regions {
182+
ty::ErasedRegions => ty::re_static,
183+
ty::NonerasedRegions(ref regions) => {
184+
if regions.len() != 1 {
185+
tcx.sess.bug(
186+
fmt!("ty::Region#subst(): \
187+
Reference to self region when \
188+
given substs with no self region: %s",
189+
substs.repr(tcx)));
190+
}
191+
*regions.get(0)
168192
}
169-
Some(self_r) => self_r
170193
}
171194
}
172195
_ => *self

src/librustc/middle/trans/base.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,8 @@ pub fn get_res_dtor(ccx: @mut CrateContext,
515515
did
516516
};
517517
assert_eq!(did.crate, ast::local_crate);
518-
let tsubsts = ty::substs { self_r: None, self_ty: None,
518+
let tsubsts = ty::substs {regions: ty::ErasedRegions,
519+
self_ty: None,
519520
tps: /*bad*/ substs.to_owned() };
520521
let (val, _) = monomorphize::monomorphic_fn(ccx,
521522
did,

src/librustc/middle/trans/callee.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -274,15 +274,10 @@ pub fn trans_fn_ref_with_vtables(
274274
// Polytype of the function item (may have type params)
275275
let fn_tpt = ty::lookup_item_type(tcx, def_id);
276276

277-
// For simplicity, we want to use the Subst trait when composing
278-
// substitutions for default methods. The subst trait does
279-
// substitutions with regions, though, so we put a dummy self
280-
// region parameter in to keep it from failing. This is a hack.
281-
let substs = ty::substs { self_r: Some(ty::re_empty),
277+
let substs = ty::substs { regions: ty::ErasedRegions,
282278
self_ty: None,
283279
tps: /*bad*/ type_params.to_owned() };
284280

285-
286281
// We need to do a bunch of special handling for default methods.
287282
// We need to modify the def_id and our substs in order to monomorphize
288283
// the function.

src/librustc/middle/trans/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,7 @@ pub fn find_vtable(tcx: ty::ctxt,
11031103

11041104
pub fn dummy_substs(tps: ~[ty::t]) -> ty::substs {
11051105
substs {
1106-
self_r: Some(ty::re_bound(ty::br_self)),
1106+
regions: ty::ErasedRegions,
11071107
self_ty: None,
11081108
tps: tps
11091109
}

src/librustc/middle/trans/type_of.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use util::ppaux;
1717
use middle::trans::type_::Type;
1818

1919
use syntax::ast;
20+
use syntax::opt_vec;
2021

2122
pub fn arg_is_indirect(ccx: &CrateContext, arg_ty: &ty::t) -> bool {
2223
!ty::type_is_immediate(ccx.tcx, *arg_ty)
@@ -312,7 +313,8 @@ pub fn llvm_type_name(cx: &CrateContext,
312313
a_struct => { "struct" }
313314
an_enum => { "enum" }
314315
};
315-
let tstr = ppaux::parameterized(cx.tcx, ty::item_path_str(cx.tcx, did), None, tps);
316+
let tstr = ppaux::parameterized(cx.tcx, ty::item_path_str(cx.tcx, did),
317+
&ty::NonerasedRegions(opt_vec::Empty), tps);
316318
if did.crate == 0 {
317319
fmt!("%s.%s", name, tstr)
318320
} else {

src/librustc/middle/ty.rs

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,15 @@ pub enum bound_region {
489489
br_cap_avoid(ast::node_id, @bound_region),
490490
}
491491

492-
type opt_region = Option<Region>;
492+
/**
493+
* Represents the values to use when substituting lifetime parameters.
494+
* If the value is `ErasedRegions`, then this subst is occurring during
495+
* trans, and all region parameters will be replaced with `ty::re_static`. */
496+
#[deriving(Clone, Eq, IterBytes)]
497+
pub enum RegionSubsts {
498+
ErasedRegions,
499+
NonerasedRegions(OptVec<ty::Region>)
500+
}
493501

494502
/**
495503
* The type substs represents the kinds of things that can be substituted to
@@ -510,9 +518,9 @@ type opt_region = Option<Region>;
510518
* always substituted away to the implementing type for a trait. */
511519
#[deriving(Clone, Eq, IterBytes)]
512520
pub struct substs {
513-
self_r: opt_region,
514521
self_ty: Option<ty::t>,
515-
tps: ~[t]
522+
tps: ~[t],
523+
regions: RegionSubsts,
516524
}
517525

518526
mod primitives {
@@ -952,7 +960,14 @@ fn mk_t(cx: ctxt, st: sty) -> t {
952960
fn sflags(substs: &substs) -> uint {
953961
let mut f = 0u;
954962
for substs.tps.iter().advance |tt| { f |= get(*tt).flags; }
955-
for substs.self_r.iter().advance |r| { f |= rflags(*r) }
963+
match substs.regions {
964+
ErasedRegions => {}
965+
NonerasedRegions(ref regions) => {
966+
for regions.iter().advance |r| {
967+
f |= rflags(*r)
968+
}
969+
}
970+
}
956971
return f;
957972
}
958973
match &st {
@@ -1290,7 +1305,7 @@ pub fn fold_bare_fn_ty(fty: &BareFnTy, fldop: &fn(t) -> t) -> BareFnTy {
12901305

12911306
fn fold_sty(sty: &sty, fldop: &fn(t) -> t) -> sty {
12921307
fn fold_substs(substs: &substs, fldop: &fn(t) -> t) -> substs {
1293-
substs {self_r: substs.self_r,
1308+
substs {regions: substs.regions.clone(),
12941309
self_ty: substs.self_ty.map(|t| fldop(*t)),
12951310
tps: substs.tps.map(|t| fldop(*t))}
12961311
}
@@ -1382,8 +1397,15 @@ pub fn fold_regions_and_ty(
13821397
fldr: &fn(r: Region) -> Region,
13831398
fldt: &fn(t: t) -> t)
13841399
-> substs {
1400+
let regions = match substs.regions {
1401+
ErasedRegions => ErasedRegions,
1402+
NonerasedRegions(ref regions) => {
1403+
NonerasedRegions(regions.map(|r| fldr(*r)))
1404+
}
1405+
};
1406+
13851407
substs {
1386-
self_r: substs.self_r.map(|r| fldr(*r)),
1408+
regions: regions,
13871409
self_ty: substs.self_ty.map(|t| fldt(*t)),
13881410
tps: substs.tps.map(|t| fldt(*t))
13891411
}
@@ -1482,8 +1504,13 @@ pub fn subst_tps(cx: ctxt, tps: &[t], self_ty_opt: Option<t>, typ: t) -> t {
14821504
}
14831505

14841506
pub fn substs_is_noop(substs: &substs) -> bool {
1507+
let regions_is_noop = match substs.regions {
1508+
ErasedRegions => false, // may be used to canonicalize
1509+
NonerasedRegions(ref regions) => regions.is_empty()
1510+
};
1511+
14851512
substs.tps.len() == 0u &&
1486-
substs.self_r.is_none() &&
1513+
regions_is_noop &&
14871514
substs.self_ty.is_none()
14881515
}
14891516

@@ -4238,30 +4265,33 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t {
42384265
})
42394266
}
42404267

4241-
ty_enum(did, ref r) =>
4242-
match (*r).self_r {
4243-
Some(_) =>
4244-
// Use re_static since trans doesn't care about regions
4245-
mk_enum(cx, did,
4246-
substs {
4247-
self_r: Some(ty::re_static),
4248-
self_ty: None,
4249-
tps: (*r).tps.clone()
4250-
}),
4251-
None =>
4268+
ty_enum(did, ref r) => {
4269+
match (*r).regions {
4270+
NonerasedRegions(_) => {
4271+
// trans doesn't care about regions
4272+
mk_enum(cx, did, substs {regions: ty::ErasedRegions,
4273+
self_ty: None,
4274+
tps: (*r).tps.clone()})
4275+
}
4276+
ErasedRegions => {
42524277
t
4253-
},
4278+
}
4279+
}
4280+
}
42544281

4255-
ty_struct(did, ref r) =>
4256-
match (*r).self_r {
4257-
Some(_) =>
4258-
// Ditto.
4259-
mk_struct(cx, did, substs {self_r: Some(ty::re_static),
4260-
self_ty: None,
4261-
tps: (*r).tps.clone()}),
4262-
None =>
4263-
t
4264-
},
4282+
ty_struct(did, ref r) => {
4283+
match (*r).regions {
4284+
NonerasedRegions(_) => {
4285+
// Ditto.
4286+
mk_struct(cx, did, substs {regions: ty::ErasedRegions,
4287+
self_ty: None,
4288+
tps: (*r).tps.clone()})
4289+
}
4290+
ErasedRegions => {
4291+
t
4292+
}
4293+
}
4294+
}
42654295

42664296
_ =>
42674297
t
@@ -4421,7 +4451,7 @@ pub fn visitor_object_ty(tcx: ctxt) -> Result<(@TraitRef, t), ~str> {
44214451
Err(s) => { return Err(s); }
44224452
};
44234453
let substs = substs {
4424-
self_r: None,
4454+
regions: ty::NonerasedRegions(opt_vec::Empty),
44254455
self_ty: None,
44264456
tps: ~[]
44274457
};

0 commit comments

Comments
 (0)