Skip to content

Commit

Permalink
Link the lifetimes of regions resulting from borrows of the
Browse files Browse the repository at this point in the history
contents of other borrowed pointers to the lifetimes of the
borrowed value.  Fixes #3148.

r=catamorphism
  • Loading branch information
nikomatsakis committed Jan 28, 2013
1 parent 83ca034 commit d4fd30c
Show file tree
Hide file tree
Showing 11 changed files with 640 additions and 94 deletions.
2 changes: 2 additions & 0 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ enum special_kind {
// a complete categorization of a value indicating where it originated
// and how it is located, as well as the mutability of the memory in
// which the value is stored.
//
// note: cmt stands for "categorized mutable type".
type cmt_ = {id: ast::node_id, // id of expr/pat producing this value
span: span, // span of same expr/pat
cat: categorization, // categorization of expr
Expand Down
35 changes: 35 additions & 0 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use core::str;
use core::vec;
use syntax::ast::{RegionTyParamBound, TraitTyParamBound, _mod, add, arm};
use syntax::ast::{binding_mode, bitand, bitor, bitxor, blk, capture_clause};
use syntax::ast::{bind_by_value, bind_infer, bind_by_ref, bind_by_move};
use syntax::ast::{crate, crate_num, decl_item, def, def_arg, def_binding};
use syntax::ast::{def_const, def_foreign_mod, def_fn, def_id, def_label};
use syntax::ast::{def_local, def_mod, def_prim_ty, def_region, def_self};
Expand Down Expand Up @@ -4521,6 +4522,10 @@ impl Resolver {
struct or enum variant",
self.session.str_of(ident));

self.enforce_default_binding_mode(
pattern,
binding_mode,
"an enum variant");
self.record_def(pattern.id, def);
}
FoundStructOrEnumVariant(_) => {
Expand All @@ -4537,6 +4542,10 @@ impl Resolver {
constant",
self.session.str_of(ident));

self.enforce_default_binding_mode(
pattern,
binding_mode,
"a constant");
self.record_def(pattern.id, def);
}
FoundConst(_) => {
Expand Down Expand Up @@ -5371,6 +5380,32 @@ impl Resolver {
self.def_map.insert(node_id, def);
}

fn enforce_default_binding_mode(pat: @pat,
pat_binding_mode: binding_mode,
descr: &str) {
match pat_binding_mode {
bind_infer => {}
bind_by_value => {
self.session.span_err(
pat.span,
fmt!("cannot use `copy` binding mode with %s",
descr));
}
bind_by_move => {
self.session.span_err(
pat.span,
fmt!("cannot use `move` binding mode with %s",
descr));
}
bind_by_ref(*) => {
self.session.span_err(
pat.span,
fmt!("cannot use `ref` binding mode with %s",
descr));
}
}
}

//
// main function checking
//
Expand Down
9 changes: 9 additions & 0 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export ty_opaque_box, mk_opaque_box;
export ty_float, mk_float, mk_mach_float, type_is_fp;
export ty_fn, FnTy, FnTyBase, FnMeta, FnSig, mk_fn;
export ty_fn_proto, ty_fn_purity, ty_fn_ret, tys_in_fn_sig;
export ty_vstore;
export replace_fn_return_type;
export ty_int, mk_int, mk_mach_int, mk_char;
export mk_i8, mk_u8, mk_i16, mk_u16, mk_i32, mk_u32, mk_i64, mk_u64;
Expand Down Expand Up @@ -3005,6 +3006,14 @@ fn is_fn_ty(fty: t) -> bool {
}
}

pure fn ty_vstore(ty: t) -> vstore {
match get(ty).sty {
ty_evec(_, vstore) => vstore,
ty_estr(vstore) => vstore,
ref s => fail fmt!("ty_vstore() called on invalid sty: %?", s)
}
}

fn ty_region(ty: t) -> Region {
match get(ty).sty {
ty_rptr(r, _) => r,
Expand Down
13 changes: 8 additions & 5 deletions src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ use middle::typeck::{isr_alist, lookup_def_ccx, method_map_entry};
use middle::typeck::{method_origin, method_self, method_trait, no_params};
use middle::typeck::{require_same_types};
use util::common::{block_query, indenter, loop_query};
use util::ppaux::{bound_region_to_str, expr_repr};
use util::ppaux::{bound_region_to_str, expr_repr, pat_repr};
use util::ppaux;

use core::either;
Expand All @@ -127,7 +127,6 @@ use syntax::ast_util;
use syntax::codemap::span;
use syntax::codemap;
use syntax::parse::token::special_idents;
use syntax::print::pprust::{expr_to_str, pat_to_str};
use syntax::print::pprust;
use syntax::visit;
use syntax;
Expand Down Expand Up @@ -469,7 +468,7 @@ fn check_fn(ccx: @crate_ctxt,
};
assign(local.span, local.node.id, o_ty);
debug!("Local variable %s is assigned to %s",
pat_to_str(local.node.pat, tcx.sess.intr()),
fcx.pat_to_str(local.node.pat),
fcx.inh.locals.get(local.node.id).to_str());
visit::visit_local(local, e, v);
};
Expand Down Expand Up @@ -756,6 +755,10 @@ impl @fn_ctxt {
expr_repr(self.tcx(), expr)
}

fn pat_to_str(pat: @ast::pat) -> ~str {
pat_repr(self.tcx(), pat)
}

fn expr_ty(ex: @ast::expr) -> ty::t {
match self.inh.node_types.find(ex.id) {
Some(t) => t,
Expand Down Expand Up @@ -1600,7 +1603,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
let fty = ty::mk_fn(tcx, copy fn_ty);

debug!("check_expr_fn_with_unifier %s fty=%s",
expr_to_str(expr, tcx.sess.intr()),
fcx.expr_to_str(expr),
fcx.infcx().ty_to_str(fty));

fcx.write_ty(expr.id, fty);
Expand Down Expand Up @@ -2713,7 +2716,7 @@ fn check_enum_variants(ccx: @crate_ctxt,
do v.node.disr_expr.iter |e_ref| {
let e = *e_ref;
debug!("disr expr, checking %s",
expr_to_str(e, ccx.tcx.sess.intr()));
pprust::expr_to_str(e, ccx.tcx.sess.intr()));
let declty = ty::mk_int(ccx.tcx);
let fcx = blank_fn_ctxt(ccx, rty, e.id);
check_const_with_ty(fcx, e.span, e, declty);
Expand Down
Loading

0 comments on commit d4fd30c

Please sign in to comment.