Skip to content

Commit 394269d

Browse files
committed
auto merge of #19033 : pnkfelix/rust/fsk-introduce-scopedata-via-refactor, r=nikomatsakis
(Previously, scopes were solely identified with NodeId's; this refactoring prepares for a future where that does not hold.) Ground work for a proper fix to #8861.
2 parents 1d81776 + 5ff9087 commit 394269d

25 files changed

+420
-269
lines changed

src/librustc/metadata/tydecode.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
pub use self::DefIdSource::*;
2020

21+
use middle::region;
2122
use middle::subst;
2223
use middle::subst::VecPerParamSpace;
2324
use middle::ty::{mod, Ty};
@@ -315,17 +316,17 @@ fn parse_region(st: &mut PState, conv: conv_did) -> ty::Region {
315316
}
316317
'f' => {
317318
assert_eq!(next(st), '[');
318-
let id = parse_uint(st) as ast::NodeId;
319+
let scope = parse_scope(st);
319320
assert_eq!(next(st), '|');
320321
let br = parse_bound_region(st, |x,y| conv(x,y));
321322
assert_eq!(next(st), ']');
322-
ty::ReFree(ty::FreeRegion {scope_id: id,
323+
ty::ReFree(ty::FreeRegion { scope: scope,
323324
bound_region: br})
324325
}
325326
's' => {
326-
let id = parse_uint(st) as ast::NodeId;
327+
let scope = parse_scope(st);
327328
assert_eq!(next(st), '|');
328-
ty::ReScope(id)
329+
ty::ReScope(scope)
329330
}
330331
't' => {
331332
ty::ReStatic
@@ -337,6 +338,16 @@ fn parse_region(st: &mut PState, conv: conv_did) -> ty::Region {
337338
}
338339
}
339340

341+
fn parse_scope(st: &mut PState) -> region::CodeExtent {
342+
match next(st) {
343+
'M' => {
344+
let node_id = parse_uint(st) as ast::NodeId;
345+
region::CodeExtent::Misc(node_id)
346+
}
347+
_ => panic!("parse_scope: bad input")
348+
}
349+
}
350+
340351
fn parse_opt<'a, 'tcx, T>(st: &mut PState<'a, 'tcx>, f: |&mut PState<'a, 'tcx>| -> T)
341352
-> Option<T> {
342353
match next(st) {

src/librustc/metadata/tyencode.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
use std::cell::RefCell;
1717

18+
use middle::region;
1819
use middle::subst;
1920
use middle::subst::VecPerParamSpace;
2021
use middle::ty::ParamTy;
@@ -143,12 +144,16 @@ pub fn enc_region(w: &mut SeekableMemWriter, cx: &ctxt, r: ty::Region) {
143144
token::get_name(name));
144145
}
145146
ty::ReFree(ref fr) => {
146-
mywrite!(w, "f[{}|", fr.scope_id);
147+
mywrite!(w, "f[");
148+
enc_scope(w, cx, fr.scope);
149+
mywrite!(w, "|");
147150
enc_bound_region(w, cx, fr.bound_region);
148151
mywrite!(w, "]");
149152
}
150-
ty::ReScope(nid) => {
151-
mywrite!(w, "s{}|", nid);
153+
ty::ReScope(scope) => {
154+
mywrite!(w, "s");
155+
enc_scope(w, cx, scope);
156+
mywrite!(w, "|");
152157
}
153158
ty::ReStatic => {
154159
mywrite!(w, "t");
@@ -163,6 +168,12 @@ pub fn enc_region(w: &mut SeekableMemWriter, cx: &ctxt, r: ty::Region) {
163168
}
164169
}
165170

171+
fn enc_scope(w: &mut SeekableMemWriter, _cx: &ctxt, scope: region::CodeExtent) {
172+
match scope {
173+
region::CodeExtent::Misc(node_id) => mywrite!(w, "M{}", node_id)
174+
}
175+
}
176+
166177
fn enc_bound_region(w: &mut SeekableMemWriter, cx: &ctxt, br: ty::BoundRegion) {
167178
match br {
168179
ty::BrAnon(idx) => {

src/librustc/middle/astencode.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -489,20 +489,32 @@ impl tr for ty::Region {
489489
ty::ReEarlyBound(id, space, index, ident) => {
490490
ty::ReEarlyBound(dcx.tr_id(id), space, index, ident)
491491
}
492-
ty::ReScope(id) => {
493-
ty::ReScope(dcx.tr_id(id))
492+
ty::ReScope(scope) => {
493+
ty::ReScope(scope.tr(dcx))
494494
}
495495
ty::ReEmpty | ty::ReStatic | ty::ReInfer(..) => {
496496
*self
497497
}
498498
ty::ReFree(ref fr) => {
499-
ty::ReFree(ty::FreeRegion {scope_id: dcx.tr_id(fr.scope_id),
500-
bound_region: fr.bound_region.tr(dcx)})
499+
ty::ReFree(fr.tr(dcx))
501500
}
502501
}
503502
}
504503
}
505504

505+
impl tr for ty::FreeRegion {
506+
fn tr(&self, dcx: &DecodeContext) -> ty::FreeRegion {
507+
ty::FreeRegion { scope: self.scope.tr(dcx),
508+
bound_region: self.bound_region.tr(dcx) }
509+
}
510+
}
511+
512+
impl tr for region::CodeExtent {
513+
fn tr(&self, dcx: &DecodeContext) -> region::CodeExtent {
514+
self.map_id(|id| dcx.tr_id(id))
515+
}
516+
}
517+
506518
impl tr for ty::BoundRegion {
507519
fn tr(&self, dcx: &DecodeContext) -> ty::BoundRegion {
508520
match *self {

src/librustc/middle/borrowck/check_loans.rs

+28-22
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use self::UseError::*;
2121
use middle::borrowck::*;
2222
use middle::expr_use_visitor as euv;
2323
use middle::mem_categorization as mc;
24+
use middle::region;
2425
use middle::ty;
2526
use syntax::ast;
2627
use syntax::codemap::Span;
@@ -134,7 +135,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
134135
None => { }
135136
}
136137

137-
self.check_for_conflicting_loans(borrow_id);
138+
self.check_for_conflicting_loans(region::CodeExtent::from_node_id(borrow_id));
138139
}
139140

140141
fn mutate(&mut self,
@@ -215,30 +216,30 @@ fn compatible_borrow_kinds(borrow_kind1: ty::BorrowKind,
215216
impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
216217
pub fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.bccx.tcx }
217218

218-
pub fn each_issued_loan(&self, scope_id: ast::NodeId, op: |&Loan| -> bool)
219+
pub fn each_issued_loan(&self, scope: region::CodeExtent, op: |&Loan| -> bool)
219220
-> bool {
220221
//! Iterates over each loan that has been issued
221-
//! on entrance to `scope_id`, regardless of whether it is
222+
//! on entrance to `scope`, regardless of whether it is
222223
//! actually *in scope* at that point. Sometimes loans
223224
//! are issued for future scopes and thus they may have been
224225
//! *issued* but not yet be in effect.
225226
226-
self.dfcx_loans.each_bit_on_entry(scope_id, |loan_index| {
227+
self.dfcx_loans.each_bit_on_entry(scope.node_id(), |loan_index| {
227228
let loan = &self.all_loans[loan_index];
228229
op(loan)
229230
})
230231
}
231232

232233
pub fn each_in_scope_loan(&self,
233-
scope_id: ast::NodeId,
234+
scope: region::CodeExtent,
234235
op: |&Loan| -> bool)
235236
-> bool {
236237
//! Like `each_issued_loan()`, but only considers loans that are
237238
//! currently in scope.
238239
239240
let tcx = self.tcx();
240-
self.each_issued_loan(scope_id, |loan| {
241-
if tcx.region_maps.is_subscope_of(scope_id, loan.kill_scope) {
241+
self.each_issued_loan(scope, |loan| {
242+
if tcx.region_maps.is_subscope_of(scope, loan.kill_scope) {
242243
op(loan)
243244
} else {
244245
true
@@ -247,7 +248,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
247248
}
248249

249250
fn each_in_scope_loan_affecting_path(&self,
250-
scope_id: ast::NodeId,
251+
scope: region::CodeExtent,
251252
loan_path: &LoanPath,
252253
op: |&Loan| -> bool)
253254
-> bool {
@@ -262,7 +263,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
262263
// let y = a; // Conflicts with restriction
263264

264265
let loan_path = owned_ptr_base_path(loan_path);
265-
let cont = self.each_in_scope_loan(scope_id, |loan| {
266+
let cont = self.each_in_scope_loan(scope, |loan| {
266267
let mut ret = true;
267268
for restr_path in loan.restricted_paths.iter() {
268269
if **restr_path == *loan_path {
@@ -302,7 +303,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
302303
}
303304
}
304305

305-
let cont = self.each_in_scope_loan(scope_id, |loan| {
306+
let cont = self.each_in_scope_loan(scope, |loan| {
306307
if *loan.loan_path == *loan_path {
307308
op(loan)
308309
} else {
@@ -318,30 +319,33 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
318319
return true;
319320
}
320321

321-
pub fn loans_generated_by(&self, scope_id: ast::NodeId) -> Vec<uint> {
322+
pub fn loans_generated_by(&self, scope: region::CodeExtent) -> Vec<uint> {
322323
//! Returns a vector of the loans that are generated as
323-
//! we encounter `scope_id`.
324+
//! we enter `scope`.
324325
325326
let mut result = Vec::new();
326-
self.dfcx_loans.each_gen_bit(scope_id, |loan_index| {
327+
self.dfcx_loans.each_gen_bit(scope.node_id(), |loan_index| {
327328
result.push(loan_index);
328329
true
329330
});
330331
return result;
331332
}
332333

333-
pub fn check_for_conflicting_loans(&self, scope_id: ast::NodeId) {
334+
pub fn check_for_conflicting_loans(&self, scope: region::CodeExtent) {
334335
//! Checks to see whether any of the loans that are issued
335-
//! by `scope_id` conflict with loans that have already been
336-
//! issued when we enter `scope_id` (for example, we do not
336+
//! on entrance to `scope` conflict with loans that have already been
337+
//! issued when we enter `scope` (for example, we do not
337338
//! permit two `&mut` borrows of the same variable).
339+
//!
340+
//! (Note that some loans can be *issued* without necessarily
341+
//! taking effect yet.)
338342
339-
debug!("check_for_conflicting_loans(scope_id={})", scope_id);
343+
debug!("check_for_conflicting_loans(scope={})", scope);
340344

341-
let new_loan_indices = self.loans_generated_by(scope_id);
345+
let new_loan_indices = self.loans_generated_by(scope);
342346
debug!("new_loan_indices = {}", new_loan_indices);
343347

344-
self.each_issued_loan(scope_id, |issued_loan| {
348+
self.each_issued_loan(scope, |issued_loan| {
345349
for &new_loan_index in new_loan_indices.iter() {
346350
let new_loan = &self.all_loans[new_loan_index];
347351
self.report_error_if_loans_conflict(issued_loan, new_loan);
@@ -535,7 +539,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
535539
old_loan.span,
536540
format!("{}; {}", borrow_summary, rule_summary).as_slice());
537541

538-
let old_loan_span = self.tcx().map.span(old_loan.kill_scope);
542+
let old_loan_span = self.tcx().map.span(old_loan.kill_scope.node_id());
539543
self.bccx.span_end_note(old_loan_span,
540544
"previous borrow ends here");
541545

@@ -657,7 +661,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
657661

658662
let mut ret = UseOk;
659663

660-
self.each_in_scope_loan_affecting_path(expr_id, use_path, |loan| {
664+
self.each_in_scope_loan_affecting_path(
665+
region::CodeExtent::from_node_id(expr_id), use_path, |loan| {
661666
if !compatible_borrow_kinds(loan.kind, borrow_kind) {
662667
ret = UseWhileBorrowed(loan.loan_path.clone(), loan.span);
663668
false
@@ -924,7 +929,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
924929
None => { return; /* no loan path, can't be any loans */ }
925930
};
926931

927-
this.each_in_scope_loan_affecting_path(assignment_id, &*loan_path, |loan| {
932+
let scope = region::CodeExtent::from_node_id(assignment_id);
933+
this.each_in_scope_loan_affecting_path(scope, &*loan_path, |loan| {
928934
this.report_illegal_mutation(assignment_span, &*loan_path, loan);
929935
false
930936
});

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

+13-7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use middle::borrowck::*;
1717
use middle::expr_use_visitor as euv;
1818
use middle::mem_categorization as mc;
19+
use middle::region;
1920
use middle::ty;
2021
use util::ppaux::Repr;
2122
use syntax::ast;
@@ -24,17 +25,20 @@ use syntax::codemap::Span;
2425
type R = Result<(),()>;
2526

2627
pub fn guarantee_lifetime<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
27-
item_scope_id: ast::NodeId,
28+
item_scope: region::CodeExtent,
2829
span: Span,
2930
cause: euv::LoanCause,
3031
cmt: mc::cmt<'tcx>,
3132
loan_region: ty::Region,
3233
_: ty::BorrowKind)
3334
-> Result<(),()> {
35+
//! Reports error if `loan_region` is larger than S
36+
//! where S is `item_scope` if `cmt` is an upvar,
37+
//! and is scope of `cmt` otherwise.
3438
debug!("guarantee_lifetime(cmt={}, loan_region={})",
3539
cmt.repr(bccx.tcx), loan_region.repr(bccx.tcx));
3640
let ctxt = GuaranteeLifetimeContext {bccx: bccx,
37-
item_scope_id: item_scope_id,
41+
item_scope: item_scope,
3842
span: span,
3943
cause: cause,
4044
loan_region: loan_region,
@@ -48,8 +52,8 @@ pub fn guarantee_lifetime<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
4852
struct GuaranteeLifetimeContext<'a, 'tcx: 'a> {
4953
bccx: &'a BorrowckCtxt<'a, 'tcx>,
5054

51-
// the node id of the function body for the enclosing item
52-
item_scope_id: ast::NodeId,
55+
// the scope of the function body for the enclosing item
56+
item_scope: region::CodeExtent,
5357

5458
span: Span,
5559
cause: euv::LoanCause,
@@ -60,7 +64,9 @@ struct GuaranteeLifetimeContext<'a, 'tcx: 'a> {
6064
impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
6165

6266
fn check(&self, cmt: &mc::cmt<'tcx>, discr_scope: Option<ast::NodeId>) -> R {
63-
//! Main routine. Walks down `cmt` until we find the "guarantor".
67+
//! Main routine. Walks down `cmt` until we find the
68+
//! "guarantor". Reports an error if `self.loan_region` is
69+
//! larger than scope of `cmt`.
6470
debug!("guarantee_lifetime.check(cmt={}, loan_region={})",
6571
cmt.repr(self.bccx.tcx),
6672
self.loan_region.repr(self.bccx.tcx));
@@ -88,7 +94,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
8894
}
8995

9096
fn check_scope(&self, max_scope: ty::Region) -> R {
91-
//! Reports an error if `loan_region` is larger than `valid_scope`
97+
//! Reports an error if `loan_region` is larger than `max_scope`
9298
9399
if !self.bccx.is_subregion_of(self.loan_region, max_scope) {
94100
Err(self.report_error(err_out_of_scope(max_scope, self.loan_region)))
@@ -109,7 +115,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
109115
temp_scope
110116
}
111117
mc::cat_upvar(..) => {
112-
ty::ReScope(self.item_scope_id)
118+
ty::ReScope(self.item_scope)
113119
}
114120
mc::cat_static_item => {
115121
ty::ReStatic

0 commit comments

Comments
 (0)