rollup merge of #18505 : bkoropoff/issue-18487
This commit is contained in:
commit
02c234cc52
@ -745,18 +745,6 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
// Translate index expression.
|
||||
let ix_datum = unpack_datum!(bcx, trans(bcx, idx));
|
||||
|
||||
// Overloaded. Evaluate `trans_overloaded_op`, which will
|
||||
// invoke the user's index() method, which basically yields
|
||||
// a `&T` pointer. We can then proceed down the normal
|
||||
// path (below) to dereference that `&T`.
|
||||
let val =
|
||||
unpack_result!(bcx,
|
||||
trans_overloaded_op(bcx,
|
||||
index_expr,
|
||||
method_call,
|
||||
base_datum,
|
||||
vec![(ix_datum, idx.id)],
|
||||
None));
|
||||
let ref_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty)).unwrap();
|
||||
let elt_ty = match ty::deref(ref_ty, true) {
|
||||
None => {
|
||||
@ -766,7 +754,25 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
}
|
||||
Some(elt_tm) => elt_tm.ty,
|
||||
};
|
||||
Datum::new(val, elt_ty, LvalueExpr)
|
||||
|
||||
// Overloaded. Evaluate `trans_overloaded_op`, which will
|
||||
// invoke the user's index() method, which basically yields
|
||||
// a `&T` pointer. We can then proceed down the normal
|
||||
// path (below) to dereference that `&T`.
|
||||
let scratch = rvalue_scratch_datum(bcx, ref_ty, "overloaded_index_elt");
|
||||
unpack_result!(bcx,
|
||||
trans_overloaded_op(bcx,
|
||||
index_expr,
|
||||
method_call,
|
||||
base_datum,
|
||||
vec![(ix_datum, idx.id)],
|
||||
Some(SaveIn(scratch.val))));
|
||||
let datum = scratch.to_expr_datum();
|
||||
if ty::type_is_sized(bcx.tcx(), elt_ty) {
|
||||
Datum::new(datum.to_llscalarish(bcx), elt_ty, LvalueExpr)
|
||||
} else {
|
||||
Datum::new(datum.val, ty::mk_open(bcx.tcx(), elt_ty), LvalueExpr)
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx,
|
||||
|
40
src/test/compile-fail/dst-index.rs
Normal file
40
src/test/compile-fail/dst-index.rs
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2014 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 that overloaded index expressions with DST result types
|
||||
// can't be used as rvalues
|
||||
|
||||
use std::ops::Index;
|
||||
use std::fmt::Show;
|
||||
|
||||
struct S;
|
||||
|
||||
impl Index<uint, str> for S {
|
||||
fn index<'a>(&'a self, _: &uint) -> &'a str {
|
||||
"hello"
|
||||
}
|
||||
}
|
||||
|
||||
struct T;
|
||||
|
||||
impl Index<uint, Show + 'static> for T {
|
||||
fn index<'a>(&'a self, idx: &uint) -> &'a Show + 'static {
|
||||
static x: uint = 42;
|
||||
&x
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
S[0];
|
||||
//~^ ERROR E0161
|
||||
T[0];
|
||||
//~^ ERROR cannot move out of dereference
|
||||
//~^^ ERROR E0161
|
||||
}
|
37
src/test/run-pass/dst-index.rs
Normal file
37
src/test/run-pass/dst-index.rs
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright 2014 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 that overloaded index expressions with DST result types
|
||||
// work and don't ICE.
|
||||
|
||||
use std::ops::Index;
|
||||
use std::fmt::Show;
|
||||
|
||||
struct S;
|
||||
|
||||
impl Index<uint, str> for S {
|
||||
fn index<'a>(&'a self, _: &uint) -> &'a str {
|
||||
"hello"
|
||||
}
|
||||
}
|
||||
|
||||
struct T;
|
||||
|
||||
impl Index<uint, Show + 'static> for T {
|
||||
fn index<'a>(&'a self, idx: &uint) -> &'a Show + 'static {
|
||||
static x: uint = 42;
|
||||
&x
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(&S[0], "hello");
|
||||
assert_eq!(format!("{}", &T[0]).as_slice(), "42");
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user