Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

more sound treatment of fn& regions; change all & to be distinct

  • Loading branch information...
commit 652b312122139501ae513e9c985d9c31030684b3 1 parent 8ee79c7
Niko Matsakis nikomatsakis authored
Showing with 229 additions and 133 deletions.
  1. +1 −1  src/libcore/option.rs
  2. +1 −1  src/libstd/arc.rs
  3. +1 −1  src/libstd/sync.rs
  4. +3 −2 src/libsyntax/ast.rs
  5. +4 −4 src/libsyntax/ast_util.rs
  6. +0 −3  src/rustc/driver/driver.rs
  7. +5 −1 src/rustc/metadata/tydecode.rs
  8. +5 −1 src/rustc/metadata/tyencode.rs
  9. +5 −2 src/rustc/middle/astencode.rs
  10. +0 −47 src/rustc/middle/block_use.rs
  11. +1 −1  src/rustc/middle/freevars.rs
  12. +2 −2 src/rustc/middle/kind.rs
  13. +1 −1  src/rustc/middle/mem_categorization.rs
  14. +5 −4 src/rustc/middle/resolve3.rs
  15. +1 −1  src/rustc/middle/trans/base.rs
  16. +2 −1  src/rustc/middle/trans/foreign.rs
  17. +1 −1  src/rustc/middle/tstate/auxiliary.rs
  18. +6 −5 src/rustc/middle/ty.rs
  19. +3 −2 src/rustc/middle/typeck/check.rs
  20. +79 −0 src/rustc/middle/typeck/check/regionck.rs
  21. +1 −1  src/rustc/middle/typeck/check/regionmanip.rs
  22. +1 −1  src/rustc/middle/typeck/check/vtable.rs
  23. +8 −3 src/rustc/middle/typeck/rscope.rs
  24. +0 −1  src/rustc/rustc.rc
  25. +16 −10 src/rustc/util/ppaux.rs
  26. +3 −1 src/test/bench/shootout-binarytrees.rs
  27. +0 −8 src/test/compile-fail/block-copy.rs
  28. +1 −1  src/test/compile-fail/borrowck-confuse-region.rs
  29. +0 −8 src/test/compile-fail/issue-1896.rs
  30. +9 −0 src/test/compile-fail/regions-freevar.rs
  31. +1 −1  src/test/compile-fail/regions-glb-free-free.rs
  32. +1 −1  src/test/compile-fail/regions-infer-borrow-scope-too-big.rs
  33. +1 −1  src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs
  34. +1 −1  src/test/compile-fail/regions-infer-call-3.rs
  35. +15 −0 src/test/compile-fail/regions-steal-closure.rs
  36. +1 −1  src/test/run-pass/borrowck-root-while-cond.rs
  37. +2 −2 src/test/run-pass/explicit-self.rs
  38. +1 −1  src/test/run-pass/issue-2748-b.rs
  39. +1 −1  src/test/run-pass/region-return-interior-of-option.rs
  40. +1 −1  src/test/run-pass/regions-addr-of-interior-of-unique-box.rs
  41. +15 −0 src/test/run-pass/regions-copy-closure.rs
  42. +1 −1  src/test/run-pass/regions-creating-enums2.rs
  43. +1 −1  src/test/run-pass/regions-escape-into-other-fn.rs
  44. +1 −1  src/test/run-pass/regions-infer-borrow-scope-view.rs
  45. +1 −1  src/test/run-pass/regions-infer-borrow-scope-within-loop-ok.rs
  46. +1 −1  src/test/run-pass/regions-infer-borrow-scope.rs
  47. +1 −1  src/test/run-pass/regions-mock-trans-impls.rs
  48. +1 −1  src/test/run-pass/regions-nullary-variant.rs
  49. +1 −1  src/test/run-pass/regions-params.rs
  50. +16 −0 src/test/run-pass/regions-static-closure.rs
