Skip to content

Commit fe1d758

Browse files
committed
Suggest borrowing unsized argument types
1 parent e59b08e commit fe1d758

File tree

8 files changed

+37
-12
lines changed

8 files changed

+37
-12
lines changed

src/librustc_middle/traits/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ pub enum ObligationCauseCode<'tcx> {
215215
/// Type of each variable must be `Sized`.
216216
VariableType(hir::HirId),
217217
/// Argument type must be `Sized`.
218-
SizedArgumentType,
218+
SizedArgumentType(Option<Span>),
219219
/// Return type must be `Sized`.
220220
SizedReturnType,
221221
/// Yield type must be `Sized`.

src/librustc_middle/traits/structural_impls.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
151151
super::VariableType(id) => Some(super::VariableType(id)),
152152
super::ReturnValue(id) => Some(super::ReturnValue(id)),
153153
super::ReturnType => Some(super::ReturnType),
154-
super::SizedArgumentType => Some(super::SizedArgumentType),
154+
super::SizedArgumentType(sp) => Some(super::SizedArgumentType(sp)),
155155
super::SizedReturnType => Some(super::SizedReturnType),
156156
super::SizedYieldType => Some(super::SizedYieldType),
157157
super::InlineAsmSized => Some(super::InlineAsmSized),

src/librustc_trait_selection/traits/error_reporting/suggestions.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1823,9 +1823,21 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
18231823
err.help("unsized locals are gated as an unstable feature");
18241824
}
18251825
}
1826-
ObligationCauseCode::SizedArgumentType => {
1827-
err.note("all function arguments must have a statically known size");
1828-
if !self.tcx.features().unsized_locals {
1826+
ObligationCauseCode::SizedArgumentType(sp) => {
1827+
if let Some(span) = sp {
1828+
err.span_suggestion_verbose(
1829+
span.shrink_to_lo(),
1830+
"function arguments must have a statically known size, borrowed types \
1831+
always have a known size",
1832+
"&".to_string(),
1833+
Applicability::MachineApplicable,
1834+
);
1835+
} else {
1836+
err.note("all function arguments must have a statically known size");
1837+
}
1838+
if tcx.sess.opts.unstable_features.is_nightly_build()
1839+
&& !self.tcx.features().unsized_locals
1840+
{
18291841
err.help("unsized locals are gated as an unstable feature");
18301842
}
18311843
}

src/librustc_typeck/check/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
487487
self.require_type_is_sized_deferred(
488488
input,
489489
expr.span,
490-
traits::SizedArgumentType,
490+
traits::SizedArgumentType(None),
491491
);
492492
}
493493
}

src/librustc_typeck/check/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,14 +1342,15 @@ fn check_fn<'a, 'tcx>(
13421342
let inputs_fn = fn_sig.inputs().iter().copied();
13431343
for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
13441344
// Check the pattern.
1345-
fcx.check_pat_top(&param.pat, param_ty, try { inputs_hir?.get(idx)?.span }, false);
1345+
let ty_span = try { inputs_hir?.get(idx)?.span };
1346+
fcx.check_pat_top(&param.pat, param_ty, ty_span, false);
13461347

13471348
// Check that argument is Sized.
13481349
// The check for a non-trivial pattern is a hack to avoid duplicate warnings
13491350
// for simple cases like `fn foo(x: Trait)`,
13501351
// where we would error once on the parameter as a whole, and once on the binding `x`.
13511352
if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
1352-
fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType);
1353+
fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType(ty_span));
13531354
}
13541355

13551356
fcx.write_ty(param.hir_id, param_ty);

src/test/ui/issues/issue-38954.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ LL | fn _test(ref _p: str) {}
66
|
77
= help: the trait `std::marker::Sized` is not implemented for `str`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
9-
= note: all function arguments must have a statically known size
109
= help: unsized locals are gated as an unstable feature
10+
help: function arguments must have a statically known size, borrowed types always have a known size
11+
|
12+
LL | fn _test(ref _p: &str) {}
13+
| ^
1114

1215
error: aborting due to previous error
1316

src/test/ui/issues/issue-41229-ref-str.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ LL | pub fn example(ref s: str) {}
66
|
77
= help: the trait `std::marker::Sized` is not implemented for `str`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
9-
= note: all function arguments must have a statically known size
109
= help: unsized locals are gated as an unstable feature
10+
help: function arguments must have a statically known size, borrowed types always have a known size
11+
|
12+
LL | pub fn example(ref s: &str) {}
13+
| ^
1114

1215
error: aborting due to previous error
1316

src/test/ui/issues/issue-42312.stderr

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@ LL | fn baz(_: Self::Target) where Self: Deref {}
66
|
77
= help: the trait `std::marker::Sized` is not implemented for `<Self as std::ops::Deref>::Target`
88
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
9-
= note: all function arguments must have a statically known size
109
= help: unsized locals are gated as an unstable feature
1110
help: consider further restricting the associated type
1211
|
1312
LL | fn baz(_: Self::Target) where Self: Deref, <Self as std::ops::Deref>::Target: std::marker::Sized {}
1413
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14+
help: function arguments must have a statically known size, borrowed types always have a known size
15+
|
16+
LL | fn baz(_: &Self::Target) where Self: Deref {}
17+
| ^
1518

1619
error[E0277]: the size for values of type `(dyn std::string::ToString + 'static)` cannot be known at compilation time
1720
--> $DIR/issue-42312.rs:8:10
@@ -21,8 +24,11 @@ LL | pub fn f(_: dyn ToString) {}
2124
|
2225
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::string::ToString + 'static)`
2326
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
24-
= note: all function arguments must have a statically known size
2527
= help: unsized locals are gated as an unstable feature
28+
help: function arguments must have a statically known size, borrowed types always have a known size
29+
|
30+
LL | pub fn f(_: &dyn ToString) {}
31+
| ^
2632

2733
error: aborting due to 2 previous errors
2834

0 commit comments

Comments
 (0)