Skip to content

Commit 02c234c

Browse files
committed
rollup merge of #18505 : bkoropoff/issue-18487
2 parents 82efef7 + 205f84f commit 02c234c

File tree

3 files changed

+96
-13
lines changed

3 files changed

+96
-13
lines changed

src/librustc/middle/trans/expr.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -745,18 +745,6 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
745745
// Translate index expression.
746746
let ix_datum = unpack_datum!(bcx, trans(bcx, idx));
747747

748-
// Overloaded. Evaluate `trans_overloaded_op`, which will
749-
// invoke the user's index() method, which basically yields
750-
// a `&T` pointer. We can then proceed down the normal
751-
// path (below) to dereference that `&T`.
752-
let val =
753-
unpack_result!(bcx,
754-
trans_overloaded_op(bcx,
755-
index_expr,
756-
method_call,
757-
base_datum,
758-
vec![(ix_datum, idx.id)],
759-
None));
760748
let ref_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty)).unwrap();
761749
let elt_ty = match ty::deref(ref_ty, true) {
762750
None => {
@@ -766,7 +754,25 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
766754
}
767755
Some(elt_tm) => elt_tm.ty,
768756
};
769-
Datum::new(val, elt_ty, LvalueExpr)
757+
758+
// Overloaded. Evaluate `trans_overloaded_op`, which will
759+
// invoke the user's index() method, which basically yields
760+
// a `&T` pointer. We can then proceed down the normal
761+
// path (below) to dereference that `&T`.
762+
let scratch = rvalue_scratch_datum(bcx, ref_ty, "overloaded_index_elt");
763+
unpack_result!(bcx,
764+
trans_overloaded_op(bcx,
765+
index_expr,
766+
method_call,
767+
base_datum,
768+
vec![(ix_datum, idx.id)],
769+
Some(SaveIn(scratch.val))));
770+
let datum = scratch.to_expr_datum();
771+
if ty::type_is_sized(bcx.tcx(), elt_ty) {
772+
Datum::new(datum.to_llscalarish(bcx), elt_ty, LvalueExpr)
773+
} else {
774+
Datum::new(datum.val, ty::mk_open(bcx.tcx(), elt_ty), LvalueExpr)
775+
}
770776
}
771777
None => {
772778
let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx,

src/test/compile-fail/dst-index.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2014 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 that overloaded index expressions with DST result types
12+
// can't be used as rvalues
13+
14+
use std::ops::Index;
15+
use std::fmt::Show;
16+
17+
struct S;
18+
19+
impl Index<uint, str> for S {
20+
fn index<'a>(&'a self, _: &uint) -> &'a str {
21+
"hello"
22+
}
23+
}
24+
25+
struct T;
26+
27+
impl Index<uint, Show + 'static> for T {
28+
fn index<'a>(&'a self, idx: &uint) -> &'a Show + 'static {
29+
static x: uint = 42;
30+
&x
31+
}
32+
}
33+
34+
fn main() {
35+
S[0];
36+
//~^ ERROR E0161
37+
T[0];
38+
//~^ ERROR cannot move out of dereference
39+
//~^^ ERROR E0161
40+
}

src/test/run-pass/dst-index.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2014 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 that overloaded index expressions with DST result types
12+
// work and don't ICE.
13+
14+
use std::ops::Index;
15+
use std::fmt::Show;
16+
17+
struct S;
18+
19+
impl Index<uint, str> for S {
20+
fn index<'a>(&'a self, _: &uint) -> &'a str {
21+
"hello"
22+
}
23+
}
24+
25+
struct T;
26+
27+
impl Index<uint, Show + 'static> for T {
28+
fn index<'a>(&'a self, idx: &uint) -> &'a Show + 'static {
29+
static x: uint = 42;
30+
&x
31+
}
32+
}
33+
34+
fn main() {
35+
assert_eq!(&S[0], "hello");
36+
assert_eq!(format!("{}", &T[0]).as_slice(), "42");
37+
}

0 commit comments

Comments
 (0)