Skip to content

Commit

Permalink
auto merge of #5740 : nikomatsakis/rust/issue-5739-reborrowed-slices,…
Browse files Browse the repository at this point in the history
… r=catamorphism

r? @catamorphism (just the last commit)

This is a minor patch to #3184 (which you also reviewed), needed for #5656
  • Loading branch information
bors committed Apr 6, 2013
2 parents bdd2439 + fd8f56e commit 28527ce
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 10 deletions.
6 changes: 3 additions & 3 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
53 changes: 46 additions & 7 deletions src/librustc/middle/typeck/check/regionck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down Expand Up @@ -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);
}
}
}

Expand Down Expand Up @@ -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
}
Expand Down
3 changes: 3 additions & 0 deletions src/test/run-pass/region-dependent-addr-of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
22 changes: 22 additions & 0 deletions src/test/run-pass/region-dependent-autofn.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 23 additions & 0 deletions src/test/run-pass/region-dependent-autoslice.rs
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit 28527ce

Please sign in to comment.