Skip to content

Commit 4f8942d

Browse files
committed
---
yaml --- r: 160657 b: refs/heads/master c: d6c8f3b h: refs/heads/master i: 160655: 15f728a v: v3
1 parent e142670 commit 4f8942d

File tree

12 files changed

+106
-49
lines changed

12 files changed

+106
-49
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: e31fc9dd4f21138d322cfc8adc270a58bcc4146f
2+
refs/heads/master: d6c8f3b7268040071d61acbeab3b5253b07b7caa
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: c9f6d696420107f82304b992cf623b806995fe18
55
refs/heads/try: 225de0d60f8ca8dcc62ab2fd8818ebbda4b58cfe

trunk/src/librustc/middle/borrowck/check_loans.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ fn owned_ptr_base_path<'a>(loan_path: &'a LoanPath) -> &'a LoanPath {
5252
None => Some(&**lp_base)
5353
}
5454
}
55+
LpDowncast(ref lp_base, _) |
5556
LpExtend(ref lp_base, _, _) => owned_ptr_base_path_helper(&**lp_base)
5657
}
5758
}
@@ -75,6 +76,7 @@ fn owned_ptr_base_path_rc(loan_path: &Rc<LoanPath>) -> Rc<LoanPath> {
7576
None => Some(lp_base.clone())
7677
}
7778
}
79+
LpDowncast(ref lp_base, _) |
7880
LpExtend(ref lp_base, _, _) => owned_ptr_base_path_helper(lp_base)
7981
}
8082
}
@@ -298,6 +300,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
298300
LpVar(_) | LpUpvar(_) => {
299301
break;
300302
}
303+
LpDowncast(ref lp_base, _) |
301304
LpExtend(ref lp_base, _, _) => {
302305
loan_path = &**lp_base;
303306
}
@@ -726,6 +729,11 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
726729
LpVar(_) | LpUpvar(_) => {
727730
// assigning to `x` does not require that `x` is initialized
728731
}
732+
LpDowncast(ref lp_base, _) => {
733+
// assigning to `(P->Variant).f` is ok if assigning to `P` is ok
734+
self.check_if_assigned_path_is_moved(id, span,
735+
use_kind, lp_base);
736+
}
729737
LpExtend(ref lp_base, _, LpInterior(_)) => {
730738
// assigning to `P.f` is ok if assigning to `P` is ok
731739
self.check_if_assigned_path_is_moved(id, span,
@@ -864,7 +872,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
864872
cmt = b;
865873
}
866874

867-
mc::cat_downcast(b) |
875+
mc::cat_downcast(b, _) |
868876
mc::cat_interior(b, _) => {
869877
assert_eq!(cmt.mutbl, mc::McInherited);
870878
cmt = b;

trunk/src/librustc/middle/borrowck/gather_loans/gather_moves.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
144144
None
145145
}
146146

147-
mc::cat_downcast(ref b) |
147+
mc::cat_downcast(ref b, _) |
148148
mc::cat_interior(ref b, _) => {
149149
match b.ty.sty {
150150
ty::ty_struct(did, _) | ty::ty_enum(did, _) => {

trunk/src/librustc/middle/borrowck/gather_loans/lifetime.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
8585
Ok(())
8686
}
8787

88-
mc::cat_downcast(ref base) |
88+
mc::cat_downcast(ref base, _) |
8989
mc::cat_deref(ref base, _, mc::OwnedPtr) | // L-Deref-Send
9090
mc::cat_interior(ref base, _) => { // L-Field
9191
self.check(base, discr_scope)
@@ -130,7 +130,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
130130
mc::cat_deref(_, _, mc::Implicit(_, r)) => {
131131
r
132132
}
133-
mc::cat_downcast(ref cmt) |
133+
mc::cat_downcast(ref cmt, _) |
134134
mc::cat_deref(ref cmt, _, mc::OwnedPtr) |
135135
mc::cat_interior(ref cmt, _) => {
136136
self.scope(cmt)

trunk/src/librustc/middle/borrowck/gather_loans/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
400400
LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => {
401401
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
402402
}
403+
LpDowncast(ref base, _) |
403404
LpExtend(ref base, mc::McInherited, _) |
404405
LpExtend(ref base, mc::McDeclared, _) => {
405406
self.mark_loan_path_as_mutated(&**base);

trunk/src/librustc/middle/borrowck/gather_loans/move_error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
124124
bccx.cmt_to_string(&*move_from)).as_slice());
125125
}
126126

127-
mc::cat_downcast(ref b) |
127+
mc::cat_downcast(ref b, _) |
128128
mc::cat_interior(ref b, _) => {
129129
match b.ty.sty {
130130
ty::ty_struct(did, _)

trunk/src/librustc/middle/borrowck/gather_loans/restrictions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
8282
SafeIf(lp.clone(), vec![lp])
8383
}
8484

85-
mc::cat_downcast(cmt_base) => {
85+
mc::cat_downcast(cmt_base, _) => {
8686
// When we borrow the interior of an enum, we have to
8787
// ensure the enum itself is not mutated, because that
8888
// could cause the type of the memory to change.

trunk/src/librustc/middle/borrowck/mod.rs

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,11 +284,27 @@ impl Loan {
284284

285285
#[deriving(PartialEq, Eq, Hash, Show)]
286286
pub enum LoanPath {
287-
LpVar(ast::NodeId), // `x` in doc.rs
288-
LpUpvar(ty::UpvarId), // `x` captured by-value into closure
287+
LpVar(ast::NodeId), // `x` in doc.rs
288+
LpUpvar(ty::UpvarId), // `x` captured by-value into closure
289+
LpDowncast(Rc<LoanPath>, ast::DefId), // `x` downcast to particular enum variant
289290
LpExtend(Rc<LoanPath>, mc::MutabilityCategory, LoanPathElem)
290291
}
291292

293+
impl LoanPath {
294+
fn kill_id(&self, tcx: &ty::ctxt) -> ast::NodeId {
295+
//! Returns the lifetime of the local variable that forms the
296+
//! base of this path. (See move_data::add_gen_kills.)
297+
match *self {
298+
LpVar(id) =>
299+
tcx.region_maps.var_scope(id),
300+
LpUpvar(ty::UpvarId { var_id: _, closure_expr_id }) =>
301+
closure_to_block(closure_expr_id, tcx),
302+
LpDowncast(ref base_lp, _) | LpExtend(ref base_lp, _, _) =>
303+
base_lp.kill_id(tcx),
304+
}
305+
}
306+
}
307+
292308
#[deriving(PartialEq, Eq, Hash, Show)]
293309
pub enum LoanPathElem {
294310
LpDeref(mc::PointerKind), // `*LV` in doc.rs
@@ -319,6 +335,7 @@ impl LoanPath {
319335
let block_id = closure_to_block(upvar_id.closure_expr_id, tcx);
320336
region::CodeExtent::from_node_id(block_id)
321337
}
338+
LpDowncast(ref base, _) |
322339
LpExtend(ref base, _, _) => base.kill_scope(tcx),
323340
}
324341
}
@@ -402,9 +419,12 @@ pub fn opt_loan_path(cmt: &mc::cmt) -> Option<Rc<LoanPath>> {
402419
})
403420
}
404421

405-
mc::cat_downcast(ref cmt_base) => {
422+
mc::cat_downcast(ref cmt_base, variant_def_id) =>
406423
opt_loan_path(cmt_base)
407-
}
424+
.map(|lp| {
425+
Rc::new(LpDowncast(lp, variant_def_id))
426+
}),
427+
408428
}
409429
}
410430

@@ -862,6 +882,15 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
862882
out.push_str(ty::local_var_name_str(self.tcx, id).get());
863883
}
864884

885+
LpDowncast(ref lp_base, variant_def_id) => {
886+
out.push('(');
887+
self.append_loan_path_to_string(&**lp_base, out);
888+
out.push_str("->");
889+
out.push_str(ty::item_path_str(self.tcx, variant_def_id).as_slice());
890+
out.push(')');
891+
}
892+
893+
865894
LpExtend(ref lp_base, _, LpInterior(mc::InteriorField(fname))) => {
866895
self.append_autoderefd_loan_path_to_string(&**lp_base, out);
867896
match fname {
@@ -899,6 +928,14 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
899928
self.append_autoderefd_loan_path_to_string(&**lp_base, out)
900929
}
901930

931+
LpDowncast(ref lp_base, variant_def_id) => {
932+
out.push('(');
933+
self.append_autoderefd_loan_path_to_string(&**lp_base, out);
934+
out.push(':');
935+
out.push_str(ty::item_path_str(self.tcx, variant_def_id).as_slice());
936+
out.push(')');
937+
}
938+
902939
LpVar(..) | LpUpvar(..) | LpExtend(_, _, LpInterior(..)) => {
903940
self.append_loan_path_to_string(loan_path, out)
904941
}
@@ -966,6 +1003,15 @@ impl<'tcx> Repr<'tcx> for LoanPath {
9661003
format!("$({} captured by id={})", s, closure_expr_id)
9671004
}
9681005

1006+
&LpDowncast(ref lp, variant_def_id) => {
1007+
let variant_str = if variant_def_id.krate == ast::LOCAL_CRATE {
1008+
ty::item_path_str(tcx, variant_def_id)
1009+
} else {
1010+
variant_def_id.repr(tcx)
1011+
};
1012+
format!("({}->{})", lp.repr(tcx), variant_str)
1013+
}
1014+
9691015
&LpExtend(ref lp, _, LpDeref(_)) => {
9701016
format!("{}.*", lp.repr(tcx))
9711017
}

trunk/src/librustc/middle/borrowck/move_data.rs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ fn loan_path_is_precise(loan_path: &LoanPath) -> bool {
175175
// location, as there is no accurate tracking of the indices.
176176
false
177177
}
178+
LpDowncast(ref lp_base, _) |
178179
LpExtend(ref lp_base, _, _) => {
179180
loan_path_is_precise(&**lp_base)
180181
}
@@ -266,6 +267,7 @@ impl MoveData {
266267
index
267268
}
268269

270+
LpDowncast(ref base, _) |
269271
LpExtend(ref base, _, _) => {
270272
let parent_index = self.move_path(tcx, base.clone());
271273

@@ -324,6 +326,7 @@ impl MoveData {
324326
None => {
325327
match **lp {
326328
LpVar(..) | LpUpvar(..) => { }
329+
LpDowncast(ref b, _) |
327330
LpExtend(ref b, _, _) => {
328331
self.add_existing_base_paths(b, result);
329332
}
@@ -434,32 +437,24 @@ impl MoveData {
434437
// of scope:
435438
for path in self.paths.borrow().iter() {
436439
match *path.loan_path {
437-
LpVar(id) => {
438-
let kill_scope = tcx.region_maps.var_scope(id);
439-
let path = (*self.path_map.borrow())[path.loan_path];
440+
LpVar(..) | LpUpvar(..) | LpDowncast(..) => {
441+
let kill_scope = path.loan_path.kill_scope(tcx);
442+
let path = *self.path_map.borrow().get(&path.loan_path);
440443
self.kill_moves(path, kill_scope.node_id(), dfcx_moves);
441444
}
442-
LpUpvar(ty::UpvarId { var_id: _, closure_expr_id }) => {
443-
let kill_id = closure_to_block(closure_expr_id, tcx);
444-
let path = (*self.path_map.borrow())[path.loan_path];
445-
self.kill_moves(path, kill_id, dfcx_moves);
446-
}
447445
LpExtend(..) => {}
448446
}
449447
}
450448

451449
// Kill all assignments when the variable goes out of scope:
452450
for (assignment_index, assignment) in
453451
self.var_assignments.borrow().iter().enumerate() {
454-
match *self.path_loan_path(assignment.path) {
455-
LpVar(id) => {
456-
let kill_scope = tcx.region_maps.var_scope(id);
452+
let lp = self.path_loan_path(assignment.path);
453+
match *lp {
454+
LpVar(..) | LpUpvar(..) | LpDowncast(..) => {
455+
let kill_scope = lp.kill_scope(tcx);
457456
dfcx_assign.add_kill(kill_scope.node_id(), assignment_index);
458457
}
459-
LpUpvar(ty::UpvarId { var_id: _, closure_expr_id }) => {
460-
let kill_id = closure_to_block(closure_expr_id, tcx);
461-
dfcx_assign.add_kill(kill_id, assignment_index);
462-
}
463458
LpExtend(..) => {
464459
tcx.sess.bug("var assignment for non var path");
465460
}

trunk/src/librustc/middle/check_static.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ impl<'tcx> euv::Delegate<'tcx> for GlobalChecker {
270270
break
271271
}
272272
mc::cat_deref(ref cmt, _, _) |
273-
mc::cat_downcast(ref cmt) |
273+
mc::cat_downcast(ref cmt, _) |
274274
mc::cat_interior(ref cmt, _) => cur = cmt,
275275

276276
mc::cat_rvalue(..) |

trunk/src/librustc/middle/mem_categorization.rs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ pub enum categorization<'tcx> {
9898
cat_local(ast::NodeId), // local variable
9999
cat_deref(cmt<'tcx>, uint, PointerKind), // deref of a ptr
100100
cat_interior(cmt<'tcx>, InteriorKind), // something interior: field, tuple, etc
101-
cat_downcast(cmt<'tcx>), // selects a particular enum variant (*1)
101+
cat_downcast(cmt, ast::DefId), // selects a particular enum variant (*1)
102102

103103
// (*1) downcast is only required if the enum has more than one variant
104104
}
@@ -1102,13 +1102,14 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
11021102
pub fn cat_downcast<N:ast_node>(&self,
11031103
node: &N,
11041104
base_cmt: cmt<'tcx>,
1105-
downcast_ty: Ty<'tcx>)
1105+
downcast_ty: Ty<'tcx>,
1106+
variant_did: ast::DefId)
11061107
-> cmt<'tcx> {
11071108
Rc::new(cmt_ {
11081109
id: node.id(),
11091110
span: node.span(),
11101111
mutbl: base_cmt.mutbl.inherit(),
1111-
cat: cat_downcast(base_cmt),
1112+
cat: cat_downcast(base_cmt, variant_did),
11121113
ty: downcast_ty,
11131114
note: NoteNone
11141115
})
@@ -1172,6 +1173,21 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
11721173

11731174
op(self, cmt.clone(), pat);
11741175

1176+
let def_map = self.tcx().def_map.borrow();
1177+
let opt_def = def_map.get(&pat.id);
1178+
1179+
// Note: This goes up here (rather than within the PatEnum arm
1180+
// alone) because struct patterns can refer to struct types or
1181+
// to struct variants within enums.
1182+
let cmt = match opt_def {
1183+
Some(&def::DefVariant(enum_did, variant_did, _))
1184+
// univariant enums do not need downcasts
1185+
if !ty::enum_is_univariant(self.tcx(), enum_did) => {
1186+
self.cat_downcast(pat, cmt.clone(), cmt.ty, variant_did)
1187+
}
1188+
_ => cmt
1189+
};
1190+
11751191
match pat.node {
11761192
ast::PatWild(_) => {
11771193
// _
@@ -1181,24 +1197,15 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
11811197
// variant(..)
11821198
}
11831199
ast::PatEnum(_, Some(ref subpats)) => {
1184-
match self.tcx().def_map.borrow().get(&pat.id) {
1185-
Some(&def::DefVariant(enum_did, _, _)) => {
1200+
match opt_def {
1201+
Some(&def::DefVariant(..)) => {
11861202
// variant(x, y, z)
1187-
1188-
let downcast_cmt = {
1189-
if ty::enum_is_univariant(self.tcx(), enum_did) {
1190-
cmt // univariant, no downcast needed
1191-
} else {
1192-
self.cat_downcast(pat, cmt.clone(), cmt.ty)
1193-
}
1194-
};
1195-
11961203
for (i, subpat) in subpats.iter().enumerate() {
11971204
let subpat_ty = if_ok!(self.pat_ty(&**subpat)); // see (*2)
11981205

11991206
let subcmt =
12001207
self.cat_imm_interior(
1201-
pat, downcast_cmt.clone(), subpat_ty,
1208+
pat, cmt.clone(), subpat_ty,
12021209
InteriorField(PositionalField(i)));
12031210

12041211
if_ok!(self.cat_pattern(subcmt, &**subpat, |x,y,z| op(x,y,z)));
@@ -1356,7 +1363,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
13561363
cat_upvar(ref var) => {
13571364
upvar_to_string(var, true)
13581365
}
1359-
cat_downcast(ref cmt) => {
1366+
cat_downcast(ref cmt, _) => {
13601367
self.cmt_to_string(&**cmt)
13611368
}
13621369
}
@@ -1392,7 +1399,7 @@ impl<'tcx> cmt_<'tcx> {
13921399
cat_upvar(..) => {
13931400
Rc::new((*self).clone())
13941401
}
1395-
cat_downcast(ref b) |
1402+
cat_downcast(ref b, _) |
13961403
cat_interior(ref b, _) |
13971404
cat_deref(ref b, _, OwnedPtr) => {
13981405
b.guarantor()
@@ -1416,7 +1423,7 @@ impl<'tcx> cmt_<'tcx> {
14161423
cat_deref(ref b, _, Implicit(ty::MutBorrow, _)) |
14171424
cat_deref(ref b, _, BorrowedPtr(ty::UniqueImmBorrow, _)) |
14181425
cat_deref(ref b, _, Implicit(ty::UniqueImmBorrow, _)) |
1419-
cat_downcast(ref b) |
1426+
cat_downcast(ref b, _) |
14201427
cat_deref(ref b, _, OwnedPtr) |
14211428
cat_interior(ref b, _) => {
14221429
// Aliasability depends on base cmt
@@ -1500,7 +1507,7 @@ impl<'tcx> Repr<'tcx> for categorization<'tcx> {
15001507
cat_interior(ref cmt, interior) => {
15011508
format!("{}.{}", cmt.cat.repr(tcx), interior.repr(tcx))
15021509
}
1503-
cat_downcast(ref cmt) => {
1510+
cat_downcast(ref cmt, _) => {
15041511
format!("{}->(enum)", cmt.cat.repr(tcx))
15051512
}
15061513
}

0 commit comments

Comments
 (0)