2  src/libcore/option.rs
View
@@ -29,7 +29,7 @@ pure fn get<T: copy>(opt: option<T>) -> T {
}
}
-pure fn get_ref<T>(opt: &option<T>) -> &T {
+pure fn get_ref<T>(opt: &r/option<T>) -> &r/T {
/*!
* Gets an immutable reference to the value inside an option.
*
2  src/libstd/arc.rs
View
@@ -361,7 +361,7 @@ impl<T: const send> &rw_arc<T> {
}
/// To be called inside of the write_downgrade block.
- fn downgrade(+token: rw_write_mode<T>) -> rw_read_mode<T> {
+ fn downgrade(+token: rw_write_mode/&a<T>) -> rw_read_mode/&a<T> {
// The rwlock should assert that the token belongs to us for us.
let state = unsafe { get_shared_immutable_state(&self.x) };
let rw_write_mode((data, t, _poison)) = token;
2  src/libstd/sync.rs
View
@@ -538,7 +538,7 @@ impl &rwlock {
}
/// To be called inside of the write_downgrade block.
- fn downgrade(+token: rwlock_write_mode) -> rwlock_read_mode {
+ fn downgrade(+token: rwlock_write_mode/&a) -> rwlock_read_mode/&a {
if !ptr::ref_eq(self, token.lock) {
fail ~"Can't downgrade() with a different rwlock's write_mode!";
}
5 src/libsyntax/ast.rs
View
@@ -84,9 +84,10 @@ enum def {
def_ty_param(def_id, uint),
def_binding(node_id, binding_mode),
def_use(def_id),
- def_upvar(node_id /* local id of closed over var */,
+ def_upvar(node_id /* id of closed over var */,
@def /* closed over def */,
- node_id /* expr node that creates the closure */),
+ node_id /* expr node that creates the closure */,
+ node_id /* id for the block/body of the closure expr */),
def_class(def_id, bool /* has constructor */),
def_typaram_binder(node_id), /* class, impl or trait that has ty params */
def_region(node_id),
8 src/libsyntax/ast_util.rs
View
@@ -60,7 +60,7 @@ pure fn def_id_of_def(d: def) -> def_id {
id
}
def_arg(id, _) | def_local(id, _) | def_self(id) |
- def_upvar(id, _, _) | def_binding(id, _) | def_region(id)
+ def_upvar(id, _, _, _) | def_binding(id, _) | def_region(id)
| def_typaram_binder(id) | def_label(id) => {
local_def(id)
}
@@ -381,9 +381,9 @@ impl inlined_item: inlined_item_utils {
referring to a def_self */
fn is_self(d: ast::def) -> bool {
match d {
- def_self(_) => true,
- def_upvar(_, d, _) => is_self(*d),
- _ => false
+ def_self(_) => true,
+ def_upvar(_, d, _, _) => is_self(*d),
+ _ => false
}
}
3  src/rustc/driver/driver.rs
View
@@ -207,9 +207,6 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
if upto == cu_typeck { return {crate: crate, tcx: some(ty_cx)}; }
- time(time_passes, ~"block-use checking", ||
- middle::block_use::check_crate(ty_cx, crate));
-
time(time_passes, ~"loop checking", ||
middle::check_loop::check_crate(ty_cx, crate));
6 src/rustc/metadata/tydecode.rs
View
@@ -128,7 +128,11 @@ fn parse_substs(st: @pstate, conv: conv_did) -> ty::substs {
fn parse_bound_region(st: @pstate) -> ty::bound_region {
match check next(st) {
's' => ty::br_self,
- 'a' => ty::br_anon,
+ 'a' => {
+ let id = parse_int(st) as uint;
+ assert next(st) == '|';
+ ty::br_anon(id)
+ }
'[' => ty::br_named(@parse_str(st, ']')),
'c' => {
let id = parse_int(st);
6 src/rustc/metadata/tyencode.rs
View
@@ -154,7 +154,11 @@ fn enc_region(w: io::Writer, cx: @ctxt, r: ty::region) {
fn enc_bound_region(w: io::Writer, br: ty::bound_region) {
match br {
ty::br_self => w.write_char('s'),
- ty::br_anon => w.write_char('a'),
+ ty::br_anon(idx) => {
+ w.write_char('a');
+ w.write_uint(idx);
+ w.write_char('|');
+ }
ty::br_named(s) => {
w.write_char('[');
w.write_str(*s);
7 src/rustc/middle/astencode.rs
View
@@ -363,8 +363,11 @@ impl ast::def: tr {
ast::def_ty_param(did, v) => ast::def_ty_param(did.tr(xcx), v),
ast::def_binding(nid, bm) => ast::def_binding(xcx.tr_id(nid), bm),
ast::def_use(did) => ast::def_use(did.tr(xcx)),
- ast::def_upvar(nid1, def, nid2) => {
- ast::def_upvar(xcx.tr_id(nid1), @(*def).tr(xcx), xcx.tr_id(nid2))
+ ast::def_upvar(nid1, def, nid2, nid3) => {
+ ast::def_upvar(xcx.tr_id(nid1),
+ @(*def).tr(xcx),
+ xcx.tr_id(nid2),
+ xcx.tr_id(nid3))
}
ast::def_class(did, has_constructor) => {
ast::def_class(did.tr(xcx), has_constructor)
47 src/rustc/middle/block_use.rs
View
@@ -1,47 +0,0 @@
-import syntax::visit;
-import syntax::ast::*;
-import driver::session::session;
-
-type ctx = {tcx: ty::ctxt, mut allow_block: bool};
-
-fn check_crate(tcx: ty::ctxt, crate: @crate) {
- let cx = {tcx: tcx, mut allow_block: false};
- let v = visit::mk_vt(@{visit_expr: visit_expr
- with *visit::default_visitor()});
- visit::visit_crate(*crate, cx, v);
-}
-
-fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
- if !cx.allow_block {
- match ty::get(ty::expr_ty(cx.tcx, ex)).struct {
- ty::ty_fn({proto: p, _}) if ty::is_blockish(p) => {
- cx.tcx.sess.span_err(ex.span,
- ~"expressions with stack closure type \
- can only appear in callee or (by-ref) argument position");
- }
- _ => {}
- }
- }
- let outer = cx.allow_block;
- match ex.node {
- expr_call(f, args, _) => {
- cx.allow_block = true;
- v.visit_expr(f, cx, v);
- let mut i = 0u;
- for ty::ty_fn_args(ty::expr_ty(cx.tcx, f)).each |arg_t| {
- cx.allow_block = (ty::arg_mode(cx.tcx, arg_t) == by_ref);
- v.visit_expr(args[i], cx, v);
- i += 1u;
- }
- }
- expr_loop_body(body) | expr_do_body(body) => {
- cx.allow_block = true;
- v.visit_expr(body, cx, v);
- }
- _ => {
- cx.allow_block = false;
- visit::visit_expr(ex, cx, v);
- }
- }
- cx.allow_block = outer;
-}
2  src/rustc/middle/freevars.rs
View
@@ -55,7 +55,7 @@ fn collect_freevars(def_map: resolve3::DefMap, blk: ast::blk)
let mut def = df;
while i < depth {
match copy def {
- ast::def_upvar(_, inner, _) => { def = *inner; }
+ ast::def_upvar(_, inner, _, _) => { def = *inner; }
_ => break
}
i += 1;
4 src/rustc/middle/kind.rs
View
@@ -103,7 +103,7 @@ fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) {
// copied in data must be copyable, but moved in data can be anything
let is_implicit = fv.is_some();
- if !is_move { check_copy(cx, id, var_t, sp, is_implicit); }
+ if !is_move { check_copy(cx, id, var_t, sp, is_implicit); }
// check that only immutable variables are implicitly copied in
for fv.each |fv| {
@@ -426,7 +426,7 @@ fn check_imm_free_var(cx: ctx, def: def, sp: span) {
}
}
}
- def_upvar(_, def1, _) => {
+ def_upvar(_, def1, _, _) => {
check_imm_free_var(cx, *def1, sp);
}
def_binding(*) | def_self(*) => { /*ok*/ }
2  src/rustc/middle/mem_categorization.rs
View
@@ -378,7 +378,7 @@ impl &mem_categorization_ctxt {
mutbl:m_imm, ty:expr_ty}
}
- ast::def_upvar(upvid, inner, fn_node_id) => {
+ ast::def_upvar(upvid, inner, fn_node_id, _) => {
let ty = ty::node_id_to_type(self.tcx, fn_node_id);
let proto = ty::ty_fn_proto(ty);
match proto {
9 src/rustc/middle/resolve3.rs
View
@@ -199,7 +199,7 @@ enum RibKind {
// We passed through a function scope at the given node ID. Translate
// upvars as appropriate.
- FunctionRibKind(node_id),
+ FunctionRibKind(node_id /* func id */, node_id /* body id */),
// We passed through a class, impl, or trait and are now in one of its
// methods. Allow references to ty params that that class, impl or trait
@@ -2752,11 +2752,12 @@ struct Resolver {
NormalRibKind => {
// Nothing to do. Continue.
}
- FunctionRibKind(function_id) => {
+ FunctionRibKind(function_id, body_id) => {
if !is_ty_param {
def = def_upvar(def_id_of_def(def).node,
@def,
- function_id);
+ function_id,
+ body_id);
}
}
MethodRibKind(item_id, method_id) => {
@@ -4164,7 +4165,7 @@ struct Resolver {
expr_fn(_, fn_decl, block, capture_clause) |
expr_fn_block(fn_decl, block, capture_clause) => {
- self.resolve_function(FunctionRibKind(expr.id),
+ self.resolve_function(FunctionRibKind(expr.id, block.node.id),
some(@fn_decl),
NoTypeParameters,
block,
2  src/rustc/middle/trans/base.rs
View
@@ -2464,7 +2464,7 @@ fn trans_local_var(cx: block, def: ast::def) -> local_var_result {
}
}
match def {
- ast::def_upvar(nid, _, _) => {
+ ast::def_upvar(nid, _, _, _) => {
assert (cx.fcx.llupvars.contains_key(nid));
return { val: cx.fcx.llupvars.get(nid), kind: lv_owned };
}
3  src/rustc/middle/trans/foreign.rs
View
@@ -961,7 +961,8 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
let fty = ty::mk_fn(bcx.tcx(), {
purity: ast::impure_fn,
proto:
- ty::proto_vstore(ty::vstore_slice(ty::re_bound(ty::br_anon))),
+ ty::proto_vstore(ty::vstore_slice(
+ ty::re_bound(ty::br_anon(0)))),
bounds: @~[],
inputs: ~[{
mode: ast::expl(ast::by_val),
2  src/rustc/middle/tstate/auxiliary.rs
View
@@ -525,7 +525,7 @@ fn expr_to_constr_arg(tcx: ty::ctxt, e: @expr) -> @constr_arg_use {
expr_path(p) {
match tcx.def_map.find(e.id) {
some(def_local(nid, _)) | some(def_arg(nid, _)) |
- some(def_binding(nid, _)) | some(def_upvar(nid, _, _)) {
+ some(def_binding(nid, _)) | some(def_upvar(nid, _, _, _)) {
return @respan(p.span,
carg_ident({ident: p.idents[0], node: nid}));
}
11 src/rustc/middle/ty.rs
View
@@ -377,8 +377,8 @@ enum bound_region {
/// The self region for classes, impls (&T in a type defn or &self/T)
br_self,
- /// Anonymous region parameter for a given fn (&T)
- br_anon,
+ /// An anonymous region parameter for a given fn (&T)
+ br_anon(uint),
/// Named region parameters for functions (a in &a/T)
br_named(ast::ident),
@@ -2192,9 +2192,10 @@ fn index_sty(cx: ctxt, sty: &sty) -> option<mt> {
pure fn hash_bound_region(br: &bound_region) -> uint {
match *br { // no idea if this is any good
ty::br_self => 0u,
- ty::br_anon => 1u,
- ty::br_named(str) => str::hash(str),
- ty::br_cap_avoid(id, br) => id as uint | hash_bound_region(br)
+ ty::br_anon(idx) => 1u | (idx << 2),
+ ty::br_named(str) => 2u | (str::hash(str) << 2),
+ ty::br_cap_avoid(id, br) =>
+ 3u | (id as uint << 2) | hash_bound_region(br)
}
}
5 src/rustc/middle/typeck/check.rs
View
@@ -2304,7 +2304,7 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) ->
ast::def_ty(_) | ast::def_prim_ty(_) => {
fcx.ccx.tcx.sess.span_fatal(sp, ~"expected value but found type");
}
- ast::def_upvar(_, inner, _) => {
+ ast::def_upvar(_, inner, _, _) => {
return ty_param_bounds_and_ty_for_def(fcx, sp, *inner);
}
ast::def_ty_param(did, n) => {
@@ -2513,7 +2513,8 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
let fty = ty::mk_fn(ccx.tcx, {
purity: ast::impure_fn,
proto:
- ty::proto_vstore(ty::vstore_slice(ty::re_bound(ty::br_anon))),
+ ty::proto_vstore(ty::vstore_slice(
+ ty::re_bound(ty::br_anon(0)))),
bounds: @~[],
inputs: ~[{
mode: ast::expl(ast::by_val),
79 src/rustc/middle/typeck/check/regionck.rs
View
@@ -21,12 +21,42 @@ import util::ppaux;
import ppaux::{note_and_explain_region, ty_to_str};
import syntax::print::pprust;
import infer::{resolve_and_force_all_but_regions, fres};
+import syntax::ast::{def_arg, def_binding, def_local, def_self, def_upvar};
+import middle::freevars::get_freevars;
import middle::kind::check_owned;
import middle::pat_util::pat_bindings;
+import middle::ty::{encl_region, proto_bare, proto_vstore, re_scope};
+import middle::ty::{ty_fn_proto, vstore_box, vstore_fixed, vstore_slice};
+import middle::ty::{vstore_uniq};
enum rcx { rcx_({fcx: @fn_ctxt, mut errors_reported: uint}) }
type rvt = visit::vt<@rcx>;
+fn encl_region_of_def(fcx: @fn_ctxt, def: ast::def) -> ty::region {
+ let tcx = fcx.tcx();
+ match def {
+ def_local(node_id, _) | def_arg(node_id, _) | def_self(node_id) |
+ def_binding(node_id, _) =>
+ return encl_region(tcx, node_id),
+ def_upvar(local_id, subdef, closure_id, body_id) => {
+ match ty_fn_proto(fcx.node_ty(closure_id)) {
+ proto_bare =>
+ tcx.sess.bug(~"proto_bare in encl_region_of_def?!"),
+ proto_vstore(vstore_fixed(_)) =>
+ tcx.sess.bug(~"vstore_fixed in encl_region_of_def?!"),
+ proto_vstore(vstore_slice(_)) =>
+ encl_region_of_def(fcx, *subdef),
+ proto_vstore(vstore_uniq) | proto_vstore(vstore_box) =>
+ re_scope(body_id)
+ }
+ }
+ _ => {
+ tcx.sess.bug(fmt!("unexpected def in encl_region_of_def: %?",
+ def))
+ }
+ }
+}
+
impl @rcx {
/// Try to resolve the type for the given node.
///
@@ -180,6 +210,22 @@ fn visit_expr(e: @ast::expr, &&rcx: @rcx, v: rvt) {
// See #3148 for more details.
}
+ ast::expr_fn(*) | ast::expr_fn_block(*) => {
+ match rcx.resolve_node_type(e.id) {
+ result::err(_) => return, // Typechecking will fail anyhow.
+ result::ok(function_type) => {
+ match ty::get(function_type).struct {
+ ty::ty_fn({
+ proto: proto_vstore(vstore_slice(region)), _
+ }) => {
+ constrain_free_variables(rcx, region, e);
+ }
+ _ => ()
+ }
+ }
+ }
+ }
+
_ => ()
}
@@ -217,6 +263,39 @@ fn visit_node(id: ast::node_id, span: span, rcx: @rcx) -> bool {
return constrain_regions_in_type(rcx, encl_region, span, ty);
}
+fn constrain_free_variables(
+ rcx: @rcx,
+ region: ty::region,
+ expr: @ast::expr)
+{
+ // Make sure that all regions referenced by the free
+ // variables inside the closure outlive the closure
+ // itself.
+ let tcx = rcx.fcx.ccx.tcx;
+ for get_freevars(tcx, expr.id).each |freevar| {
+ debug!("freevar def is %?", freevar.def);
+ let def = freevar.def;
+ let en_region = encl_region_of_def(rcx.fcx, def);
+ match rcx.fcx.mk_subr(true, freevar.span,
+ region, en_region) {
+ result::ok(()) => {}
+ result::err(_) => {
+ tcx.sess.span_err(
+ freevar.span,
+ ~"captured variable does not outlive the enclosing closure");
+ note_and_explain_region(
+ tcx,
+ ~"captured variable is valid for",
+ en_region);
+ note_and_explain_region(
+ tcx,
+ ~"closure is valid for",
+ region);
+ }
+ }
+ }
+}
+
fn constrain_regions_in_type(
rcx: @rcx,
encl_region: ty::region,
2  src/rustc/middle/typeck/check/regionmanip.rs
View
@@ -148,7 +148,7 @@ fn replace_bound_regions_in_fn_ty(
// As long as we are not within a fn() type, `&T` is
// mapped to the free region anon_r. But within a fn
// type, it remains bound.
- ty::re_bound(ty::br_anon) if in_fn => r,
+ ty::re_bound(ty::br_anon(_)) if in_fn => r,
ty::re_bound(br) => {
match isr.find(br) {
2  src/rustc/middle/typeck/check/vtable.rs
View
@@ -321,7 +321,7 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
if !is_early { cx.vtable_map.insert(callee_id, vtbls); }
}
}
- _ => ()
+ none => ()
}
}
ast::expr_cast(src, _) => {
11 src/rustc/middle/typeck/rscope.rs
View
@@ -52,15 +52,20 @@ impl @anon_rscope: region_scope {
}
}
-enum binding_rscope = {base: region_scope};
+struct binding_rscope {
+ base: region_scope;
+ mut anon_bindings: uint;
+}
fn in_binding_rscope<RS: region_scope copy owned>(self: RS)
-> @binding_rscope {
let base = self as region_scope;
- @binding_rscope({base: base})
+ @binding_rscope { base: base, anon_bindings: 0 }
}
impl @binding_rscope: region_scope {
fn anon_region(_span: span) -> result<ty::region, ~str> {
- result::ok(ty::re_bound(ty::br_anon))
+ let idx = self.anon_bindings;
+ self.anon_bindings += 1;
+ result::ok(ty::re_bound(ty::br_anon(idx)))
}
fn named_region(span: span, id: ast::ident) -> result<ty::region, ~str> {
do self.base.named_region(span, id).chain_err |_e| {
1  src/rustc/rustc.rc
View
@@ -94,7 +94,6 @@ mod middle {
}
mod mem_categorization;
mod liveness;
- mod block_use;
mod kind;
mod freevars;
mod capture;
26 src/rustc/util/ppaux.rs
View
@@ -68,18 +68,21 @@ fn explain_region_and_span(cx: ctxt, region: ty::region)
}
re_free(id, br) => {
+ let prefix = match br {
+ br_anon(idx) => fmt!("the anonymous lifetime #%u defined on",
+ idx + 1),
+ _ => fmt!("the lifetime %s as defined on",
+ bound_region_to_str(cx, br))
+ };
+
match cx.items.find(id) {
some(ast_map::node_block(blk)) => {
let (msg, opt_span) = explain_span(cx, ~"block", blk.span);
- (fmt!("the lifetime %s as defined on %s",
- bound_region_to_str(cx, br), msg),
- opt_span)
+ (fmt!("%s %s", prefix, msg), opt_span)
}
some(_) | none => {
// this really should not happen
- (fmt!("the lifetime %s as defined on node %d",
- bound_region_to_str(cx, br), id),
- none)
+ (fmt!("%s node %d", prefix, id), none)
}
}
}
@@ -103,10 +106,13 @@ fn explain_region_and_span(cx: ctxt, region: ty::region)
fn bound_region_to_str(cx: ctxt, br: bound_region) -> ~str {
match br {
- br_anon => { ~"&" }
- br_named(str) => { fmt!{"&%s", *str} }
- br_self if cx.sess.ppregions() => { ~"&<self>" }
- br_self => { ~"&self" }
+ br_named(str) => fmt!{"&%s", *str},
+ br_self if cx.sess.ppregions() => ~"&<self>",
+ br_self => ~"&self",
+
+ br_anon(idx) => {
+ if cx.sess.ppregions() {fmt!("&%u", idx)} else {~"&"}
+ }
// FIXME(#3011) -- even if this arm is removed, exhaustiveness checking
// does not fail
4 src/test/bench/shootout-binarytrees.rs
View
@@ -13,7 +13,9 @@ fn item_check(t: &tree) -> int {
}
}
-fn bottom_up_tree(arena: &arena::arena, item: int, depth: int) -> &tree {
+fn bottom_up_tree(arena: &r/arena::arena,
+ item: int,
+ depth: int) -> &r/tree {
if depth > 0 {
return arena.alloc(
|| node(bottom_up_tree(arena, 2 * item - 1, depth - 1),
8 src/test/compile-fail/block-copy.rs
View
@@ -1,8 +0,0 @@
-// error-pattern: stack closure type can only appear
-
-fn lol(f: fn()) -> fn() { return f; }
-fn main() {
- let i = 8;
- let f = lol(fn&() { log(error, i); });
- f();
-}
2  src/test/compile-fail/borrowck-confuse-region.rs
View
@@ -8,7 +8,7 @@
fn get() -> &int {
let x = 3;
return &x;
- //~^ ERROR illegal borrow: borrowed pointer must be valid for the lifetime & as defined on the block at 8:17, but the borrowed value is only valid for the block at 8:17
+ //~^ ERROR illegal borrow: borrowed pointer must be valid for the anonymous lifetime #1 defined on the block at 8:17, but the borrowed value is only valid for the block at 8:17
}
fn main() {}
8 src/test/compile-fail/issue-1896.rs
View
@@ -1,8 +0,0 @@
-type t<T> = { f: fn() -> T };
-
-fn f<T>(_x: t<T>) {}
-
-fn main() {
- let x: t<()> = { f: || () }; //~ ERROR expressions with stack closure
- f(x);
-}
9 src/test/compile-fail/regions-freevar.rs
View
@@ -0,0 +1,9 @@
+fn wants_static_fn(_x: &static/fn()) {}
+
+fn main() {
+ let i = 3;
+ do wants_static_fn {
+ #debug("i=%d", i);
+ //~^ ERROR captured variable does not outlive the enclosing closure
+ }
+}
2  src/test/compile-fail/regions-glb-free-free.rs
View
@@ -11,7 +11,7 @@ mod argparse {
mut value: uint;
}
- fn flag(name: &str, desc: &str) -> Flag {
+ fn flag(name: &r/str, desc: &r/str) -> Flag/&r {
Flag { name: name, desc: desc, max_count: 1, value: 0 }
}
2  src/test/compile-fail/regions-infer-borrow-scope-too-big.rs
View
@@ -1,6 +1,6 @@
type point = {x: int, y: int};
-fn x_coord(p: &point) -> &int {
+fn x_coord(p: &r/point) -> &r/int {
return &p.x;
}
2  src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs
View
@@ -1,4 +1,4 @@
-fn borrow<T>(x: &T) -> &T {x}
+fn borrow<T>(x: &r/T) -> &r/T {x}
fn foo(cond: fn() -> bool, box: fn() -> @int) {
let mut y: &int;
2  src/test/compile-fail/regions-infer-call-3.rs
View
@@ -1,4 +1,4 @@
-fn select(x: &int, y: &int) -> &int { x }
+fn select(x: &r/int, y: &r/int) -> &r/int { x }
fn with<T>(f: fn(x: &int) -> T) -> T {
f(&20)
15 src/test/compile-fail/regions-steal-closure.rs
View
@@ -0,0 +1,15 @@
+struct closure_box {
+ cl: &fn();
+}
+
+fn box_it(x: &r/fn()) -> closure_box/&r {
+ closure_box {cl: x}
+}
+
+fn main() {
+ let cl_box = {
+ let mut i = 3;
+ box_it(|| i += 1) //~ ERROR cannot infer an appropriate lifetime
+ };
+ cl_box.cl();
+}
2  src/test/run-pass/borrowck-root-while-cond.rs
View
@@ -1,4 +1,4 @@
-fn borrow<T>(x: &T) -> &T {x}
+fn borrow<T>(x: &r/T) -> &r/T {x}
fn main() {
let rec = @{mut f: @22};
4 src/test/run-pass/explicit-self.rs
View
@@ -19,13 +19,13 @@ fn compute_area(shape: &shape) -> float {
impl shape {
// self is in the implicit self region
fn select<T>(&self, threshold: float,
- a: &T, b: &T) -> &T {
+ a: &r/T, b: &r/T) -> &r/T {
if compute_area(self) > threshold {a} else {b}
}
}
fn select_based_on_unit_circle<T>(
- threshold: float, a: &T, b: &T) -> &T {
+ threshold: float, a: &r/T, b: &r/T) -> &r/T {
let shape = &circle({x: 0.0, y: 0.0}, 1.0);
shape.select(threshold, a, b)
2  src/test/run-pass/issue-2748-b.rs
View
@@ -1,4 +1,4 @@
-fn thing(x: &[int]) -> &[int] { x }
+fn thing(x: &r/[int]) -> &r/[int] { x }
fn main() {
let x = &[1,2,3];
let y = x;
2  src/test/run-pass/region-return-interior-of-option.rs
View
@@ -1,4 +1,4 @@
-fn get<T>(opt: &option<T>) -> &T {
+fn get<T>(opt: &r/option<T>) -> &r/T {
match *opt {
some(ref v) => v,
none => fail ~"none"
2  src/test/run-pass/regions-addr-of-interior-of-unique-box.rs
View
@@ -1,7 +1,7 @@
type point = { x: int, y: int };
type character = { pos: ~point };
-fn get_x(x: &character) -> &int {
+fn get_x(x: &r/character) -> &r/int {
// interesting case because the scope of this
// borrow of the unique pointer is in fact
// larger than the fn itself
15 src/test/run-pass/regions-copy-closure.rs
View
@@ -0,0 +1,15 @@
+struct closure_box {
+ cl: &fn();
+}
+
+fn box_it(x: &r/fn()) -> closure_box/&r {
+ closure_box {cl: x}
+}
+
+fn main() {
+ let mut i = 3;
+ let cl_box = box_it(|| i += 1);
+ assert i == 3;
+ cl_box.cl();
+ assert i == 4;
+}
2  src/test/run-pass/regions-creating-enums2.rs
View
@@ -3,7 +3,7 @@ enum ast {
add(&ast, &ast)
}
-fn mk_add_ok(x: &ast, y: &ast) -> ast {
+fn mk_add_ok(x: &r/ast, y: &r/ast) -> ast/&r {
add(x, y)
}
2  src/test/run-pass/regions-escape-into-other-fn.rs
View
@@ -1,4 +1,4 @@
-fn foo(x: &uint) -> &uint { x }
+fn foo(x: &r/uint) -> &r/uint { x }
fn bar(x: &uint) -> uint { *x }
fn main() {
2  src/test/run-pass/regions-infer-borrow-scope-view.rs
View
@@ -1,4 +1,4 @@
-fn view<T>(x: &[T]) -> &[T] {x}
+fn view<T>(x: &r/[T]) -> &r/[T] {x}
fn main() {
let v = ~[1, 2, 3];
2  src/test/run-pass/regions-infer-borrow-scope-within-loop-ok.rs
View
@@ -1,4 +1,4 @@
-fn borrow<T>(x: &T) -> &T {x}
+fn borrow<T>(x: &r/T) -> &r/T {x}
fn main() {
let x = @3;
2  src/test/run-pass/regions-infer-borrow-scope.rs
View
@@ -1,6 +1,6 @@
type point = {x: int, y: int};
-fn x_coord(p: &point) -> &int {
+fn x_coord(p: &r/point) -> &r/int {
return &p.x;
}
2  src/test/run-pass/regions-mock-trans-impls.rs
View
@@ -15,7 +15,7 @@ type ccx = {
x: int
};
-fn h(bcx : &bcx) -> &bcx {
+fn h(bcx : &r/bcx) -> &r/bcx {
return bcx.fcx.arena.alloc(|| { fcx: bcx.fcx });
}
2  src/test/run-pass/regions-nullary-variant.rs
View
@@ -2,7 +2,7 @@ enum roption {
a, b(&uint)
}
-fn mk(cond: bool, ptr: &uint) -> roption {
+fn mk(cond: bool, ptr: &r/uint) -> roption/&r {
if cond {a} else {b(ptr)}
}
2  src/test/run-pass/regions-params.rs
View
@@ -1,4 +1,4 @@
-fn region_identity(x: &uint) -> &uint { x }
+fn region_identity(x: &r/uint) -> &r/uint { x }
fn apply<T>(t: T, f: fn(T) -> T) -> T { f(t) }
16 src/test/run-pass/regions-static-closure.rs
View
@@ -0,0 +1,16 @@
+struct closure_box {
+ cl: &fn();
+}
+
+fn box_it(x: &r/fn()) -> closure_box/&r {
+ closure_box {cl: x}
+}
+
+fn call_static_closure(cl: closure_box/&static) {
+ cl.cl();
+}
+
+fn main() {
+ let cl_box = box_it(|| debug!("Hello, world!"));
+ call_static_closure(cl_box);
+}
Please sign in to comment.
Something went wrong with that request. Please try again.