diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 59a043d1d6996..7cc069c9b6446 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -83,7 +83,8 @@ pub(super) fn check_fn<'a, 'tcx>( } // Check that argument is Sized. - if !params_can_be_unsized { + let tail = fcx.tcx.struct_tail_with_normalize(param_ty, |ty| ty, || {}); + if !params_can_be_unsized || matches!(tail.kind(), ty::Foreign(..)) { fcx.require_type_is_sized( param_ty, param.pat.span, diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl index 94b553a07a755..5514f7707edd7 100644 --- a/compiler/rustc_monomorphize/messages.ftl +++ b/compiler/rustc_monomorphize/messages.ftl @@ -30,6 +30,7 @@ monomorphize_type_length_limit = reached the type-length limit while instantiati monomorphize_unknown_cgu_collection_mode = unknown codegen-item collection mode '{$mode}', falling back to 'lazy' mode +monomorphize_unsized_extern_fn_param = unsized arguments must not be `extern` types monomorphize_unused_generic_params = item has unused generic parameters monomorphize_written_to_path = the full type name has been written to '{$path}' diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index ee6c154e6e84e..edcc356848179 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1041,6 +1041,12 @@ fn visit_fn_use<'tcx>( _ => bug!("failed to resolve instance for {ty}"), } }; + for ¶m_ty in ty.fn_sig(tcx).inputs().skip_binder() { + let tail = tcx.struct_tail_with_normalize(param_ty, |ty| ty, || {}); + if matches!(tail.kind(), ty::Foreign(..)) { + tcx.dcx().emit_fatal(errors::UnsizedExternParam { span: source }); + } + } visit_instance_use(tcx, instance, is_direct_call, source, output); } } diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index 35fc78f204533..7f20399da92de 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -104,3 +104,10 @@ pub struct StartNotFound; pub struct UnknownCguCollectionMode<'a> { pub mode: &'a str, } + +#[derive(Diagnostic)] +#[diag(monomorphize_unsized_extern_fn_param)] +pub struct UnsizedExternParam { + #[primary_span] + pub span: Span, +} diff --git a/tests/ui/recursion/recursion.stderr b/tests/ui/recursion/recursion.stderr index 7a9f04d4bd6d3..691e79703f384 100644 --- a/tests/ui/recursion/recursion.stderr +++ b/tests/ui/recursion/recursion.stderr @@ -1,3 +1,18 @@ +error: reached the recursion limit finding the struct tail for `Nil` + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` + +error: reached the recursion limit finding the struct tail for `Nil` + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +note: the above error was encountered while instantiating `fn test::>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + --> $DIR/recursion.rs:18:11 + | +LL | _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: reached the recursion limit while instantiating `test::>>>>>` --> $DIR/recursion.rs:18:11 | @@ -11,5 +26,5 @@ LL | fn test (n:isize, i:isize, first:T, second:T) ->isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: the full type name has been written to '$TEST_BUILD_DIR/recursion/recursion/recursion.long-type.txt' -error: aborting due to 1 previous error +error: aborting due to 3 previous errors diff --git a/tests/ui/unsized-locals/extern-parameter-issue-123887-generic-wrapped.rs b/tests/ui/unsized-locals/extern-parameter-issue-123887-generic-wrapped.rs new file mode 100644 index 0000000000000..60a69b5eac569 --- /dev/null +++ b/tests/ui/unsized-locals/extern-parameter-issue-123887-generic-wrapped.rs @@ -0,0 +1,16 @@ +// https://github.com/rust-lang/rust/issues/123887 +// Do not ICE on unsized extern parameter +//@ compile-flags: -Clink-dead-code --emit=link +#![feature(extern_types, unsized_fn_params)] + +extern "C" { + type ExternType; +} + +struct Wrapper(T); +fn f(_: impl ?Sized) {} +fn g(x: Box>) { + f(*x); //~ ERROR unsized arguments must not be `extern` types +} + +fn main() {} diff --git a/tests/ui/unsized-locals/extern-parameter-issue-123887-generic-wrapped.stderr b/tests/ui/unsized-locals/extern-parameter-issue-123887-generic-wrapped.stderr new file mode 100644 index 0000000000000..cc0326a454a80 --- /dev/null +++ b/tests/ui/unsized-locals/extern-parameter-issue-123887-generic-wrapped.stderr @@ -0,0 +1,8 @@ +error: unsized arguments must not be `extern` types + --> $DIR/extern-parameter-issue-123887-generic-wrapped.rs:13:5 + | +LL | f(*x); + | ^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/unsized-locals/extern-parameter-issue-123887-generic.rs b/tests/ui/unsized-locals/extern-parameter-issue-123887-generic.rs new file mode 100644 index 0000000000000..5ad8a22ed16f5 --- /dev/null +++ b/tests/ui/unsized-locals/extern-parameter-issue-123887-generic.rs @@ -0,0 +1,15 @@ +// https://github.com/rust-lang/rust/issues/123887 +// Do not ICE on unsized extern parameter +//@ compile-flags: -Clink-dead-code --emit=link +#![feature(extern_types, unsized_fn_params)] + +extern "C" { + type ExternType; +} + +fn f(_: impl ?Sized) {} +fn g(x: Box) { + f(*x); //~ ERROR unsized arguments must not be `extern` types +} + +fn main() {} diff --git a/tests/ui/unsized-locals/extern-parameter-issue-123887-generic.stderr b/tests/ui/unsized-locals/extern-parameter-issue-123887-generic.stderr new file mode 100644 index 0000000000000..c2de5f23fd5a7 --- /dev/null +++ b/tests/ui/unsized-locals/extern-parameter-issue-123887-generic.stderr @@ -0,0 +1,8 @@ +error: unsized arguments must not be `extern` types + --> $DIR/extern-parameter-issue-123887-generic.rs:12:5 + | +LL | f(*x); + | ^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/unsized-locals/extern-parameter-issue-123887-wrapped.rs b/tests/ui/unsized-locals/extern-parameter-issue-123887-wrapped.rs new file mode 100644 index 0000000000000..a9d074a7d2673 --- /dev/null +++ b/tests/ui/unsized-locals/extern-parameter-issue-123887-wrapped.rs @@ -0,0 +1,13 @@ +// https://github.com/rust-lang/rust/issues/123887 +// Do not ICE on unsized extern parameter +//@ compile-flags: -Clink-dead-code --emit=link +#![feature(extern_types, unsized_fn_params)] + +extern "C" { + type ExternType; +} + +struct Wrapper(T); +fn f(_: Wrapper) {} //~ ERROR the size for values of type `ExternType` cannot be known at compilation time + +fn main() {} diff --git a/tests/ui/unsized-locals/extern-parameter-issue-123887-wrapped.stderr b/tests/ui/unsized-locals/extern-parameter-issue-123887-wrapped.stderr new file mode 100644 index 0000000000000..cf29ed5c099dc --- /dev/null +++ b/tests/ui/unsized-locals/extern-parameter-issue-123887-wrapped.stderr @@ -0,0 +1,20 @@ +error[E0277]: the size for values of type `ExternType` cannot be known at compilation time + --> $DIR/extern-parameter-issue-123887-wrapped.rs:11:6 + | +LL | fn f(_: Wrapper) {} + | ^ doesn't have a size known at compile-time + | + = help: within `Wrapper`, the trait `Sized` is not implemented for `ExternType`, which is required by `Wrapper: Sized` +note: required because it appears within the type `Wrapper` + --> $DIR/extern-parameter-issue-123887-wrapped.rs:10:8 + | +LL | struct Wrapper(T); + | ^^^^^^^ +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn f(_: &Wrapper) {} + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/unsized-locals/extern-parameter-issue-123887.rs b/tests/ui/unsized-locals/extern-parameter-issue-123887.rs new file mode 100644 index 0000000000000..e3f910c3f82a5 --- /dev/null +++ b/tests/ui/unsized-locals/extern-parameter-issue-123887.rs @@ -0,0 +1,12 @@ +// https://github.com/rust-lang/rust/issues/123887 +// Do not ICE on unsized extern parameter +//@ compile-flags: -Clink-dead-code --emit=link +#![feature(extern_types, unsized_fn_params)] + +extern "C" { + type ExternType; +} + +fn f(_: ExternType) {} //~ ERROR the size for values of type `ExternType` cannot be known at compilation time + +fn main() {} diff --git a/tests/ui/unsized-locals/extern-parameter-issue-123887.stderr b/tests/ui/unsized-locals/extern-parameter-issue-123887.stderr new file mode 100644 index 0000000000000..0ade9081917a6 --- /dev/null +++ b/tests/ui/unsized-locals/extern-parameter-issue-123887.stderr @@ -0,0 +1,15 @@ +error[E0277]: the size for values of type `ExternType` cannot be known at compilation time + --> $DIR/extern-parameter-issue-123887.rs:10:6 + | +LL | fn f(_: ExternType) {} + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `ExternType` +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn f(_: &ExternType) {} + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`.