Account for multiple trait bounds in bare trait object suggestion
Note the parentheses in the last suggestion: ``` error[E0277]: the size for values of type `(dyn Foo + Send + 'static)` cannot be known at compilation time --> $DIR/not-on-bare-trait.rs:7:8 | LL | fn foo(_x: Foo + Send) { | ^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Foo + Send + 'static)` = help: unsized fn params are gated as an unstable feature help: you can use `impl Trait` as the argument type | LL | fn foo(_x: impl Foo + Send) { | ++++ help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn foo(_x: &(Foo + Send)) { | ++ + ```
This commit is contained in:
parent
0487500776
commit
8551cab7b7
@ -3202,9 +3202,10 @@ fn note_obligation_cause_code<T>(
|
||||
}
|
||||
ObligationCauseCode::SizedArgumentType(ty_span) => {
|
||||
if let Some(span) = ty_span {
|
||||
if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder()
|
||||
let trait_len = if let ty::PredicateKind::Clause(clause) =
|
||||
predicate.kind().skip_binder()
|
||||
&& let ty::ClauseKind::Trait(trait_pred) = clause
|
||||
&& let ty::Dynamic(..) = trait_pred.self_ty().kind()
|
||||
&& let ty::Dynamic(preds, ..) = trait_pred.self_ty().kind()
|
||||
{
|
||||
let span = if let Ok(snippet) =
|
||||
self.tcx.sess.source_map().span_to_snippet(span)
|
||||
@ -3221,12 +3222,39 @@ fn note_obligation_cause_code<T>(
|
||||
"impl ".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_lo(),
|
||||
preds
|
||||
.iter()
|
||||
.filter(|pred| {
|
||||
// We only want to count `dyn Foo + Bar`, not `dyn Foo<Bar>`,
|
||||
// because the later doesn't need parentheses.
|
||||
matches!(
|
||||
pred.skip_binder(),
|
||||
ty::ExistentialPredicate::Trait(_)
|
||||
| ty::ExistentialPredicate::AutoTrait(_)
|
||||
)
|
||||
})
|
||||
.count()
|
||||
} else {
|
||||
1
|
||||
};
|
||||
let sugg = if trait_len == 1 {
|
||||
vec![(span.shrink_to_lo(), "&".to_string())]
|
||||
} else if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
|
||||
&& snippet.starts_with('(')
|
||||
{
|
||||
// We don't want to suggest `&((dyn Foo + Bar))` when we have
|
||||
// `(dyn Foo + Bar)`.
|
||||
vec![(span.shrink_to_lo(), "&".to_string())]
|
||||
} else {
|
||||
vec![
|
||||
(span.shrink_to_lo(), "&(".to_string()),
|
||||
(span.shrink_to_hi(), ")".to_string()),
|
||||
]
|
||||
};
|
||||
err.multipart_suggestion_verbose(
|
||||
"function arguments must have a statically known size, borrowed types \
|
||||
always have a known size",
|
||||
"&",
|
||||
sugg,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
|
@ -9,5 +9,8 @@ fn foo(_x: Foo + Send) {
|
||||
//~| WARN trait objects without an explicit `dyn` are deprecated
|
||||
//~| WARN this is accepted in the current edition
|
||||
}
|
||||
fn bar(_x: (dyn Foo + Send)) {
|
||||
//~^ ERROR the size for values of type
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -34,9 +34,26 @@ LL | fn foo(_x: impl Foo + Send) {
|
||||
| ++++
|
||||
help: function arguments must have a statically known size, borrowed types always have a known size
|
||||
|
|
||||
LL | fn foo(_x: &Foo + Send) {
|
||||
LL | fn foo(_x: &(Foo + Send)) {
|
||||
| ++ +
|
||||
|
||||
error[E0277]: the size for values of type `(dyn Foo + Send + 'static)` cannot be known at compilation time
|
||||
--> $DIR/not-on-bare-trait.rs:12:8
|
||||
|
|
||||
LL | fn bar(_x: (dyn Foo + Send)) {
|
||||
| ^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `(dyn Foo + Send + 'static)`
|
||||
= help: unsized fn params are gated as an unstable feature
|
||||
help: you can use `impl Trait` as the argument type
|
||||
|
|
||||
LL | fn bar(_x: impl (dyn Foo + Send)) {
|
||||
| ++++
|
||||
help: function arguments must have a statically known size, borrowed types always have a known size
|
||||
|
|
||||
LL | fn bar(_x: &(dyn Foo + Send)) {
|
||||
| +
|
||||
|
||||
error: aborting due to 1 previous error; 1 warning emitted
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
Loading…
Reference in New Issue
Block a user