diff --git a/src/librustc_middle/traits/mod.rs b/src/librustc_middle/traits/mod.rs index fc37cb2504da..db81dc19c08f 100644 --- a/src/librustc_middle/traits/mod.rs +++ b/src/librustc_middle/traits/mod.rs @@ -215,7 +215,7 @@ pub enum ObligationCauseCode<'tcx> { /// Type of each variable must be `Sized`. VariableType(hir::HirId), /// Argument type must be `Sized`. - SizedArgumentType, + SizedArgumentType(Option), /// Return type must be `Sized`. SizedReturnType, /// Yield type must be `Sized`. diff --git a/src/librustc_middle/traits/structural_impls.rs b/src/librustc_middle/traits/structural_impls.rs index faaa576f1790..e2a0e3dfa305 100644 --- a/src/librustc_middle/traits/structural_impls.rs +++ b/src/librustc_middle/traits/structural_impls.rs @@ -151,7 +151,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { super::VariableType(id) => Some(super::VariableType(id)), super::ReturnValue(id) => Some(super::ReturnValue(id)), super::ReturnType => Some(super::ReturnType), - super::SizedArgumentType => Some(super::SizedArgumentType), + super::SizedArgumentType(sp) => Some(super::SizedArgumentType(sp)), super::SizedReturnType => Some(super::SizedReturnType), super::SizedYieldType => Some(super::SizedYieldType), super::InlineAsmSized => Some(super::InlineAsmSized), diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index d677d84b2ba1..3c3b5bdf59cc 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -1823,9 +1823,21 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err.help("unsized locals are gated as an unstable feature"); } } - ObligationCauseCode::SizedArgumentType => { - err.note("all function arguments must have a statically known size"); - if !self.tcx.features().unsized_locals { + ObligationCauseCode::SizedArgumentType(sp) => { + if let Some(span) = sp { + err.span_suggestion_verbose( + span.shrink_to_lo(), + "function arguments must have a statically known size, borrowed types \ + always have a known size", + "&".to_string(), + Applicability::MachineApplicable, + ); + } else { + err.note("all function arguments must have a statically known size"); + } + if tcx.sess.opts.unstable_features.is_nightly_build() + && !self.tcx.features().unsized_locals + { err.help("unsized locals are gated as an unstable feature"); } } diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index e6b51f4c2cd2..3956e91a1673 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -487,7 +487,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.require_type_is_sized_deferred( input, expr.span, - traits::SizedArgumentType, + traits::SizedArgumentType(None), ); } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index fa7360ce9005..aa768f1d251b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1342,14 +1342,15 @@ fn check_fn<'a, 'tcx>( let inputs_fn = fn_sig.inputs().iter().copied(); for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() { // Check the pattern. - fcx.check_pat_top(¶m.pat, param_ty, try { inputs_hir?.get(idx)?.span }, false); + let ty_span = try { inputs_hir?.get(idx)?.span }; + fcx.check_pat_top(¶m.pat, param_ty, ty_span, false); // Check that argument is Sized. // The check for a non-trivial pattern is a hack to avoid duplicate warnings // for simple cases like `fn foo(x: Trait)`, // where we would error once on the parameter as a whole, and once on the binding `x`. if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals { - fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType); + fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType(ty_span)); } fcx.write_ty(param.hir_id, param_ty); diff --git a/src/test/ui/issues/issue-38954.stderr b/src/test/ui/issues/issue-38954.stderr index d3168ef9e4aa..93133bc94bbc 100644 --- a/src/test/ui/issues/issue-38954.stderr +++ b/src/test/ui/issues/issue-38954.stderr @@ -6,8 +6,11 @@ LL | fn _test(ref _p: str) {} | = help: the trait `std::marker::Sized` is not implemented for `str` = note: to learn more, visit - = note: all function arguments must have a statically known size = help: unsized locals are gated as an unstable feature +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn _test(ref _p: &str) {} + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-41229-ref-str.stderr b/src/test/ui/issues/issue-41229-ref-str.stderr index 9d854e4be9ea..1b908ca49de4 100644 --- a/src/test/ui/issues/issue-41229-ref-str.stderr +++ b/src/test/ui/issues/issue-41229-ref-str.stderr @@ -6,8 +6,11 @@ LL | pub fn example(ref s: str) {} | = help: the trait `std::marker::Sized` is not implemented for `str` = note: to learn more, visit - = note: all function arguments must have a statically known size = help: unsized locals are gated as an unstable feature +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | pub fn example(ref s: &str) {} + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-42312.stderr b/src/test/ui/issues/issue-42312.stderr index 0d4797a7a067..58eb3afee81d 100644 --- a/src/test/ui/issues/issue-42312.stderr +++ b/src/test/ui/issues/issue-42312.stderr @@ -6,12 +6,15 @@ LL | fn baz(_: Self::Target) where Self: Deref {} | = help: the trait `std::marker::Sized` is not implemented for `::Target` = note: to learn more, visit - = note: all function arguments must have a statically known size = help: unsized locals are gated as an unstable feature help: consider further restricting the associated type | LL | fn baz(_: Self::Target) where Self: Deref, ::Target: std::marker::Sized {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn baz(_: &Self::Target) where Self: Deref {} + | ^ error[E0277]: the size for values of type `(dyn std::string::ToString + 'static)` cannot be known at compilation time --> $DIR/issue-42312.rs:8:10 @@ -21,8 +24,11 @@ LL | pub fn f(_: dyn ToString) {} | = help: the trait `std::marker::Sized` is not implemented for `(dyn std::string::ToString + 'static)` = note: to learn more, visit - = note: all function arguments must have a statically known size = help: unsized locals are gated as an unstable feature +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | pub fn f(_: &dyn ToString) {} + | ^ error: aborting due to 2 previous errors