Skip to content

Commit bd84627

Browse files
committed
---
yaml --- r: 34002 b: refs/heads/snap-stage3 c: 2fcf562 h: refs/heads/master v: v3
1 parent eb9dc65 commit bd84627

File tree

7 files changed

+112
-8
lines changed

7 files changed

+112
-8
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: cd6f24f9d14ac90d167386a56e7a6ac1f0318195
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: e71081ec0368729aec8d2c077192f026f128dc81
4+
refs/heads/snap-stage3: 2fcf562d163e57acdc4a7e5b0504df2dea6e34e6
55
refs/heads/try: d324a424d8f84b1eb049b12cf34182bda91b0024
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/librustc/middle/borrowck/gather_loans.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ impl gather_loan_ctxt {
295295
autoref.mutbl,
296296
autoref.region)
297297
}
298-
ty::AutoBorrowVec => {
298+
ty::AutoBorrowVec | ty::AutoBorrowVecRef => {
299299
let cmt_index = mcx.cat_index(expr, cmt);
300300
self.guarantee_valid(cmt_index,
301301
autoref.mutbl,

branches/snap-stage3/src/librustc/middle/trans/expr.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ use base::*;
119119
use syntax::print::pprust::{expr_to_str};
120120
use util::ppaux::ty_to_str;
121121
use util::common::indenter;
122-
use ty::{AutoPtr, AutoBorrowVec, AutoBorrowFn};
122+
use ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn};
123123
use callee::{AutorefArg, DoAutorefArg, DontAutorefArg};
124124
use middle::ty::MoveValue;
125125

@@ -202,6 +202,9 @@ fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock {
202202
AutoBorrowVec => {
203203
unpack_datum!(bcx, auto_slice(bcx, datum))
204204
}
205+
AutoBorrowVecRef => {
206+
unpack_datum!(bcx, auto_slice_and_ref(bcx, datum))
207+
}
205208
AutoBorrowFn => {
206209
// currently, all closure types are
207210
// represented precisely the same, so no
@@ -243,6 +246,11 @@ fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock {
243246
Store(bcx, len, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]));
244247
DatumBlock {bcx: bcx, datum: scratch}
245248
}
249+
250+
fn auto_slice_and_ref(bcx: block, datum: Datum) -> DatumBlock {
251+
let DatumBlock { bcx, datum } = auto_slice(bcx, datum);
252+
auto_ref(bcx, datum)
253+
}
246254
}
247255

248256
fn trans_into(bcx: block, expr: @ast::expr, dest: Dest) -> block {

branches/snap-stage3/src/librustc/middle/ty.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ export DerivedMethodInfo;
218218
export DerivedFieldInfo;
219219
export AutoAdjustment;
220220
export AutoRef;
221-
export AutoRefKind, AutoPtr, AutoBorrowVec, AutoBorrowFn;
221+
export AutoRefKind, AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn;
222222
export iter_bound_traits_and_supertraits;
223223
export count_traits_and_supertraits;
224224

@@ -352,6 +352,9 @@ enum AutoRefKind {
352352
/// Convert from @[]/~[] to &[] (or str)
353353
AutoBorrowVec,
354354

355+
/// Convert from @[]/~[] to &&[] (or str)
356+
AutoBorrowVecRef,
357+
355358
/// Convert from @fn()/~fn() to &fn()
356359
AutoBorrowFn,
357360
}

branches/snap-stage3/src/librustc/middle/typeck/check/method.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -707,19 +707,46 @@ impl LookupContext {
707707
ty_evec(mt, vstore_box) |
708708
ty_evec(mt, vstore_uniq) |
709709
ty_evec(mt, vstore_fixed(_)) => {
710-
self.search_for_some_kind_of_autorefd_method(
710+
// First try to borrow to a slice
711+
let entry = self.search_for_some_kind_of_autorefd_method(
711712
AutoBorrowVec, autoderefs, [m_const, m_imm, m_mutbl],
712713
|m,r| ty::mk_evec(tcx,
713714
{ty:mt.ty, mutbl:m},
714-
vstore_slice(r)))
715+
vstore_slice(r)));
716+
717+
if entry.is_some() { return entry; }
718+
719+
// Then try to borrow to a slice *and* borrow a pointer.
720+
self.search_for_some_kind_of_autorefd_method(
721+
AutoBorrowVecRef, autoderefs, [m_const, m_imm, m_mutbl],
722+
|m,r| {
723+
let slice_ty = ty::mk_evec(tcx,
724+
{ty:mt.ty, mutbl:m},
725+
vstore_slice(r));
726+
// NB: we do not try to autoref to a mutable
727+
// pointer. That would be creating a pointer
728+
// to a temporary pointer (the borrowed
729+
// slice), so any update the callee makes to
730+
// it can't be observed.
731+
ty::mk_rptr(tcx, r, {ty:slice_ty, mutbl:m_imm})
732+
})
715733
}
716734

717735
ty_estr(vstore_box) |
718736
ty_estr(vstore_uniq) |
719737
ty_estr(vstore_fixed(_)) => {
720-
self.search_for_some_kind_of_autorefd_method(
738+
let entry = self.search_for_some_kind_of_autorefd_method(
721739
AutoBorrowVec, autoderefs, [m_imm],
722-
|_m,r| ty::mk_estr(tcx, vstore_slice(r)))
740+
|_m,r| ty::mk_estr(tcx, vstore_slice(r)));
741+
742+
if entry.is_some() { return entry; }
743+
744+
self.search_for_some_kind_of_autorefd_method(
745+
AutoBorrowVecRef, autoderefs, [m_imm],
746+
|m,r| {
747+
let slice_ty = ty::mk_estr(tcx, vstore_slice(r));
748+
ty::mk_rptr(tcx, r, {ty:slice_ty, mutbl:m})
749+
})
723750
}
724751

725752
ty_trait(*) | ty_fn(*) => {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
fn main() {
2+
3+
// Testing that method lookup does not automatically borrow
4+
// vectors to slices then automatically create a &mut self
5+
// reference. That would allow creating a mutable pointer to a
6+
// temporary, which would be a source of confusion
7+
8+
let mut a = @[0];
9+
a.test_mut(); //~ ERROR type `@[int]` does not implement any method in scope named `test_mut`
10+
}
11+
12+
trait MyIter {
13+
pure fn test_mut(&mut self);
14+
}
15+
16+
impl &[int]: MyIter {
17+
pure fn test_mut(&mut self) { }
18+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Testing that method lookup automatically both borrows vectors to slices
2+
// and also references them to create the &self pointer
3+
4+
trait MyIter {
5+
pure fn test_imm(&self);
6+
pure fn test_const(&const self);
7+
}
8+
9+
impl &[int]: MyIter {
10+
pure fn test_imm(&self) { assert self[0] == 1 }
11+
pure fn test_const(&const self) { assert self[0] == 1 }
12+
}
13+
14+
impl &str: MyIter {
15+
pure fn test_imm(&self) { assert *self == "test" }
16+
pure fn test_const(&const self) { assert *self == "test" }
17+
}
18+
19+
fn main() {
20+
// NB: Associativity of ~, etc. in this context is surprising. These must be parenthesized
21+
22+
([1]).test_imm();
23+
(~[1]).test_imm();
24+
(@[1]).test_imm();
25+
(&[1]).test_imm();
26+
("test").test_imm();
27+
(~"test").test_imm();
28+
(@"test").test_imm();
29+
(&"test").test_imm();
30+
31+
// XXX: Other types of mutable vecs don't currently exist
32+
(@mut [1]).test_imm();
33+
34+
([1]).test_const();
35+
(~[1]).test_const();
36+
(@[1]).test_const();
37+
(&[1]).test_const();
38+
("test").test_const();
39+
(~"test").test_const();
40+
(@"test").test_const();
41+
(&"test").test_const();
42+
43+
(@mut [1]).test_const();
44+
45+
// NB: We don't do this double autoreffing for &mut self because that would
46+
// allow creating a mutable pointer to a temporary, which would be a source
47+
// of confusion
48+
}

0 commit comments

Comments
 (0)