Skip to content

Commit 3004f0e

Browse files
committed
---
yaml --- r: 42475 b: refs/heads/try c: 9fed56e h: refs/heads/master i: 42473: 5bdd300 42471: ec23b11 v: v3
1 parent 37a8d1e commit 3004f0e

File tree

6 files changed

+144
-23
lines changed

6 files changed

+144
-23
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 19dfec2aaf746535de1521f68421f9980dbf25de
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 2f46b763da2c098913884f101b6d71d69af41b49
5-
refs/heads/try: c7abdd38473ef2ef3fe50a0d234b8cd27fc53f0e
5+
refs/heads/try: 9fed56ed9035912a2657b07ab1b7671706bd9576
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: a810c03263670238bccd64cabb12a23a46e3a278

branches/try/src/librustc/metadata/decoder.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,8 @@ fn variant_disr_val(d: ebml::Doc) -> Option<int> {
264264

265265
fn doc_type(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::t {
266266
let tp = reader::get_doc(doc, tag_items_data_item_type);
267-
parse_ty_data(tp.data, cdata.cnum, tp.start, tcx, |did| {
268-
translate_def_id(cdata, did)
269-
})
267+
parse_ty_data(tp.data, cdata.cnum, tp.start, tcx,
268+
|_, did| translate_def_id(cdata, did))
270269
}
271270

272271
fn item_type(item_id: ast::def_id, item: ebml::Doc,
@@ -289,9 +288,8 @@ fn item_ty_param_bounds(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd)
289288
-> @~[ty::param_bounds] {
290289
let mut bounds = ~[];
291290
for reader::tagged_docs(item, tag_items_data_item_ty_param_bounds) |p| {
292-
let bd = parse_bounds_data(p.data, p.start, cdata.cnum, tcx, |did| {
293-
translate_def_id(cdata, did)
294-
});
291+
let bd = parse_bounds_data(p.data, p.start, cdata.cnum, tcx,
292+
|_, did| translate_def_id(cdata, did));
295293
bounds.push(bd);
296294
}
297295
@bounds

branches/try/src/librustc/metadata/tydecode.rs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,33 @@ export parse_state_from_data;
3333
export parse_arg_data, parse_ty_data, parse_def_id, parse_ident;
3434
export parse_bounds_data;
3535
export pstate;
36+
export DefIdSource, NominalType, TypeWithId, TypeParameter;
3637

3738
// Compact string representation for ty::t values. API ty_str &
3839
// parse_from_str. Extra parameters are for converting to/from def_ids in the
3940
// data buffer. Whatever format you choose should not contain pipe characters.
4041

41-
// Callback to translate defs to strs or back:
42-
type conv_did = fn(ast::def_id) -> ast::def_id;
42+
// Def id conversion: when we encounter def-ids, they have to be translated.
43+
// For example, the crate number must be converted from the crate number used
44+
// in the library we are reading from into the local crate numbers in use
45+
// here. To perform this translation, the type decoder is supplied with a
46+
// conversion function of type `conv_did`.
47+
//
48+
// Sometimes, particularly when inlining, the correct translation of the
49+
// def-id will depend on where it originated from. Therefore, the conversion
50+
// function is given an indicator of the source of the def-id. See
51+
// astencode.rs for more information.
52+
enum DefIdSource {
53+
// Identifies a struct, trait, enum, etc.
54+
NominalType,
55+
56+
// Identifies a type alias (`type X = ...`).
57+
TypeWithId,
58+
59+
// Identifies a type parameter (`fn foo<X>() { ... }`).
60+
TypeParameter
61+
}
62+
type conv_did = fn(source: DefIdSource, ast::def_id) -> ast::def_id;
4363

4464
type pstate = {data: @~[u8], crate: int, mut pos: uint, tcx: ty::ctxt};
4565

@@ -245,21 +265,21 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
245265
'c' => return ty::mk_char(st.tcx),
246266
't' => {
247267
assert (next(st) == '[');
248-
let def = parse_def(st, conv);
268+
let def = parse_def(st, NominalType, conv);
249269
let substs = parse_substs(st, conv);
250270
assert next(st) == ']';
251271
return ty::mk_enum(st.tcx, def, substs);
252272
}
253273
'x' => {
254274
assert next(st) == '[';
255-
let def = parse_def(st, conv);
275+
let def = parse_def(st, NominalType, conv);
256276
let substs = parse_substs(st, conv);
257277
let vstore = parse_vstore(st);
258278
assert next(st) == ']';
259279
return ty::mk_trait(st.tcx, def, substs, vstore);
260280
}
261281
'p' => {
262-
let did = parse_def(st, conv);
282+
let did = parse_def(st, TypeParameter, conv);
263283
return ty::mk_param(st.tcx, parse_int(st) as uint, did);
264284
}
265285
's' => {
@@ -327,17 +347,14 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
327347
}
328348
}
329349
'"' => {
330-
let def = parse_def(st, conv);
350+
let def = parse_def(st, TypeWithId, conv);
331351
let inner = parse_ty(st, conv);
332352
ty::mk_with_id(st.tcx, inner, def)
333353
}
334354
'B' => ty::mk_opaque_box(st.tcx),
335355
'a' => {
336-
debug!("saw a class");
337356
assert (next(st) == '[');
338-
debug!("saw a [");
339-
let did = parse_def(st, conv);
340-
debug!("parsed a def_id %?", did);
357+
let did = parse_def(st, NominalType, conv);
341358
let substs = parse_substs(st, conv);
342359
assert (next(st) == ']');
343360
return ty::mk_struct(st.tcx, did, substs);
@@ -356,11 +373,12 @@ fn parse_mt(st: @pstate, conv: conv_did) -> ty::mt {
356373
ty::mt { ty: parse_ty(st, conv), mutbl: m }
357374
}
358375

359-
fn parse_def(st: @pstate, conv: conv_did) -> ast::def_id {
376+
fn parse_def(st: @pstate, source: DefIdSource,
377+
conv: conv_did) -> ast::def_id {
360378
let mut def = ~[];
361379
while peek(st) != '|' { def.push(next_byte(st)); }
362380
st.pos = st.pos + 1u;
363-
return conv(parse_def_id(def));
381+
return conv(source, parse_def_id(def));
364382
}
365383

366384
fn parse_int(st: @pstate) -> int {

branches/try/src/librustc/middle/astencode.rs

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use e = metadata::encoder;
1717
use metadata::decoder;
1818
use metadata::encoder;
1919
use metadata::tydecode;
20+
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter};
2021
use metadata::tyencode;
2122
use middle::freevars::freevar_entry;
2223
use middle::typeck::{method_origin, method_map_entry, vtable_res};
@@ -168,14 +169,55 @@ fn reserve_id_range(sess: Session,
168169

169170
impl extended_decode_ctxt {
170171
fn tr_id(id: ast::node_id) -> ast::node_id {
172+
/*!
173+
*
174+
* Translates an internal id, meaning a node id that is known
175+
* to refer to some part of the item currently being inlined,
176+
* such as a local variable or argument. All naked node-ids
177+
* that appear in types have this property, since if something
178+
* might refer to an external item we would use a def-id to
179+
* allow for the possibility that the item resides in another
180+
* crate.
181+
*/
182+
171183
// from_id_range should be non-empty
172184
assert !ast_util::empty(self.from_id_range);
173185
(id - self.from_id_range.min + self.to_id_range.min)
174186
}
175187
fn tr_def_id(did: ast::def_id) -> ast::def_id {
188+
/*!
189+
*
190+
* Translates an EXTERNAL def-id, converting the crate number
191+
* from the one used in the encoded data to the current crate
192+
* numbers.. By external, I mean that it be translated to a
193+
* reference to the item in its original crate, as opposed to
194+
* being translated to a reference to the inlined version of
195+
* the item. This is typically, but not always, what you
196+
* want, because most def-ids refer to external things like
197+
* types or other fns that may or may not be inlined. Note
198+
* that even when the inlined function is referencing itself
199+
* recursively, we would want `tr_def_id` for that
200+
* reference--- conceptually the function calls the original,
201+
* non-inlined version, and trans deals with linking that
202+
* recursive call to the inlined copy.
203+
*
204+
* However, there are a *few* cases where def-ids are used but
205+
* we know that the thing being referenced is in fact *internal*
206+
* to the item being inlined. In those cases, you should use
207+
* `tr_intern_def_id()` below.
208+
*/
209+
176210
decoder::translate_def_id(self.dcx.cdata, did)
177211
}
178212
fn tr_intern_def_id(did: ast::def_id) -> ast::def_id {
213+
/*!
214+
*
215+
* Translates an INTERNAL def-id, meaning a def-id that is
216+
* known to refer to some part of the item currently being
217+
* inlined. In that case, we want to convert the def-id to
218+
* refer to the current crate and to the new, inlined node-id.
219+
*/
220+
179221
assert did.crate == ast::local_crate;
180222
ast::def_id { crate: ast::local_crate, node: self.tr_id(did.node) }
181223
}
@@ -906,15 +948,17 @@ trait ebml_decoder_decoder_helpers {
906948
fn read_bounds(xcx: extended_decode_ctxt) -> @~[ty::param_bound];
907949
fn read_ty_param_bounds_and_ty(xcx: extended_decode_ctxt)
908950
-> ty::ty_param_bounds_and_ty;
951+
fn convert_def_id(xcx: extended_decode_ctxt,
952+
source: DefIdSource,
953+
did: ast::def_id) -> ast::def_id;
909954
}
910955

911956
impl reader::Decoder: ebml_decoder_decoder_helpers {
912-
913957
fn read_arg(xcx: extended_decode_ctxt) -> ty::arg {
914958
do self.read_opaque |doc| {
915959
tydecode::parse_arg_data(
916960
doc.data, xcx.dcx.cdata.cnum, doc.start, xcx.dcx.tcx,
917-
|a| xcx.tr_def_id(a))
961+
|s, a| self.convert_def_id(xcx, s, a))
918962
}
919963
}
920964

@@ -927,7 +971,7 @@ impl reader::Decoder: ebml_decoder_decoder_helpers {
927971
do self.read_opaque |doc| {
928972
tydecode::parse_ty_data(
929973
doc.data, xcx.dcx.cdata.cnum, doc.start, xcx.dcx.tcx,
930-
|a| xcx.tr_def_id(a))
974+
|s, a| self.convert_def_id(xcx, s, a))
931975
}
932976
}
933977

@@ -939,7 +983,7 @@ impl reader::Decoder: ebml_decoder_decoder_helpers {
939983
do self.read_opaque |doc| {
940984
tydecode::parse_bounds_data(
941985
doc.data, doc.start, xcx.dcx.cdata.cnum, xcx.dcx.tcx,
942-
|a| xcx.tr_def_id(a))
986+
|s, a| self.convert_def_id(xcx, s, a))
943987
}
944988
}
945989

@@ -960,6 +1004,29 @@ impl reader::Decoder: ebml_decoder_decoder_helpers {
9601004
}
9611005
}
9621006
}
1007+
1008+
fn convert_def_id(xcx: extended_decode_ctxt,
1009+
source: tydecode::DefIdSource,
1010+
did: ast::def_id) -> ast::def_id {
1011+
/*!
1012+
*
1013+
* Converts a def-id that appears in a type. The correct
1014+
* translation will depend on what kind of def-id this is.
1015+
* This is a subtle point: type definitions are not
1016+
* inlined into the current crate, so if the def-id names
1017+
* a nominal type or type alias, then it should be
1018+
* translated to refer to the source crate.
1019+
*
1020+
* However, *type parameters* are cloned along with the function
1021+
* they are attached to. So we should translate those def-ids
1022+
* to refer to the new, cloned copy of the type parameter.
1023+
*/
1024+
1025+
match source {
1026+
NominalType | TypeWithId => xcx.tr_def_id(did),
1027+
TypeParameter => xcx.tr_intern_def_id(did)
1028+
}
1029+
}
9631030
}
9641031

9651032
fn decode_side_tables(xcx: extended_decode_ctxt,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub fn to_closure<A: Durable Copy>(x: A) -> @fn() -> A {
12+
fn@() -> A { copy x }
13+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// xfail-fast - check-fast doesn't understand aux-build
12+
// aux-build:issue4516_ty_param_lib.rs
13+
14+
// Trigger a bug concerning inlining of generic functions.
15+
// The def-ids in type parameters were not being correctly
16+
// resolved and hence when we checked the type of the closure
17+
// variable (see the library mod) to determine if the value
18+
// should be moved into the closure, trans failed to find
19+
// the relevant kind bounds.
20+
21+
extern mod issue4516_ty_param_lib;
22+
use issue4516_ty_param_lib::to_closure;
23+
fn main() {
24+
to_closure(22)();
25+
}

0 commit comments

Comments
 (0)