Suggest borrowing unsized argument types

This commit is contained in:
Esteban Küber 2020-07-10 14:53:48 -07:00
parent c724b67e1b
commit c88409de13
8 changed files with 37 additions and 12 deletions

View file

@ -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<Span>),
/// Return type must be `Sized`.
SizedReturnType,
/// Yield type must be `Sized`.

View file

@ -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),

View file

@ -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");
}
}

View file

@ -487,7 +487,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.require_type_is_sized_deferred(
input,
expr.span,
traits::SizedArgumentType,
traits::SizedArgumentType(None),
);
}
}

View file

@ -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(&param.pat, param_ty, try { inputs_hir?.get(idx)?.span }, false);
let ty_span = try { inputs_hir?.get(idx)?.span };
fcx.check_pat_top(&param.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);

View file

@ -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 <https://doc.rust-lang.org/book/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
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

View file

@ -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 <https://doc.rust-lang.org/book/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
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

View file

@ -6,12 +6,15 @@ LL | fn baz(_: Self::Target) where Self: Deref {}
|
= help: the trait `std::marker::Sized` is not implemented for `<Self as std::ops::Deref>::Target`
= note: to learn more, visit <https://doc.rust-lang.org/book/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
help: consider further restricting the associated type
|
LL | fn baz(_: Self::Target) where Self: Deref, <Self as std::ops::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 <https://doc.rust-lang.org/book/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
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