From c46f91324434d46472bd4aa15286240b7ba537d6 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Sun, 26 Jul 2015 03:55:35 +0300 Subject: [PATCH] typeck: handle unsized structs in type hints by recursing into their last field. --- src/librustc_typeck/check/mod.rs | 10 +++++----- src/test/run-pass/coerce-expect-unsized.rs | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 85df5d67ff6..0c60cdc4ca2 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2490,7 +2490,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // The special-cased logic below has three functions: // 1. Provide as good of an expected type as possible. let expected = expected_arg_tys.get(i).map(|&ty| { - Expectation::rvalue_hint(ty) + Expectation::rvalue_hint(fcx.tcx(), ty) }); check_expr_with_unifier(fcx, &**arg, @@ -3268,7 +3268,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, match unop { ast::UnUniq => match ty.sty { ty::TyBox(ty) => { - Expectation::rvalue_hint(ty) + Expectation::rvalue_hint(tcx, ty) } _ => { NoExpectation @@ -3345,7 +3345,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, // the last field of a struct can be unsized. ExpectHasType(mt.ty) } else { - Expectation::rvalue_hint(mt.ty) + Expectation::rvalue_hint(tcx, mt.ty) } } _ => NoExpectation @@ -3982,8 +3982,8 @@ impl<'tcx> Expectation<'tcx> { /// which still is useful, because it informs integer literals and the like. /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169 /// for examples of where this comes up,. - fn rvalue_hint(ty: Ty<'tcx>) -> Expectation<'tcx> { - match ty.sty { + fn rvalue_hint(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> { + match tcx.struct_tail(ty).sty { ty::TySlice(_) | ty::TyTrait(..) => { ExpectRvalueLikeUnsized(ty) } diff --git a/src/test/run-pass/coerce-expect-unsized.rs b/src/test/run-pass/coerce-expect-unsized.rs index 6926879856c..ee4ec24b7e3 100644 --- a/src/test/run-pass/coerce-expect-unsized.rs +++ b/src/test/run-pass/coerce-expect-unsized.rs @@ -13,7 +13,9 @@ #![allow(unknown_features)] #![feature(box_syntax)] +use std::cell::RefCell; use std::fmt::Debug; +use std::rc::Rc; // Check that coercions apply at the pointer level and don't cause // rvalue expressions to be unsized. See #20169 for more information. @@ -45,6 +47,9 @@ pub fn main() { let _: Box<[isize]> = Box::new([1, 2, 3]); let _: Box _> = Box::new(|x| (x as u8)); + let _: Rc> = Rc::new(RefCell::new([1, 2, 3])); + let _: Rc _>> = Rc::new(RefCell::new(|x| (x as u8))); + let _: Vec _>> = vec![ Box::new(|x| (x as u8)), Box::new(|x| (x as i16 as u8)),