From b7095f55721645cbc73027792c00844734f0f2a3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 23 May 2023 17:57:08 +0000 Subject: [PATCH 1/2] Don't ICE on unsized rust-call abi call --- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 8 +++++++- compiler/rustc_hir_typeck/src/callee.rs | 1 + tests/ui/unsized-locals/rust-call.rs | 12 ++++++++++++ tests/ui/unsized-locals/rust-call.stderr | 12 ++++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 tests/ui/unsized-locals/rust-call.rs create mode 100644 tests/ui/unsized-locals/rust-call.stderr diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 69e32c35ed8d3..f489a1fb3e501 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1449,7 +1449,7 @@ fn check_fn_or_method<'tcx>( let span = tcx.def_span(def_id); let has_implicit_self = hir_decl.implicit_self != hir::ImplicitSelfKind::None; let mut inputs = sig.inputs().iter().skip(if has_implicit_self { 1 } else { 0 }); - // Check that the argument is a tuple + // Check that the argument is a tuple and is sized if let Some(ty) = inputs.next() { wfcx.register_bound( ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall), @@ -1457,6 +1457,12 @@ fn check_fn_or_method<'tcx>( *ty, tcx.require_lang_item(hir::LangItem::Tuple, Some(span)), ); + wfcx.register_bound( + ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall), + wfcx.param_env, + *ty, + tcx.require_lang_item(hir::LangItem::Sized, Some(span)), + ); } else { tcx.sess.span_err( hir_decl.inputs.last().map_or(span, |input| input.span), diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 4389ad6ef2678..9da72aae77660 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -470,6 +470,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.require_lang_item(hir::LangItem::Tuple, Some(sp)), traits::ObligationCause::new(sp, self.body_id, traits::RustCall), ); + self.require_type_is_sized(ty, sp, traits::RustCall); } else { self.tcx.sess.span_err( sp, diff --git a/tests/ui/unsized-locals/rust-call.rs b/tests/ui/unsized-locals/rust-call.rs new file mode 100644 index 0000000000000..ff4075aa4c03c --- /dev/null +++ b/tests/ui/unsized-locals/rust-call.rs @@ -0,0 +1,12 @@ +#![feature(unsized_tuple_coercion)] +#![feature(unboxed_closures)] +#![feature(unsized_fn_params)] + +fn bad() -> extern "rust-call" fn(([u8],)) { todo!() } + +fn main() { + let f = bad(); + let slice: Box<([u8],)> = Box::new(([1; 8],)); + f(*slice); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time +} diff --git a/tests/ui/unsized-locals/rust-call.stderr b/tests/ui/unsized-locals/rust-call.stderr new file mode 100644 index 0000000000000..7cc021f5741db --- /dev/null +++ b/tests/ui/unsized-locals/rust-call.stderr @@ -0,0 +1,12 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/rust-call.rs:10:7 + | +LL | f(*slice); + | ^^^^^^ doesn't have a size known at compile-time + | + = help: within `([u8],)`, the trait `Sized` is not implemented for `[u8]` + = note: required because it appears within the type `([u8],)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From b95ea45a60faac4219226d13f9c6c7fffd0b8cef Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 23 May 2023 18:15:00 +0000 Subject: [PATCH 2/2] Note why rust-call abi requires sized obl --- .../src/traits/error_reporting/suggestions.rs | 8 +++++++- tests/ui/unsized-locals/rust-call.stderr | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 80d0faca670a7..2937d9509f8d2 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2663,9 +2663,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { | ObligationCauseCode::LetElse | ObligationCauseCode::BinOp { .. } | ObligationCauseCode::AscribeUserTypeProvePredicate(..) - | ObligationCauseCode::RustCall | ObligationCauseCode::DropImpl | ObligationCauseCode::ConstParam(_) => {} + ObligationCauseCode::RustCall => { + if let Some(pred) = predicate.to_opt_poly_trait_pred() + && Some(pred.def_id()) == self.tcx.lang_items().sized_trait() + { + err.note("argument required to be sized due to `extern \"rust-call\"` ABI"); + } + } ObligationCauseCode::SliceOrArrayElem => { err.note("slice and array elements must have `Sized` type"); } diff --git a/tests/ui/unsized-locals/rust-call.stderr b/tests/ui/unsized-locals/rust-call.stderr index 7cc021f5741db..fff7ef75b3322 100644 --- a/tests/ui/unsized-locals/rust-call.stderr +++ b/tests/ui/unsized-locals/rust-call.stderr @@ -6,6 +6,7 @@ LL | f(*slice); | = help: within `([u8],)`, the trait `Sized` is not implemented for `[u8]` = note: required because it appears within the type `([u8],)` + = note: argument required to be sized due to `extern "rust-call"` ABI error: aborting due to previous error