Skip to content

Commit 01bf87e

Browse files
committed
Link the lifetimes of regions resulting from borrows of the
contents of other borrowed pointers to the lifetimes of the borrowed value. Fixes #3148.
1 parent b73d926 commit 01bf87e

File tree

11 files changed

+640
-94
lines changed

11 files changed

+640
-94
lines changed

src/librustc/middle/mem_categorization.rs

+2
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ enum special_kind {
111111
// a complete categorization of a value indicating where it originated
112112
// and how it is located, as well as the mutability of the memory in
113113
// which the value is stored.
114+
//
115+
// note: cmt stands for "categorized mutable type".
114116
type cmt_ = {id: ast::node_id, // id of expr/pat producing this value
115117
span: span, // span of same expr/pat
116118
cat: categorization, // categorization of expr

src/librustc/middle/resolve.rs

+35
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use core::str;
2525
use core::vec;
2626
use syntax::ast::{RegionTyParamBound, TraitTyParamBound, _mod, add, arm};
2727
use syntax::ast::{binding_mode, bitand, bitor, bitxor, blk, capture_clause};
28+
use syntax::ast::{bind_by_value, bind_infer, bind_by_ref, bind_by_move};
2829
use syntax::ast::{crate, crate_num, decl_item, def, def_arg, def_binding};
2930
use syntax::ast::{def_const, def_foreign_mod, def_fn, def_id, def_label};
3031
use syntax::ast::{def_local, def_mod, def_prim_ty, def_region, def_self};
@@ -4521,6 +4522,10 @@ impl Resolver {
45214522
struct or enum variant",
45224523
self.session.str_of(ident));
45234524

4525+
self.enforce_default_binding_mode(
4526+
pattern,
4527+
binding_mode,
4528+
"an enum variant");
45244529
self.record_def(pattern.id, def);
45254530
}
45264531
FoundStructOrEnumVariant(_) => {
@@ -4537,6 +4542,10 @@ impl Resolver {
45374542
constant",
45384543
self.session.str_of(ident));
45394544

4545+
self.enforce_default_binding_mode(
4546+
pattern,
4547+
binding_mode,
4548+
"a constant");
45404549
self.record_def(pattern.id, def);
45414550
}
45424551
FoundConst(_) => {
@@ -5371,6 +5380,32 @@ impl Resolver {
53715380
self.def_map.insert(node_id, def);
53725381
}
53735382

5383+
fn enforce_default_binding_mode(pat: @pat,
5384+
pat_binding_mode: binding_mode,
5385+
descr: &str) {
5386+
match pat_binding_mode {
5387+
bind_infer => {}
5388+
bind_by_value => {
5389+
self.session.span_err(
5390+
pat.span,
5391+
fmt!("cannot use `copy` binding mode with %s",
5392+
descr));
5393+
}
5394+
bind_by_move => {
5395+
self.session.span_err(
5396+
pat.span,
5397+
fmt!("cannot use `move` binding mode with %s",
5398+
descr));
5399+
}
5400+
bind_by_ref(*) => {
5401+
self.session.span_err(
5402+
pat.span,
5403+
fmt!("cannot use `ref` binding mode with %s",
5404+
descr));
5405+
}
5406+
}
5407+
}
5408+
53745409
//
53755410
// main function checking
53765411
//

src/librustc/middle/ty.rs

+9
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export ty_opaque_box, mk_opaque_box;
119119
export ty_float, mk_float, mk_mach_float, type_is_fp;
120120
export ty_fn, FnTy, FnTyBase, FnMeta, FnSig, mk_fn;
121121
export ty_fn_proto, ty_fn_purity, ty_fn_ret, tys_in_fn_sig;
122+
export ty_vstore;
122123
export replace_fn_return_type;
123124
export ty_int, mk_int, mk_mach_int, mk_char;
124125
export mk_i8, mk_u8, mk_i16, mk_u16, mk_i32, mk_u32, mk_i64, mk_u64;
@@ -3005,6 +3006,14 @@ fn is_fn_ty(fty: t) -> bool {
30053006
}
30063007
}
30073008

3009+
pure fn ty_vstore(ty: t) -> vstore {
3010+
match get(ty).sty {
3011+
ty_evec(_, vstore) => vstore,
3012+
ty_estr(vstore) => vstore,
3013+
ref s => fail fmt!("ty_vstore() called on invalid sty: %?", s)
3014+
}
3015+
}
3016+
30083017
fn ty_region(ty: t) -> Region {
30093018
match get(ty).sty {
30103019
ty_rptr(r, _) => r,

src/librustc/middle/typeck/check/mod.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ use middle::typeck::{isr_alist, lookup_def_ccx, method_map_entry};
105105
use middle::typeck::{method_origin, method_self, method_trait, no_params};
106106
use middle::typeck::{require_same_types};
107107
use util::common::{block_query, indenter, loop_query};
108-
use util::ppaux::{bound_region_to_str, expr_repr};
108+
use util::ppaux::{bound_region_to_str, expr_repr, pat_repr};
109109
use util::ppaux;
110110

111111
use core::either;
@@ -127,7 +127,6 @@ use syntax::ast_util;
127127
use syntax::codemap::span;
128128
use syntax::codemap;
129129
use syntax::parse::token::special_idents;
130-
use syntax::print::pprust::{expr_to_str, pat_to_str};
131130
use syntax::print::pprust;
132131
use syntax::visit;
133132
use syntax;
@@ -469,7 +468,7 @@ fn check_fn(ccx: @crate_ctxt,
469468
};
470469
assign(local.span, local.node.id, o_ty);
471470
debug!("Local variable %s is assigned to %s",
472-
pat_to_str(local.node.pat, tcx.sess.intr()),
471+
fcx.pat_to_str(local.node.pat),
473472
fcx.inh.locals.get(local.node.id).to_str());
474473
visit::visit_local(local, e, v);
475474
};
@@ -756,6 +755,10 @@ impl @fn_ctxt {
756755
expr_repr(self.tcx(), expr)
757756
}
758757

758+
fn pat_to_str(pat: @ast::pat) -> ~str {
759+
pat_repr(self.tcx(), pat)
760+
}
761+
759762
fn expr_ty(ex: @ast::expr) -> ty::t {
760763
match self.inh.node_types.find(ex.id) {
761764
Some(t) => t,
@@ -1600,7 +1603,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
16001603
let fty = ty::mk_fn(tcx, copy fn_ty);
16011604

16021605
debug!("check_expr_fn_with_unifier %s fty=%s",
1603-
expr_to_str(expr, tcx.sess.intr()),
1606+
fcx.expr_to_str(expr),
16041607
fcx.infcx().ty_to_str(fty));
16051608

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

0 commit comments

Comments
 (0)