Skip to content

Commit 882fe19

Browse files
committed
Suggest returning a reference for unsized place from a closure
1 parent 1d05e3c commit 882fe19

File tree

4 files changed

+158
-0
lines changed

4 files changed

+158
-0
lines changed

compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3307,6 +3307,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
33073307
}
33083308
ObligationCauseCode::SizedReturnType | ObligationCauseCode::SizedCallReturnType => {
33093309
err.note("the return type of a function must have a statically known size");
3310+
if let Some(node_body_id) = tcx.hir_node_by_def_id(body_id).body_id()
3311+
&& let body = tcx.hir_body(node_body_id)
3312+
&& let hir::Node::Expr(closure_expr) = tcx.hir_node_by_def_id(body_id)
3313+
&& let hir::ExprKind::Closure(closure) = closure_expr.kind
3314+
&& let hir::FnRetTy::DefaultReturn(_) = closure.fn_decl.output
3315+
{
3316+
err.span_suggestion_verbose(
3317+
body.value.span.shrink_to_lo(),
3318+
"consider borrowing the value",
3319+
"&",
3320+
Applicability::MaybeIncorrect,
3321+
);
3322+
}
33103323
}
33113324
ObligationCauseCode::SizedYieldType => {
33123325
err.note("the yield type of a coroutine must have a statically known size");
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#![allow(unused_variables, for_loops_over_fallibles)]
2+
//@ run-rustfix
3+
4+
fn main() {
5+
// Basic case from the issue: str slice
6+
let o = Some("Hello, world!");
7+
for s in o.map(|s| &s[3..8]) {}
8+
//~^ ERROR the size for values of type `str` cannot be known at compilation time
9+
//~| ERROR the size for values of type `str` cannot be known at compilation time
10+
//~| ERROR the size for values of type `str` cannot be known at compilation time
11+
//~| ERROR `Option<str>` is not an iterator
12+
13+
// Byte slice case
14+
let arr = Some(b"Hello, world!");
15+
for s in arr.map(|s| &s[3..8]) {}
16+
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
17+
//~| ERROR the size for values of type `[u8]` cannot be known at compilation time
18+
//~| ERROR the size for values of type `[u8]` cannot be known at compilation time
19+
//~| ERROR `Option<[u8]>` is not an iterator
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#![allow(unused_variables, for_loops_over_fallibles)]
2+
//@ run-rustfix
3+
4+
fn main() {
5+
// Basic case from the issue: str slice
6+
let o = Some("Hello, world!");
7+
for s in o.map(|s| s[3..8]) {}
8+
//~^ ERROR the size for values of type `str` cannot be known at compilation time
9+
//~| ERROR the size for values of type `str` cannot be known at compilation time
10+
//~| ERROR the size for values of type `str` cannot be known at compilation time
11+
//~| ERROR `Option<str>` is not an iterator
12+
13+
// Byte slice case
14+
let arr = Some(b"Hello, world!");
15+
for s in arr.map(|s| s[3..8]) {}
16+
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
17+
//~| ERROR the size for values of type `[u8]` cannot be known at compilation time
18+
//~| ERROR the size for values of type `[u8]` cannot be known at compilation time
19+
//~| ERROR `Option<[u8]>` is not an iterator
20+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
error[E0277]: the size for values of type `str` cannot be known at compilation time
2+
--> $DIR/unsized-return-suggest-ref-issue-152064.rs:7:16
3+
|
4+
LL | for s in o.map(|s| s[3..8]) {}
5+
| ^^^ doesn't have a size known at compile-time
6+
|
7+
= help: the trait `Sized` is not implemented for `str`
8+
note: required by an implicit `Sized` bound in `Option::<T>::map`
9+
--> $SRC_DIR/core/src/option.rs:LL:COL
10+
11+
error[E0277]: the size for values of type `str` cannot be known at compilation time
12+
--> $DIR/unsized-return-suggest-ref-issue-152064.rs:7:24
13+
|
14+
LL | for s in o.map(|s| s[3..8]) {}
15+
| ^^^^^^^ doesn't have a size known at compile-time
16+
|
17+
= help: the trait `Sized` is not implemented for `str`
18+
= note: the return type of a function must have a statically known size
19+
help: consider borrowing the value
20+
|
21+
LL | for s in o.map(|s| &s[3..8]) {}
22+
| +
23+
24+
error[E0277]: the size for values of type `str` cannot be known at compilation time
25+
--> $DIR/unsized-return-suggest-ref-issue-152064.rs:7:14
26+
|
27+
LL | for s in o.map(|s| s[3..8]) {}
28+
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
29+
|
30+
= help: the trait `Sized` is not implemented for `str`
31+
note: required by an implicit `Sized` bound in `Option`
32+
--> $SRC_DIR/core/src/option.rs:LL:COL
33+
34+
error[E0277]: `Option<str>` is not an iterator
35+
--> $DIR/unsized-return-suggest-ref-issue-152064.rs:7:14
36+
|
37+
LL | for s in o.map(|s| s[3..8]) {}
38+
| ^^^^^^^^^^^^^^^^^^ `Option<str>` is not an iterator
39+
|
40+
= help: the trait `IntoIterator` is not implemented for `Option<str>`
41+
help: the following other types implement trait `IntoIterator`
42+
--> $SRC_DIR/core/src/option.rs:LL:COL
43+
|
44+
= note: `Option<T>`
45+
::: $SRC_DIR/core/src/option.rs:LL:COL
46+
|
47+
= note: `&Option<T>`
48+
::: $SRC_DIR/core/src/option.rs:LL:COL
49+
|
50+
= note: `&mut Option<T>`
51+
52+
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
53+
--> $DIR/unsized-return-suggest-ref-issue-152064.rs:15:18
54+
|
55+
LL | for s in arr.map(|s| s[3..8]) {}
56+
| ^^^ doesn't have a size known at compile-time
57+
|
58+
= help: the trait `Sized` is not implemented for `[u8]`
59+
note: required by an implicit `Sized` bound in `Option::<T>::map`
60+
--> $SRC_DIR/core/src/option.rs:LL:COL
61+
62+
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
63+
--> $DIR/unsized-return-suggest-ref-issue-152064.rs:15:26
64+
|
65+
LL | for s in arr.map(|s| s[3..8]) {}
66+
| ^^^^^^^ doesn't have a size known at compile-time
67+
|
68+
= help: the trait `Sized` is not implemented for `[u8]`
69+
= note: the return type of a function must have a statically known size
70+
help: consider borrowing the value
71+
|
72+
LL | for s in arr.map(|s| &s[3..8]) {}
73+
| +
74+
75+
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
76+
--> $DIR/unsized-return-suggest-ref-issue-152064.rs:15:14
77+
|
78+
LL | for s in arr.map(|s| s[3..8]) {}
79+
| ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
80+
|
81+
= help: the trait `Sized` is not implemented for `[u8]`
82+
note: required by an implicit `Sized` bound in `Option`
83+
--> $SRC_DIR/core/src/option.rs:LL:COL
84+
85+
error[E0277]: `Option<[u8]>` is not an iterator
86+
--> $DIR/unsized-return-suggest-ref-issue-152064.rs:15:14
87+
|
88+
LL | for s in arr.map(|s| s[3..8]) {}
89+
| ^^^^^^^^^^^^^^^^^^^^ `Option<[u8]>` is not an iterator
90+
|
91+
= help: the trait `IntoIterator` is not implemented for `Option<[u8]>`
92+
help: the following other types implement trait `IntoIterator`
93+
--> $SRC_DIR/core/src/option.rs:LL:COL
94+
|
95+
= note: `Option<T>`
96+
::: $SRC_DIR/core/src/option.rs:LL:COL
97+
|
98+
= note: `&Option<T>`
99+
::: $SRC_DIR/core/src/option.rs:LL:COL
100+
|
101+
= note: `&mut Option<T>`
102+
103+
error: aborting due to 8 previous errors
104+
105+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)