Skip to content

Commit d989796

Browse files
committed
Suggest borrowing in more unsized fn param cases
1 parent b7db6bb commit d989796

File tree

15 files changed

+80
-49
lines changed

15 files changed

+80
-49
lines changed

src/librustc_ast_lowering/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
526526
Ident::with_dummy_span(sym::_task_context),
527527
hir::BindingAnnotation::Mutable,
528528
);
529-
let param = hir::Param { attrs: &[], hir_id: self.next_id(), pat, span };
529+
let param = hir::Param { attrs: &[], hir_id: self.next_id(), pat, ty_span: span, span };
530530
let params = arena_vec![self; param];
531531

532532
let body_id = self.lower_body(move |this| {

src/librustc_ast_lowering/item.rs

+2
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
972972
attrs: self.lower_attrs(&param.attrs),
973973
hir_id: self.lower_node_id(param.id),
974974
pat: self.lower_pat(&param.pat),
975+
ty_span: param.ty.span,
975976
span: param.span,
976977
}
977978
}
@@ -1098,6 +1099,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10981099
attrs: parameter.attrs,
10991100
hir_id: parameter.hir_id,
11001101
pat: new_parameter_pat,
1102+
ty_span: parameter.ty_span,
11011103
span: parameter.span,
11021104
};
11031105

src/librustc_hir/hir.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2148,6 +2148,7 @@ pub struct Param<'hir> {
21482148
pub attrs: &'hir [Attribute],
21492149
pub hir_id: HirId,
21502150
pub pat: &'hir Pat<'hir>,
2151+
pub ty_span: Span,
21512152
pub span: Span,
21522153
}
21532154

src/librustc_trait_selection/traits/error_reporting/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
403403
}
404404

405405
self.suggest_dereferences(&obligation, &mut err, &trait_ref, points_at_arg);
406-
self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err);
407406
self.suggest_fn_call(&obligation, &mut err, &trait_ref, points_at_arg);
408407
self.suggest_remove_reference(&obligation, &mut err, &trait_ref);
409408
self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref);

src/librustc_trait_selection/traits/error_reporting/suggestions.rs

+31-34
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,6 @@ pub trait InferCtxtExt<'tcx> {
4343
body_id: hir::HirId,
4444
);
4545

46-
fn suggest_borrow_on_unsized_slice(
47-
&self,
48-
code: &ObligationCauseCode<'tcx>,
49-
err: &mut DiagnosticBuilder<'_>,
50-
);
51-
5246
fn suggest_dereferences(
5347
&self,
5448
obligation: &PredicateObligation<'tcx>,
@@ -515,32 +509,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
515509
}
516510
}
517511

