From 28d0ce9a8ba08748877163768f4b846dabc1d4a7 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 19 May 2012 10:31:48 -0700 Subject: [PATCH] fix up handling of &x where x is an arg or &self (for now at least). --- Makefile.in | 2 +- src/rustc/middle/typeck/check/regionmanip.rs | 51 +++++++++++++++---- src/test/compile-fail/regions-addr-of-arg.rs | 10 ++++ src/test/compile-fail/regions-addr-of-self.rs | 23 +++++++++ .../regions-addr-of-upvar-self.rs | 17 +++++++ 5 files changed, 91 insertions(+), 12 deletions(-) create mode 100644 src/test/compile-fail/regions-addr-of-arg.rs create mode 100644 src/test/compile-fail/regions-addr-of-self.rs create mode 100644 src/test/compile-fail/regions-addr-of-upvar-self.rs diff --git a/Makefile.in b/Makefile.in index 06288dede01..96f94823283 100644 --- a/Makefile.in +++ b/Makefile.in @@ -198,7 +198,7 @@ STDLIB_INPUTS := $(wildcard $(addprefix $(S)src/libstd/, \ COMPILER_CRATE := $(S)src/rustc/rustc.rc COMPILER_INPUTS := $(filter-out $(S)src/rustc/driver/rustc.rs, \ $(wildcard $(addprefix $(S)src/rustc/, \ - rustc.rc *.rs */*.rs */*/*.rs))) + rustc.rc *.rs */*.rs */*/*.rs */*/*/*.rs))) LIBRUSTSYNTAX_CRATE := $(S)src/librustsyntax/rustsyntax.rc LIBRUSTSYNTAX_INPUTS := $(wildcard $(addprefix $(S)src/librustsyntax/, \ diff --git a/src/rustc/middle/typeck/check/regionmanip.rs b/src/rustc/middle/typeck/check/regionmanip.rs index 8f8472ec5b4..dfa3744a8fe 100644 --- a/src/rustc/middle/typeck/check/regionmanip.rs +++ b/src/rustc/middle/typeck/check/regionmanip.rs @@ -1,4 +1,5 @@ import middle::typeck::infer::{ty_and_region_var_methods}; +import syntax::print::pprust::{expr_to_str}; // Helper functions related to manipulating region types. @@ -113,6 +114,20 @@ fn replace_bound_regions( * stack position and so the resulting region will be the enclosing block. */ fn region_of(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region { + #debug["region_of(expr=%s)", expr_to_str(expr)]; + ret alt expr.node { + ast::expr_path(path) { + def(fcx, expr, lookup_def(fcx, path.span, expr.id))} + ast::expr_field(base, _, _) { + deref(fcx, base)} + ast::expr_index(base, _) { + deref(fcx, base)} + ast::expr_unary(ast::deref, base) { + deref(fcx, base)} + _ { + borrow(fcx, expr)} + }; + fn borrow(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region { ty::encl_region(fcx.ccx.tcx, expr.id) } @@ -127,24 +142,38 @@ fn region_of(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region { } } - alt expr.node { - ast::expr_path(path) { - let defn = lookup_def(fcx, path.span, expr.id); - alt defn { + fn def(fcx: @fn_ctxt, expr: @ast::expr, d: ast::def) -> ty::region { + alt d { + ast::def_arg(local_id, _) | ast::def_local(local_id, _) | - ast::def_upvar(local_id, _, _) { + ast::def_binding(local_id) { + #debug["region_of.def/arg/local/binding(id=%d)", local_id]; let local_scope = fcx.ccx.tcx.region_map.get(local_id); ty::re_scope(local_scope) } - _ { + ast::def_upvar(_, inner, _) { + #debug["region_of.def/upvar"]; + def(fcx, expr, *inner) + } + ast::def_self(*) { + alt fcx.in_scope_regions.find(ty::br_self) { + some(r) {r} + none { + // eventually, this should never happen... self should + // always be an &self.T rptr + borrow(fcx, expr) + } + } + } + ast::def_fn(_, _) | ast::def_mod(_) | + ast::def_native_mod(_) | ast::def_const(_) | + ast::def_use(_) | ast::def_variant(_, _) | + ast::def_ty(_) | ast::def_prim_ty(_) | + ast::def_ty_param(_, _) | ast::def_class(_) | + ast::def_region(_) { ty::re_static } } - } - ast::expr_field(base, _, _) { deref(fcx, base) } - ast::expr_index(base, _) { deref(fcx, base) } - ast::expr_unary(ast::deref, base) { deref(fcx, base) } - _ { borrow(fcx, expr) } } } diff --git a/src/test/compile-fail/regions-addr-of-arg.rs b/src/test/compile-fail/regions-addr-of-arg.rs new file mode 100644 index 00000000000..4c14937de68 --- /dev/null +++ b/src/test/compile-fail/regions-addr-of-arg.rs @@ -0,0 +1,10 @@ +fn foo(a: int) { + let _p: &static.int = &a; //! ERROR mismatched types +} + +fn bar(a: int) { + let _q: &blk.int = &a; +} + +fn main() { +} \ No newline at end of file diff --git a/src/test/compile-fail/regions-addr-of-self.rs b/src/test/compile-fail/regions-addr-of-self.rs new file mode 100644 index 00000000000..b9943bc18e0 --- /dev/null +++ b/src/test/compile-fail/regions-addr-of-self.rs @@ -0,0 +1,23 @@ +class dog { + let mut cats_chased: uint; + + new() { + self.cats_chased = 0u; + } + + fn chase_cat() { + let p: &static.mut uint = &mut self.cats_chased; //! ERROR mismatched types + *p += 1u; + } + + fn chase_cat_2() { + let p: &blk.mut uint = &mut self.cats_chased; + *p += 1u; + } +} + +fn main() { + let d = dog(); + d.chase_cat(); + #debug["cats_chased: %u", d.cats_chased]; +} \ No newline at end of file diff --git a/src/test/compile-fail/regions-addr-of-upvar-self.rs b/src/test/compile-fail/regions-addr-of-upvar-self.rs new file mode 100644 index 00000000000..b0cd97d24d3 --- /dev/null +++ b/src/test/compile-fail/regions-addr-of-upvar-self.rs @@ -0,0 +1,17 @@ +class dog { + let mut food: uint; + + new() { + self.food = 0u; + } + + fn chase_cat() { + uint::range(0u, 10u) { |i| + let p: &static.mut uint = &mut self.food; //! ERROR mismatched types + *p = 3u; + } + } +} + +fn main() { +} \ No newline at end of file