Auto merge of #27294 - eddyb:deep-unsize-hinting, r=nrc

`Rc::new(RefCell::new(x)): Rc<RefCell<Trait>>` should not mean `RefCell::new(x): RefCell<Trait>`.
The latter is impossible, as an rvalue can't have an unsized type.
We were already handling unsized argument hints, but not when dealing with unsized structures.
This commit is contained in:
bors 2015-07-26 23:35:38 +00:00
commit 6d288192d9
2 changed files with 10 additions and 5 deletions

View file

@ -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)
}

View file

@ -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<Fn(isize) -> _> = Box::new(|x| (x as u8));
let _: Rc<RefCell<[isize]>> = Rc::new(RefCell::new([1, 2, 3]));
let _: Rc<RefCell<FnMut(isize) -> _>> = Rc::new(RefCell::new(|x| (x as u8)));
let _: Vec<Box<Fn(isize) -> _>> = vec![
Box::new(|x| (x as u8)),
Box::new(|x| (x as i16 as u8)),