From 8a9ced1551a8f44798989f99f32ed1657c70bfce Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Fri, 31 Oct 2014 23:31:16 -0700 Subject: [PATCH 1/3] Fix trans of index overload expressions with DST result types Closes #18487 --- src/librustc/middle/trans/expr.rs | 32 ++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 3bfa6af4a9bc..37e9a10d670f 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -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, From 6b93b4eb7caa26f0bda28d9c89952406f426670c Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Fri, 31 Oct 2014 23:42:48 -0700 Subject: [PATCH 2/3] Add regression test for #18487 --- src/test/run-pass/dst-index.rs | 37 ++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/test/run-pass/dst-index.rs diff --git a/src/test/run-pass/dst-index.rs b/src/test/run-pass/dst-index.rs new file mode 100644 index 000000000000..266f9bcba5f9 --- /dev/null +++ b/src/test/run-pass/dst-index.rs @@ -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 or the MIT license +// , 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 for S { + fn index<'a>(&'a self, _: &uint) -> &'a str { + "hello" + } +} + +struct T; + +impl Index 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"); +} From 205f84f13c69dd20caa6ecb6fc1bbed9171f0703 Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Sat, 1 Nov 2014 01:56:09 -0700 Subject: [PATCH 3/3] Add compile-fail test of DST rvalues resulting from overloaded index --- src/test/compile-fail/dst-index.rs | 40 ++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/test/compile-fail/dst-index.rs diff --git a/src/test/compile-fail/dst-index.rs b/src/test/compile-fail/dst-index.rs new file mode 100644 index 000000000000..542562b69e6a --- /dev/null +++ b/src/test/compile-fail/dst-index.rs @@ -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 or the MIT license +// , 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 for S { + fn index<'a>(&'a self, _: &uint) -> &'a str { + "hello" + } +} + +struct T; + +impl Index 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 +}