about summary refs log tree commit diff
path: root/src/librustc/metadata
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2015-04-03 19:50:32 +0200
committerFelix S. Klock II <pnkfelix@pnkfx.org>2015-04-04 09:23:40 +0200
commit05b8a106e45b0c8381c6bc89e76e7bb94b03a84c (patch)
treef61eccebacd9d2a5ff64783ca5e0095e52d58d8a /src/librustc/metadata
parentd1835ae7cc175b9aff383432e934e7ad13825ebc (diff)
Encode more precise scoping rules for function params.
Function params which outlive everything in the body (incl
temporaries).  Thus if we assign them their own `CodeExtent`, the
region inference can properly show that it is sound to have
temporaries with destructors that reference the parameters (because
such temporaries will be dropped before the parameters are).

This allows us to address issue 23338 in a clean way.

As a drive-by, fix a mistake in the tyencode for
`CodeExtent::BlockRemainder`.
Diffstat (limited to 'src/librustc/metadata')
-rw-r--r--src/librustc/metadata/tydecode.rs13
-rw-r--r--src/librustc/metadata/tyencode.rs4
2 files changed, 16 insertions, 1 deletions
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 3fb128b1881..8030275ef30 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -373,6 +373,16 @@ fn parse_region_<F>(st: &mut PState, conv: &mut F) -> ty::Region where
 
 fn parse_scope(st: &mut PState) -> region::CodeExtent {
     match next(st) {
+        'P' => {
+            assert_eq!(next(st), '[');
+            let fn_id = parse_uint(st) as ast::NodeId;
+            assert_eq!(next(st), '|');
+            let body_id = parse_uint(st) as ast::NodeId;
+            assert_eq!(next(st), ']');
+            region::CodeExtent::ParameterScope {
+                fn_id: fn_id, body_id: body_id
+            }
+        }
         'M' => {
             let node_id = parse_uint(st) as ast::NodeId;
             region::CodeExtent::Misc(node_id)
@@ -382,8 +392,11 @@ fn parse_scope(st: &mut PState) -> region::CodeExtent {
             region::CodeExtent::DestructionScope(node_id)
         }
         'B' => {
+            assert_eq!(next(st), '[');
             let node_id = parse_uint(st) as ast::NodeId;
+            assert_eq!(next(st), '|');
             let first_stmt_index = parse_uint(st);
+            assert_eq!(next(st), ']');
             let block_remainder = region::BlockRemainder {
                 block: node_id, first_statement_index: first_stmt_index,
             };
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index 7a2df496628..90a905f1840 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -275,9 +275,11 @@ pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) {
 
 fn enc_scope(w: &mut Encoder, _cx: &ctxt, scope: region::CodeExtent) {
     match scope {
+        region::CodeExtent::ParameterScope {
+            fn_id, body_id } => mywrite!(w, "P[{}|{}]", fn_id, body_id),
         region::CodeExtent::Misc(node_id) => mywrite!(w, "M{}", node_id),
         region::CodeExtent::Remainder(region::BlockRemainder {
-            block: b, first_statement_index: i }) => mywrite!(w, "B{}{}", b, i),
+            block: b, first_statement_index: i }) => mywrite!(w, "B[{}|{}]", b, i),
         region::CodeExtent::DestructionScope(node_id) => mywrite!(w, "D{}", node_id),
     }
 }