parent
13801f60b2
commit
fd8f56efab
5 changed files with 97 additions and 10 deletions
|
@ -197,13 +197,13 @@ pub enum AutoRefKind {
|
|||
/// Convert from T to &T
|
||||
AutoPtr,
|
||||
|
||||
/// Convert from @[]/~[] to &[] (or str)
|
||||
/// Convert from @[]/~[]/&[] to &[] (or str)
|
||||
AutoBorrowVec,
|
||||
|
||||
/// Convert from @[]/~[] to &&[] (or str)
|
||||
/// Convert from @[]/~[]/&[] to &&[] (or str)
|
||||
AutoBorrowVecRef,
|
||||
|
||||
/// Convert from @fn()/~fn() to &fn()
|
||||
/// Convert from @fn()/~fn()/&fn() to &fn()
|
||||
AutoBorrowFn
|
||||
}
|
||||
|
||||
|
|
|
@ -494,8 +494,8 @@ pub mod guarantor {
|
|||
* inferencer would not know of this dependency and thus it might
|
||||
* infer the lifetime of L2 to be greater than L1 (issue #3148).
|
||||
*
|
||||
* There are a number of troublesome scenarios in the test
|
||||
* `region-dependent-addr-of.rs`, but here is one example:
|
||||
* There are a number of troublesome scenarios in the tests
|
||||
* `region-dependent-*.rs`, but here is one example:
|
||||
*
|
||||
* struct Foo { i: int }
|
||||
* struct Bar { foo: Foo }
|
||||
|
@ -583,8 +583,35 @@ pub mod guarantor {
|
|||
let mut expr_ct = categorize_unadjusted(rcx, expr);
|
||||
expr_ct = apply_autoderefs(
|
||||
rcx, expr, autoderefs, expr_ct);
|
||||
for expr_ct.cat.guarantor.each |g| {
|
||||
infallibly_mk_subr(rcx, true, expr.span, autoref.region, *g);
|
||||
|
||||
match autoref.kind {
|
||||
ty::AutoPtr => {
|
||||
// In this case, we are implicitly adding an `&`.
|
||||
maybe_make_subregion(rcx, expr, autoref.region,
|
||||
expr_ct.cat.guarantor);
|
||||
}
|
||||
|
||||
ty::AutoBorrowVec |
|
||||
ty::AutoBorrowVecRef |
|
||||
ty::AutoBorrowFn => {
|
||||
// In each of these cases, what is being borrowed is
|
||||
// not the (autoderef'd) expr itself but rather the
|
||||
// contents of the autoderef'd expression (i.e., what
|
||||
// the pointer points at).
|
||||
maybe_make_subregion(rcx, expr, autoref.region,
|
||||
guarantor_of_deref(&expr_ct.cat));
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_make_subregion(
|
||||
rcx: @mut Rcx,
|
||||
expr: @ast::expr,
|
||||
sub_region: ty::Region,
|
||||
sup_region: Option<ty::Region>)
|
||||
{
|
||||
for sup_region.each |r| {
|
||||
infallibly_mk_subr(rcx, true, expr.span, sub_region, *r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -813,19 +840,31 @@ pub mod guarantor {
|
|||
|
||||
fn pointer_categorize(ty: ty::t) -> PointerCategorization {
|
||||
match ty::get(ty).sty {
|
||||
ty::ty_rptr(r, _) | ty::ty_evec(_, ty::vstore_slice(r)) |
|
||||
ty::ty_rptr(r, _) |
|
||||
ty::ty_evec(_, ty::vstore_slice(r)) |
|
||||
ty::ty_estr(ty::vstore_slice(r)) => {
|
||||
BorrowedPointer(r)
|
||||
}
|
||||
ty::ty_uniq(*) | ty::ty_estr(ty::vstore_uniq) |
|
||||
ty::ty_uniq(*) |
|
||||
ty::ty_estr(ty::vstore_uniq) |
|
||||
ty::ty_evec(_, ty::vstore_uniq) => {
|
||||
OwnedPointer
|
||||
}
|
||||
ty::ty_box(*) | ty::ty_ptr(*) |
|
||||
ty::ty_box(*) |
|
||||
ty::ty_ptr(*) |
|
||||
ty::ty_evec(_, ty::vstore_box) |
|
||||
ty::ty_estr(ty::vstore_box) => {
|
||||
OtherPointer
|
||||
}
|
||||
ty::ty_closure(ref closure_ty) => {
|
||||
match closure_ty.sigil {
|
||||
ast::BorrowedSigil => BorrowedPointer(closure_ty.region),
|
||||
ast::OwnedSigil => OwnedPointer,
|
||||
|
||||
// NOTE This is...not quite right. Deduce a test etc.
|
||||
ast::ManagedSigil => OtherPointer,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
NotPointer
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test lifetimes are linked properly when we create dependent region pointers.
|
||||
// Issue #3148.
|
||||
|
||||
struct A {
|
||||
value: B
|
||||
}
|
||||
|
|
22
src/test/run-pass/region-dependent-autofn.rs
Normal file
22
src/test/run-pass/region-dependent-autofn.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test lifetimes are linked properly when we autoslice a vector.
|
||||
// Issue #3148.
|
||||
|
||||
fn subslice<'r>(v: &'r fn()) -> &'r fn() { v }
|
||||
|
||||
fn both<'r>(v: &'r fn()) -> &'r fn() {
|
||||
subslice(subslice(v))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
both(main);
|
||||
}
|
23
src/test/run-pass/region-dependent-autoslice.rs
Normal file
23
src/test/run-pass/region-dependent-autoslice.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test lifetimes are linked properly when we autoslice a vector.
|
||||
// Issue #3148.
|
||||
|
||||
fn subslice1<'r>(v: &'r [uint]) -> &'r [uint] { v }
|
||||
|
||||
fn both<'r>(v: &'r [uint]) -> &'r [uint] {
|
||||
subslice1(subslice1(v))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let v = ~[1,2,3];
|
||||
both(v);
|
||||
}
|
Loading…
Add table
Reference in a new issue