Skip to content

Commit fd8f56e

Browse files
committed
Link lifetimes of autoslice'd vectors (Issue #3184)
Fixes #5739.
1 parent 13801f6 commit fd8f56e

File tree

5 files changed

+97
-10
lines changed

5 files changed

+97
-10
lines changed

src/librustc/middle/ty.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -197,13 +197,13 @@ pub enum AutoRefKind {
197197
/// Convert from T to &T
198198
AutoPtr,
199199

200-
/// Convert from @[]/~[] to &[] (or str)
200+
/// Convert from @[]/~[]/&[] to &[] (or str)
201201
AutoBorrowVec,
202202

203-
/// Convert from @[]/~[] to &&[] (or str)
203+
/// Convert from @[]/~[]/&[] to &&[] (or str)
204204
AutoBorrowVecRef,
205205

206-
/// Convert from @fn()/~fn() to &fn()
206+
/// Convert from @fn()/~fn()/&fn() to &fn()
207207
AutoBorrowFn
208208
}
209209

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

+46-7
Original file line numberDiff line numberDiff line change
@@ -494,8 +494,8 @@ pub mod guarantor {
494494
* inferencer would not know of this dependency and thus it might
495495
* infer the lifetime of L2 to be greater than L1 (issue #3148).
496496
*
497-
* There are a number of troublesome scenarios in the test
498-
* `region-dependent-addr-of.rs`, but here is one example:
497+
* There are a number of troublesome scenarios in the tests
498+
* `region-dependent-*.rs`, but here is one example:
499499
*
500500
* struct Foo { i: int }
501501
* struct Bar { foo: Foo }
@@ -583,8 +583,35 @@ pub mod guarantor {
583583
let mut expr_ct = categorize_unadjusted(rcx, expr);
584584
expr_ct = apply_autoderefs(
585585
rcx, expr, autoderefs, expr_ct);
586-
for expr_ct.cat.guarantor.each |g| {
587-
infallibly_mk_subr(rcx, true, expr.span, autoref.region, *g);
586+
587+
match autoref.kind {
588+
ty::AutoPtr => {
589+
// In this case, we are implicitly adding an `&`.
590+
maybe_make_subregion(rcx, expr, autoref.region,
591+
expr_ct.cat.guarantor);
592+
}
593+
594+
ty::AutoBorrowVec |
595+
ty::AutoBorrowVecRef |
596+
ty::AutoBorrowFn => {
597+
// In each of these cases, what is being borrowed is
598+
// not the (autoderef'd) expr itself but rather the
599+
// contents of the autoderef'd expression (i.e., what
600+
// the pointer points at).
601+
maybe_make_subregion(rcx, expr, autoref.region,
602+
guarantor_of_deref(&expr_ct.cat));
603+
}
604+
}
605+
606+
fn maybe_make_subregion(
607+
rcx: @mut Rcx,
608+
expr: @ast::expr,
609+
sub_region: ty::Region,
610+
sup_region: Option<ty::Region>)
611+
{
612+
for sup_region.each |r| {
613+
infallibly_mk_subr(rcx, true, expr.span, sub_region, *r);
614+
}
588615
}
589616
}
590617

@@ -813,19 +840,31 @@ pub mod guarantor {
813840

814841
fn pointer_categorize(ty: ty::t) -> PointerCategorization {
815842
match ty::get(ty).sty {
816-
ty::ty_rptr(r, _) | ty::ty_evec(_, ty::vstore_slice(r)) |
843+
ty::ty_rptr(r, _) |
844+
ty::ty_evec(_, ty::vstore_slice(r)) |
817845
ty::ty_estr(ty::vstore_slice(r)) => {
818846
BorrowedPointer(r)
819847
}
820-
ty::ty_uniq(*) | ty::ty_estr(ty::vstore_uniq) |
848+
ty::ty_uniq(*) |
849+
ty::ty_estr(ty::vstore_uniq) |
821850
ty::ty_evec(_, ty::vstore_uniq) => {
822851
OwnedPointer
823852
}
824-
ty::ty_box(*) | ty::ty_ptr(*) |
853+
ty::ty_box(*) |
854+
ty::ty_ptr(*) |
825855
ty::ty_evec(_, ty::vstore_box) |
826856
ty::ty_estr(ty::vstore_box) => {
827857
OtherPointer
828858
}
859+
ty::ty_closure(ref closure_ty) => {
860+
match closure_ty.sigil {
861+
ast::BorrowedSigil => BorrowedPointer(closure_ty.region),
862+
ast::OwnedSigil => OwnedPointer,
863+
864+
// NOTE This is...not quite right. Deduce a test etc.
865+
ast::ManagedSigil => OtherPointer,
866+
}
867+
}
829868
_ => {
830869
NotPointer
831870
}

src/test/run-pass/region-dependent-addr-of.rs

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// Test lifetimes are linked properly when we create dependent region pointers.
12+
// Issue #3148.
13+
1114
struct A {
1215
value: B
1316
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test lifetimes are linked properly when we autoslice a vector.
12+
// Issue #3148.
13+
14+
fn subslice<'r>(v: &'r fn()) -> &'r fn() { v }
15+
16+
fn both<'r>(v: &'r fn()) -> &'r fn() {
17+
subslice(subslice(v))
18+
}
19+
20+
fn main() {
21+
both(main);
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test lifetimes are linked properly when we autoslice a vector.
12+
// Issue #3148.
13+
14+
fn subslice1<'r>(v: &'r [uint]) -> &'r [uint] { v }
15+
16+
fn both<'r>(v: &'r [uint]) -> &'r [uint] {
17+
subslice1(subslice1(v))
18+
}
19+
20+
fn main() {
21+
let v = ~[1,2,3];
22+
both(v);
23+
}

0 commit comments

Comments
 (0)