518-
/// When encountering an assignment of an unsized trait, like `let x = ""[..];`, provide a
519-
/// suggestion to borrow the initializer in order to use have a slice instead.
520-
fn suggest_borrow_on_unsized_slice(
521-
&self,
522-
code: &ObligationCauseCode<'tcx>,
523-
err: &mut DiagnosticBuilder<'_>,
524-
) {
525-
if let &ObligationCauseCode::VariableType(hir_id) = code {
526-
let parent_node = self.tcx.hir().get_parent_node(hir_id);
527-
if let Some(Node::Local(ref local)) = self.tcx.hir().find(parent_node) {
528-
if let Some(ref expr) = local.init {
529-
if let hir::ExprKind::Index(_, _) = expr.kind {
530-
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
531-
err.span_suggestion(
532-
expr.span,
533-
"consider borrowing here",
534-
format!("&{}", snippet),
535-
Applicability::MachineApplicable,
536-
);
537-
}
538-
}
539-
}
540-
}
541-
}
542-
}
543-
544512
/// Given a closure's `DefId`, return the given name of the closure.
545513
///
546514
/// This doesn't account for reassignments, but it's only used for suggestions.
@@ -1817,8 +1785,37 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
18171785
}
18181786
}
18191787
}
1820-
ObligationCauseCode::VariableType(_) => {
1821-
err.note("all local variables must have a statically known size");
1788+
ObligationCauseCode::VariableType(hir_id) => {
1789+
let parent_node = self.tcx.hir().get_parent_node(hir_id);
1790+
match self.tcx.hir().find(parent_node) {
1791+
Some(Node::Local(hir::Local {
1792+
init: Some(hir::Expr { kind: hir::ExprKind::Index(_, _), span, .. }),
1793+
..
1794+
})) => {
1795+
// When encountering an assignment of an unsized trait, like
1796+
// `let x = ""[..];`, provide a suggestion to borrow the initializer in
1797+
// order to use have a slice instead.
1798+
err.span_suggestion_verbose(
1799+
span.shrink_to_lo(),
1800+
"consider borrowing here",
1801+
"&".to_owned(),
1802+
Applicability::MachineApplicable,
1803+
);
1804+
err.note("all local variables must have a statically known size");
1805+
}
1806+
Some(Node::Param(param)) => {
1807+
err.span_suggestion_verbose(
1808+
param.ty_span.shrink_to_lo(),
1809+
"function arguments must have a statically known size, borrowed types \
1810+
always have a known size",
1811+
"&".to_owned(),
1812+
Applicability::MachineApplicable,
1813+
);
1814+
}
1815+
_ => {
1816+
err.note("all local variables must have a statically known size");
1817+
}
1818+
}
18221819
if !self.tcx.features().unsized_locals {
18231820
err.help("unsized locals are gated as an unstable feature");
18241821
}

src/test/ui/async-await/issue-72590-type-error-sized.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ LL | async fn frob(self) {}
1818
|
1919
= help: within `Foo`, the trait `std::marker::Sized` is not implemented for `str`
2020
= note: required because it appears within the type `Foo`
21-
= note: all local variables must have a statically known size
2221
= help: unsized locals are gated as an unstable feature
22+
help: function arguments must have a statically known size, borrowed types always have a known size
23+
|
24+
LL | async fn frob(&self) {}
25+
| ^
2326

2427
error: aborting due to 3 previous errors
2528

src/test/ui/error-codes/E0277.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ LL | fn f(p: Path) { }
66
|
77
= help: within `std::path::Path`, the trait `std::marker::Sized` is not implemented for `[u8]`
88
= note: required because it appears within the type `std::path::Path`
9-
= note: all local variables 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 f(p: &Path) { }
13+
| ^
1114

1215
error[E0277]: the trait bound `i32: Foo` is not satisfied
1316
--> $DIR/E0277.rs:17:15

src/test/ui/feature-gates/feature-gate-unsized_locals.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ LL | fn f(f: dyn FnOnce()) {}
55
| ^ doesn't have a size known at compile-time
66
|
77
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::FnOnce() + 'static)`
8-
= note: all local variables must have a statically known size
98
= help: unsized locals are gated as an unstable feature
9+
help: function arguments must have a statically known size, borrowed types always have a known size
10+
|
11+
LL | fn f(f: &dyn FnOnce()) {}
12+
| ^
1013

1114
error: aborting due to previous error
1215

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ LL | fn foo(self) -> &'static i32 {
55
| ^^^^ doesn't have a size known at compile-time
66
|
77
= help: the trait `std::marker::Sized` is not implemented for `Self`
8-
= note: all local variables must have a statically known size
98
= help: unsized locals are gated as an unstable feature
109
help: consider further restricting `Self`
1110
|
1211
LL | fn foo(self) -> &'static i32 where Self: std::marker::Sized {
1312
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
13+
help: function arguments must have a statically known size, borrowed types always have a known size
14+
|
15+
LL | fn foo(&self) -> &'static i32 {
16+
| ^
1417

1518
error: aborting due to previous error
1619

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ LL | fn new_struct(r: dyn A + 'static)
55
| ^ doesn't have a size known at compile-time
66
|
77
= help: the trait `std::marker::Sized` is not implemented for `(dyn A + 'static)`
8-
= note: all local variables must have a statically known size
98
= help: unsized locals are gated as an unstable feature
9+
help: function arguments must have a statically known size, borrowed types always have a known size
10+
|
11+
LL | fn new_struct(r: &dyn A + 'static)
12+
| ^
1013

1114
error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time
1215
--> $DIR/issue-5883.rs:8:8

src/test/ui/resolve/issue-5035-2.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ LL | fn foo(_x: K) {}
55
| ^^ doesn't have a size known at compile-time
66
|
77
= help: the trait `std::marker::Sized` is not implemented for `(dyn I + 'static)`
8-
= note: all local variables must have a statically known size
98
= help: unsized locals are gated as an unstable feature
9+
help: function arguments must have a statically known size, borrowed types always have a known size
10+
|
11+
LL | fn foo(_x: &K) {}
12+
| ^
1013

1114
error: aborting due to previous error
1215

src/test/ui/str/str-array-assignment.stderr

+5-3
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
1919
--> $DIR/str-array-assignment.rs:7:7
2020
|
2121
LL | let v = s[..2];
22-
| ^ ------ help: consider borrowing here: `&s[..2]`
23-
| |
24-
| doesn't have a size known at compile-time
22+
| ^ doesn't have a size known at compile-time
2523
|
2624
= help: the trait `std::marker::Sized` is not implemented for `str`
2725
= note: all local variables must have a statically known size
2826
= help: unsized locals are gated as an unstable feature
27+
help: consider borrowing here
28+
|
29+
LL | let v = &s[..2];
30+
| ^
2931

3032
error[E0308]: mismatched types
3133
--> $DIR/str-array-assignment.rs:9:17

src/test/ui/suggestions/path-by-value.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ LL | fn f(p: Path) { }
66
|
77
= help: within `std::path::Path`, the trait `std::marker::Sized` is not implemented for `[u8]`
88
= note: required because it appears within the type `std::path::Path`
9-
= note: all local variables 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 f(p: &Path) { }
13+
| ^
1114

1215
error: aborting due to previous error
1316

src/test/ui/traits/trait-bounds-not-on-bare-trait.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@ LL | fn foo(_x: Foo + Send) {
1313
| ^^ doesn't have a size known at compile-time
1414
|
1515
= help: the trait `std::marker::Sized` is not implemented for `(dyn Foo + std::marker::Send + 'static)`
16-
= note: all local variables must have a statically known size
1716
= help: unsized locals are gated as an unstable feature
17+
help: function arguments must have a statically known size, borrowed types always have a known size
18+
|
19+
LL | fn foo(_x: &Foo + Send) {
20+
| ^
1821

1922
error: aborting due to previous error; 1 warning emitted
2023

src/test/ui/unsized6.stderr

+8-2
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,11 @@ LL | fn g1<X: ?Sized>(x: X) {}
144144
| this type parameter needs to be `std::marker::Sized`
145145
|
146146
= help: the trait `std::marker::Sized` is not implemented for `X`
147-
= note: all local variables must have a statically known size
148147
= help: unsized locals are gated as an unstable feature
148+
help: function arguments must have a statically known size, borrowed types always have a known size
149+
|
150+
LL | fn g1<X: ?Sized>(x: &X) {}
151+
| ^
149152

150153
error[E0277]: the size for values of type `X` cannot be known at compilation time
151154
--> $DIR/unsized6.rs:40:22
@@ -156,8 +159,11 @@ LL | fn g2<X: ?Sized + T>(x: X) {}
156159
| this type parameter needs to be `std::marker::Sized`
157160
|
158161
= help: the trait `std::marker::Sized` is not implemented for `X`
159-
= note: all local variables must have a statically known size
160162
= help: unsized locals are gated as an unstable feature
163+
help: function arguments must have a statically known size, borrowed types always have a known size
164+
|
165+
LL | fn g2<X: ?Sized + T>(x: &X) {}
166+
| ^
161167

162168
error: aborting due to 13 previous errors
163169

0 commit comments

Comments
 (0)