mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
Suggest borrowing in more unsized fn param cases
This commit is contained in:
parent
b7db6bb5af
commit
d989796b47
@ -526,7 +526,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
Ident::with_dummy_span(sym::_task_context),
|
||||
hir::BindingAnnotation::Mutable,
|
||||
);
|
||||
let param = hir::Param { attrs: &[], hir_id: self.next_id(), pat, span };
|
||||
let param = hir::Param { attrs: &[], hir_id: self.next_id(), pat, ty_span: span, span };
|
||||
let params = arena_vec![self; param];
|
||||
|
||||
let body_id = self.lower_body(move |this| {
|
||||
|
@ -972,6 +972,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
attrs: self.lower_attrs(¶m.attrs),
|
||||
hir_id: self.lower_node_id(param.id),
|
||||
pat: self.lower_pat(¶m.pat),
|
||||
ty_span: param.ty.span,
|
||||
span: param.span,
|
||||
}
|
||||
}
|
||||
@ -1098,6 +1099,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
attrs: parameter.attrs,
|
||||
hir_id: parameter.hir_id,
|
||||
pat: new_parameter_pat,
|
||||
ty_span: parameter.ty_span,
|
||||
span: parameter.span,
|
||||
};
|
||||
|
||||
|
@ -2148,6 +2148,7 @@ pub struct Param<'hir> {
|
||||
pub attrs: &'hir [Attribute],
|
||||
pub hir_id: HirId,
|
||||
pub pat: &'hir Pat<'hir>,
|
||||
pub ty_span: Span,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
|
@ -403,7 +403,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
self.suggest_dereferences(&obligation, &mut err, &trait_ref, points_at_arg);
|
||||
self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err);
|
||||
self.suggest_fn_call(&obligation, &mut err, &trait_ref, points_at_arg);
|
||||
self.suggest_remove_reference(&obligation, &mut err, &trait_ref);
|
||||
self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref);
|
||||
|
@ -43,12 +43,6 @@ pub trait InferCtxtExt<'tcx> {
|
||||
body_id: hir::HirId,
|
||||
);
|
||||
|
||||
fn suggest_borrow_on_unsized_slice(
|
||||
&self,
|
||||
code: &ObligationCauseCode<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
);
|
||||
|
||||
fn suggest_dereferences(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
@ -515,32 +509,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// When encountering an assignment of an unsized trait, like `let x = ""[..];`, provide a
|
||||
/// suggestion to borrow the initializer in order to use have a slice instead.
|
||||
fn suggest_borrow_on_unsized_slice(
|
||||
&self,
|
||||
code: &ObligationCauseCode<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
) {
|
||||
if let &ObligationCauseCode::VariableType(hir_id) = code {
|
||||
let parent_node = self.tcx.hir().get_parent_node(hir_id);
|
||||
if let Some(Node::Local(ref local)) = self.tcx.hir().find(parent_node) {
|
||||
if let Some(ref expr) = local.init {
|
||||
if let hir::ExprKind::Index(_, _) = expr.kind {
|
||||
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
|
||||
err.span_suggestion(
|
||||
expr.span,
|
||||
"consider borrowing here",
|
||||
format!("&{}", snippet),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a closure's `DefId`, return the given name of the closure.
|
||||
///
|
||||
/// 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> {
|
||||
}
|
||||
}
|
||||
}
|
||||
ObligationCauseCode::VariableType(_) => {
|
||||
err.note("all local variables must have a statically known size");
|
||||
ObligationCauseCode::VariableType(hir_id) => {
|
||||
let parent_node = self.tcx.hir().get_parent_node(hir_id);
|
||||
match self.tcx.hir().find(parent_node) {
|
||||
Some(Node::Local(hir::Local {
|
||||
init: Some(hir::Expr { kind: hir::ExprKind::Index(_, _), span, .. }),
|
||||
..
|
||||
})) => {
|
||||
// When encountering an assignment of an unsized trait, like
|
||||
// `let x = ""[..];`, provide a suggestion to borrow the initializer in
|
||||
// order to use have a slice instead.
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_lo(),
|
||||
"consider borrowing here",
|
||||
"&".to_owned(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.note("all local variables must have a statically known size");
|
||||
}
|
||||
Some(Node::Param(param)) => {
|
||||
err.span_suggestion_verbose(
|
||||
param.ty_span.shrink_to_lo(),
|
||||
"function arguments must have a statically known size, borrowed types \
|
||||
always have a known size",
|
||||
"&".to_owned(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
err.note("all local variables must have a statically known size");
|
||||
}
|
||||
}
|
||||
if !self.tcx.features().unsized_locals {
|
||||
err.help("unsized locals are gated as an unstable feature");
|
||||
}
|
||||
|
@ -18,8 +18,11 @@ LL | async fn frob(self) {}
|
||||
|
|
||||
= help: within `Foo`, the trait `std::marker::Sized` is not implemented for `str`
|
||||
= note: required because it appears within the type `Foo`
|
||||
= note: all local variables 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 | async fn frob(&self) {}
|
||||
| ^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -6,8 +6,11 @@ LL | fn f(p: Path) { }
|
||||
|
|
||||
= help: within `std::path::Path`, the trait `std::marker::Sized` is not implemented for `[u8]`
|
||||
= note: required because it appears within the type `std::path::Path`
|
||||
= note: all local variables 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 f(p: &Path) { }
|
||||
| ^
|
||||
|
||||
error[E0277]: the trait bound `i32: Foo` is not satisfied
|
||||
--> $DIR/E0277.rs:17:15
|
||||
|
@ -5,8 +5,11 @@ LL | fn f(f: dyn FnOnce()) {}
|
||||
| ^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::FnOnce() + 'static)`
|
||||
= note: all local variables 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 f(f: &dyn FnOnce()) {}
|
||||
| ^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -5,12 +5,15 @@ LL | fn foo(self) -> &'static i32 {
|
||||
| ^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `std::marker::Sized` is not implemented for `Self`
|
||||
= note: all local variables must have a statically known size
|
||||
= help: unsized locals are gated as an unstable feature
|
||||
help: consider further restricting `Self`
|
||||
|
|
||||
LL | fn foo(self) -> &'static i32 where Self: std::marker::Sized {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: function arguments must have a statically known size, borrowed types always have a known size
|
||||
|
|
||||
LL | fn foo(&self) -> &'static i32 {
|
||||
| ^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -5,8 +5,11 @@ LL | fn new_struct(r: dyn A + 'static)
|
||||
| ^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `std::marker::Sized` is not implemented for `(dyn A + 'static)`
|
||||
= note: all local variables 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 new_struct(r: &dyn A + 'static)
|
||||
| ^
|
||||
|
||||
error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time
|
||||
--> $DIR/issue-5883.rs:8:8
|
||||
|
@ -5,8 +5,11 @@ LL | fn foo(_x: K) {}
|
||||
| ^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `std::marker::Sized` is not implemented for `(dyn I + 'static)`
|
||||
= note: all local variables 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 foo(_x: &K) {}
|
||||
| ^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -19,13 +19,15 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
|
||||
--> $DIR/str-array-assignment.rs:7:7
|
||||
|
|
||||
LL | let v = s[..2];
|
||||
| ^ ------ help: consider borrowing here: `&s[..2]`
|
||||
| |
|
||||
| doesn't have a size known at compile-time
|
||||
| ^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `std::marker::Sized` is not implemented for `str`
|
||||
= note: all local variables must have a statically known size
|
||||
= help: unsized locals are gated as an unstable feature
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | let v = &s[..2];
|
||||
| ^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/str-array-assignment.rs:9:17
|
||||
|
@ -6,8 +6,11 @@ LL | fn f(p: Path) { }
|
||||
|
|
||||
= help: within `std::path::Path`, the trait `std::marker::Sized` is not implemented for `[u8]`
|
||||
= note: required because it appears within the type `std::path::Path`
|
||||
= note: all local variables 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 f(p: &Path) { }
|
||||
| ^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -13,8 +13,11 @@ LL | fn foo(_x: Foo + Send) {
|
||||
| ^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `std::marker::Sized` is not implemented for `(dyn Foo + std::marker::Send + 'static)`
|
||||
= note: all local variables 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 foo(_x: &Foo + Send) {
|
||||
| ^
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
|
@ -144,8 +144,11 @@ LL | fn g1<X: ?Sized>(x: X) {}
|
||||
| this type parameter needs to be `std::marker::Sized`
|
||||
|
|
||||
= help: the trait `std::marker::Sized` is not implemented for `X`
|
||||
= note: all local variables 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 g1<X: ?Sized>(x: &X) {}
|
||||
| ^
|
||||
|
||||
error[E0277]: the size for values of type `X` cannot be known at compilation time
|
||||
--> $DIR/unsized6.rs:40:22
|
||||
@ -156,8 +159,11 @@ LL | fn g2<X: ?Sized + T>(x: X) {}
|
||||
| this type parameter needs to be `std::marker::Sized`
|
||||
|
|
||||
= help: the trait `std::marker::Sized` is not implemented for `X`
|
||||
= note: all local variables 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 g2<X: ?Sized + T>(x: &X) {}
|
||||
| ^
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user