typeck: handle unsized structs in type hints by recursing into their last field.
This commit is contained in:
parent
cf7e825ecd
commit
c46f913244
2 changed files with 10 additions and 5 deletions
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)),
|
||||
|
|
Loading…
Add table
Reference in a new issue