fix up handling of &x where x is an arg or &self (for now at least).

This commit is contained in:
Niko Matsakis 2012-05-19 10:31:48 -07:00
parent 83a85d765b
commit 28d0ce9a8b
5 changed files with 91 additions and 12 deletions

View File

@ -198,7 +198,7 @@ STDLIB_INPUTS := $(wildcard $(addprefix $(S)src/libstd/, \
COMPILER_CRATE := $(S)src/rustc/rustc.rc COMPILER_CRATE := $(S)src/rustc/rustc.rc
COMPILER_INPUTS := $(filter-out $(S)src/rustc/driver/rustc.rs, \ COMPILER_INPUTS := $(filter-out $(S)src/rustc/driver/rustc.rs, \
$(wildcard $(addprefix $(S)src/rustc/, \ $(wildcard $(addprefix $(S)src/rustc/, \
rustc.rc *.rs */*.rs */*/*.rs))) rustc.rc *.rs */*.rs */*/*.rs */*/*/*.rs)))
LIBRUSTSYNTAX_CRATE := $(S)src/librustsyntax/rustsyntax.rc LIBRUSTSYNTAX_CRATE := $(S)src/librustsyntax/rustsyntax.rc
LIBRUSTSYNTAX_INPUTS := $(wildcard $(addprefix $(S)src/librustsyntax/, \ LIBRUSTSYNTAX_INPUTS := $(wildcard $(addprefix $(S)src/librustsyntax/, \

View File

@ -1,4 +1,5 @@
import middle::typeck::infer::{ty_and_region_var_methods}; import middle::typeck::infer::{ty_and_region_var_methods};
import syntax::print::pprust::{expr_to_str};
// Helper functions related to manipulating region types. // 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. * stack position and so the resulting region will be the enclosing block.
*/ */
fn region_of(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region { 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 { fn borrow(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region {
ty::encl_region(fcx.ccx.tcx, expr.id) ty::encl_region(fcx.ccx.tcx, expr.id)
} }
@ -127,25 +142,39 @@ fn region_of(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region {
} }
} }
alt expr.node { fn def(fcx: @fn_ctxt, expr: @ast::expr, d: ast::def) -> ty::region {
ast::expr_path(path) { alt d {
let defn = lookup_def(fcx, path.span, expr.id); ast::def_arg(local_id, _) |
alt defn {
ast::def_local(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); let local_scope = fcx.ccx.tcx.region_map.get(local_id);
ty::re_scope(local_scope) 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 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) }
}
} }
fn collect_bound_regions_in_tys( fn collect_bound_regions_in_tys(

View File

@ -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() {
}

View File

@ -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];
}

View File

@ -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() {
}