Check arg/ret sizedness at ExprKind::Path.

This commit is contained in:
Masaki Hara 2018-11-19 00:18:13 +09:00
parent 682b33a110
commit 8b426232ee
7 changed files with 48 additions and 44 deletions

View File

@ -3956,6 +3956,31 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
tcx.types.err
};
if let ty::FnDef(..) = ty.sty {
let fn_sig = ty.fn_sig(tcx);
if !tcx.features().unsized_locals {
// We want to remove some Sized bounds from std functions,
// but don't want to expose the removal to stable Rust.
// i.e. we don't want to allow
//
// ```rust
// drop as fn(str);
// ```
//
// to work in stable even if the Sized bound on `drop` is relaxed.
for i in 0..fn_sig.inputs().skip_binder().len() {
let input = tcx.erase_late_bound_regions(&fn_sig.input(i));
self.require_type_is_sized_deferred(input, expr.span,
traits::SizedArgumentType);
}
}
// Here we want to prevent struct constructors from returning unsized types.
// There were two cases this happened: fn pointer coercion in stable
// and usual function call in presense of unsized_locals.
let output = tcx.erase_late_bound_regions(&fn_sig.output());
self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
}
// We always require that the type provided as the value for
// a type parameter outlives the moment of instantiation.
let substs = self.tables.borrow().node_substs(expr.hir_id);

View File

@ -1,22 +0,0 @@
error[E0161]: cannot move a value of type X: the size of X cannot be statically determined
--> $DIR/issue-30355.rs:15:6
|
LL | &X(*Y)
| ^^^^^
error[E0161]: cannot move a value of type [u8]: the size of [u8] cannot be statically determined
--> $DIR/issue-30355.rs:15:8
|
LL | &X(*Y)
| ^^
error[E0508]: cannot move out of type `[u8]`, a non-copy slice
--> $DIR/issue-30355.rs:15:8
|
LL | &X(*Y)
| ^^ cannot move out of here
error: aborting due to 3 previous errors
Some errors occurred: E0161, E0508.
For more information about an error, try `rustc --explain E0161`.

View File

@ -13,9 +13,7 @@ pub struct X([u8]);
pub static Y: &'static X = {
const Y: &'static [u8] = b"";
&X(*Y)
//~^ ERROR cannot move out
//~^^ ERROR cannot move a
//~^^^ ERROR cannot move a
//~^ ERROR E0277
};
fn main() {}

View File

@ -1,22 +1,14 @@
error[E0161]: cannot move a value of type X: the size of X cannot be statically determined
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/issue-30355.rs:15:6
|
LL | &X(*Y)
| ^^^^^
error[E0161]: cannot move a value of type [u8]: the size of [u8] cannot be statically determined
--> $DIR/issue-30355.rs:15:8
| ^ doesn't have a size known at compile-time
|
LL | &X(*Y)
| ^^
= help: the trait `std::marker::Sized` is not implemented for `[u8]`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: all function arguments must have a statically known size
= help: unsized locals are gated as an unstable feature
error[E0507]: cannot move out of borrowed content
--> $DIR/issue-30355.rs:15:8
|
LL | &X(*Y)
| ^^ cannot move out of borrowed content
error: aborting due to previous error
error: aborting due to 3 previous errors
Some errors occurred: E0161, E0507.
For more information about an error, try `rustc --explain E0161`.
For more information about this error, try `rustc --explain E0277`.

View File

@ -23,4 +23,6 @@ fn main() {
//~^ERROR E0277
udrop::<A<[u8]>>(A { 0: *foo() });
//~^ERROR E0277
udrop::<A<[u8]>>(A(*foo()));
//~^ERROR E0277
}

View File

@ -20,6 +20,17 @@ LL | udrop::<A<[u8]>>(A { 0: *foo() });
= note: required because it appears within the type `A<[u8]>`
= note: structs must have a statically known size to be initialized
error: aborting due to 2 previous errors
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/unsized-exprs.rs:26:22
|
LL | udrop::<A<[u8]>>(A(*foo()));
| ^ doesn't have a size known at compile-time
|
= help: within `A<[u8]>`, the trait `std::marker::Sized` is not implemented for `[u8]`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required because it appears within the type `A<[u8]>`
= note: the return type of a function must have a statically known size
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -21,6 +21,4 @@ impl std::ops::Add<i32> for A<[u8]> {
fn main() {
udrop::<[u8]>(foo()[..]);
//~^ERROR cannot move out of indexed content
// FIXME: should be error
udrop::<A<[u8]>>(A(*foo()));
}