Rework borrowing suggestions to use Expr instead of just Span
In the suggestion machinery for borrowing expressions and types, always use the available obligation `Span` to find the appropriate `Expr` to perform appropriateness checks no the `ExprKind` instead of on the textual snippet corresponding to the `Span`. Unify the logic for the case where `&` *and* `&mut` are appropriate with the logic for only one of those cases. Handle the case when `S::foo()` should have been `<&S>::foo()` (instead of suggesting the prior `&S::foo()`.
This commit is contained in:
parent
78a6e13298
commit
7dfc3e9af4
16 changed files with 217 additions and 213 deletions
|
|
@ -1321,7 +1321,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
let imm_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_imm_ref);
|
||||
let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref);
|
||||
|
||||
let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) =
|
||||
let (ref_inner_ty_satisfies_pred, ref_inner_ty_is_mut) =
|
||||
if let ObligationCauseCode::WhereClauseInExpr(..) = obligation.cause.code()
|
||||
&& let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind()
|
||||
{
|
||||
|
|
@ -1333,117 +1333,139 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
(false, false)
|
||||
};
|
||||
|
||||
if imm_ref_self_ty_satisfies_pred
|
||||
|| mut_ref_self_ty_satisfies_pred
|
||||
|| ref_inner_ty_satisfies_pred
|
||||
{
|
||||
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||
// We don't want a borrowing suggestion on the fields in structs,
|
||||
// ```
|
||||
// struct Foo {
|
||||
// the_foos: Vec<Foo>
|
||||
// }
|
||||
// ```
|
||||
if !matches!(
|
||||
span.ctxt().outer_expn_data().kind,
|
||||
ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if snippet.starts_with('&') {
|
||||
// This is already a literal borrow and the obligation is failing
|
||||
// somewhere else in the obligation chain. Do not suggest non-sense.
|
||||
return false;
|
||||
}
|
||||
// We have a very specific type of error, where just borrowing this argument
|
||||
// might solve the problem. In cases like this, the important part is the
|
||||
// original type obligation, not the last one that failed, which is arbitrary.
|
||||
// Because of this, we modify the error to refer to the original obligation and
|
||||
// return early in the caller.
|
||||
let is_immut = imm_ref_self_ty_satisfies_pred
|
||||
|| (ref_inner_ty_satisfies_pred && !ref_inner_ty_is_mut);
|
||||
let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_is_mut;
|
||||
if !is_immut && !is_mut {
|
||||
return false;
|
||||
}
|
||||
let Ok(_snippet) = self.tcx.sess.source_map().span_to_snippet(span) else {
|
||||
return false;
|
||||
};
|
||||
// We don't want a borrowing suggestion on the fields in structs
|
||||
// ```
|
||||
// #[derive(Clone)]
|
||||
// struct Foo {
|
||||
// the_foos: Vec<Foo>
|
||||
// }
|
||||
// ```
|
||||
if !matches!(
|
||||
span.ctxt().outer_expn_data().kind,
|
||||
ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
// We have a very specific type of error, where just borrowing this argument
|
||||
// might solve the problem. In cases like this, the important part is the
|
||||
// original type obligation, not the last one that failed, which is arbitrary.
|
||||
// Because of this, we modify the error to refer to the original obligation and
|
||||
// return early in the caller.
|
||||
|
||||
let msg = format!(
|
||||
"the trait bound `{}` is not satisfied",
|
||||
self.tcx.short_string(old_pred, err.long_ty_path()),
|
||||
);
|
||||
let self_ty_str =
|
||||
self.tcx.short_string(old_pred.self_ty().skip_binder(), err.long_ty_path());
|
||||
if has_custom_message {
|
||||
err.note(msg);
|
||||
} else {
|
||||
err.messages = vec![(rustc_errors::DiagMessage::from(msg), Style::NoStyle)];
|
||||
}
|
||||
err.span_label(
|
||||
span,
|
||||
format!(
|
||||
"the trait `{}` is not implemented for `{self_ty_str}`",
|
||||
old_pred.print_modifiers_and_trait_path()
|
||||
),
|
||||
);
|
||||
let mut label = || {
|
||||
let msg = format!(
|
||||
"the trait bound `{}` is not satisfied",
|
||||
self.tcx.short_string(old_pred, err.long_ty_path()),
|
||||
);
|
||||
let self_ty_str =
|
||||
self.tcx.short_string(old_pred.self_ty().skip_binder(), err.long_ty_path());
|
||||
if has_custom_message {
|
||||
err.note(msg);
|
||||
} else {
|
||||
err.messages = vec![(rustc_errors::DiagMessage::from(msg), Style::NoStyle)];
|
||||
}
|
||||
err.span_label(
|
||||
span,
|
||||
format!(
|
||||
"the trait `{}` is not implemented for `{self_ty_str}`",
|
||||
old_pred.print_modifiers_and_trait_path()
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred {
|
||||
err.span_suggestions(
|
||||
span.shrink_to_lo(),
|
||||
"consider borrowing here",
|
||||
["&".to_string(), "&mut ".to_string()],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
|
||||
let sugg_prefix = format!("&{}", if is_mut { "mut " } else { "" });
|
||||
let sugg_msg = format!(
|
||||
"consider{} borrowing here",
|
||||
if is_mut { " mutably" } else { "" }
|
||||
);
|
||||
let mut sugg_prefixes = vec![];
|
||||
if is_immut {
|
||||
sugg_prefixes.push("&");
|
||||
}
|
||||
if is_mut {
|
||||
sugg_prefixes.push("&mut ");
|
||||
}
|
||||
let sugg_msg = format!(
|
||||
"consider{} borrowing here",
|
||||
if is_mut && !is_immut { " mutably" } else { "" },
|
||||
);
|
||||
|
||||
// Issue #109436, we need to add parentheses properly for method calls
|
||||
// for example, `foo.into()` should be `(&foo).into()`
|
||||
if let Some(_) =
|
||||
self.tcx.sess.source_map().span_look_ahead(span, ".", Some(50))
|
||||
{
|
||||
err.multipart_suggestion_verbose(
|
||||
sugg_msg,
|
||||
vec![
|
||||
(span.shrink_to_lo(), format!("({sugg_prefix}")),
|
||||
(span.shrink_to_hi(), ")".to_string()),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
// Issue #104961, we need to add parentheses properly for compound expressions
|
||||
// for example, `x.starts_with("hi".to_string() + "you")`
|
||||
// should be `x.starts_with(&("hi".to_string() + "you"))`
|
||||
let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) else {
|
||||
return false;
|
||||
};
|
||||
let mut expr_finder = FindExprBySpan::new(span, self.tcx);
|
||||
expr_finder.visit_expr(body.value);
|
||||
|
||||
// Issue #104961, we need to add parentheses properly for compound expressions
|
||||
// for example, `x.starts_with("hi".to_string() + "you")`
|
||||
// should be `x.starts_with(&("hi".to_string() + "you"))`
|
||||
let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id)
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
let mut expr_finder = FindExprBySpan::new(span, self.tcx);
|
||||
expr_finder.visit_expr(body.value);
|
||||
let Some(expr) = expr_finder.result else {
|
||||
return false;
|
||||
};
|
||||
let needs_parens = expr_needs_parens(expr);
|
||||
|
||||
let span = if needs_parens { span } else { span.shrink_to_lo() };
|
||||
let suggestions = if !needs_parens {
|
||||
vec![(span.shrink_to_lo(), sugg_prefix)]
|
||||
} else {
|
||||
if let Some(ty) = expr_finder.ty_result {
|
||||
if let hir::Node::Expr(expr) = self.tcx.parent_hir_node(ty.hir_id)
|
||||
&& let hir::ExprKind::Path(hir::QPath::TypeRelative(_, _)) = expr.kind
|
||||
&& ty.span == span
|
||||
{
|
||||
// We've encountered something like `str::from("")`, where the intended code
|
||||
// was likely `<&str>::from("")`. #143393.
|
||||
label();
|
||||
err.multipart_suggestions(
|
||||
sugg_msg,
|
||||
sugg_prefixes.into_iter().map(|sugg_prefix| {
|
||||
vec![
|
||||
(span.shrink_to_lo(), format!("{sugg_prefix}(")),
|
||||
(span.shrink_to_hi(), ")".to_string()),
|
||||
(span.shrink_to_lo(), format!("<{sugg_prefix}")),
|
||||
(span.shrink_to_hi(), ">".to_string()),
|
||||
]
|
||||
};
|
||||
err.multipart_suggestion_verbose(
|
||||
sugg_msg,
|
||||
suggestions,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
let Some(expr) = expr_finder.result else {
|
||||
return false;
|
||||
};
|
||||
if let hir::ExprKind::AddrOf(_, _, _) = expr.kind {
|
||||
return false;
|
||||
}
|
||||
let needs_parens_post = expr_needs_parens(expr);
|
||||
let needs_parens_pre = match self.tcx.parent_hir_node(expr.hir_id) {
|
||||
Node::Expr(e)
|
||||
if let hir::ExprKind::MethodCall(_, base, _, _) = e.kind
|
||||
&& base.hir_id == expr.hir_id =>
|
||||
{
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
label();
|
||||
let suggestions = sugg_prefixes.into_iter().map(|sugg_prefix| {
|
||||
match (needs_parens_pre, needs_parens_post) {
|
||||
(false, false) => vec![(span.shrink_to_lo(), sugg_prefix.to_string())],
|
||||
// We have something like `foo.bar()`, where we want to bororw foo, so we need
|
||||
// to suggest `(&mut foo).bar()`.
|
||||
(false, true) => vec![
|
||||
(span.shrink_to_lo(), format!("{sugg_prefix}(")),
|
||||
(span.shrink_to_hi(), ")".to_string()),
|
||||
],
|
||||
// Issue #109436, we need to add parentheses properly for method calls
|
||||
// for example, `foo.into()` should be `(&foo).into()`
|
||||
(true, false) => vec![
|
||||
(span.shrink_to_lo(), format!("({sugg_prefix}")),
|
||||
(span.shrink_to_hi(), ")".to_string()),
|
||||
],
|
||||
(true, true) => vec![
|
||||
(span.shrink_to_lo(), format!("({sugg_prefix}(")),
|
||||
(span.shrink_to_hi(), "))".to_string()),
|
||||
],
|
||||
}
|
||||
});
|
||||
err.multipart_suggestions(sugg_msg, suggestions, Applicability::MaybeIncorrect);
|
||||
return true;
|
||||
};
|
||||
|
||||
if let ObligationCauseCode::ImplDerived(cause) = &*code {
|
||||
|
|
|
|||
|
|
@ -2,25 +2,37 @@ error[E0277]: the size for values of type `Opaque` cannot be known
|
|||
--> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:43
|
||||
|
|
||||
LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) };
|
||||
| ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
|
||||
| ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Opaque`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `MetaSized` is not implemented for `Opaque`
|
||||
= note: the trait bound `Opaque: MetaSized` is not satisfied
|
||||
note: required by a bound in `std::intrinsics::size_of_val`
|
||||
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | const _SIZE: usize = unsafe { size_of_val(&(&4 as *const i32 as *const Opaque)) };
|
||||
| ++ +
|
||||
LL | const _SIZE: usize = unsafe { size_of_val(&mut (&4 as *const i32 as *const Opaque)) };
|
||||
| ++++++ +
|
||||
|
||||
error[E0277]: the size for values of type `Opaque` cannot be known
|
||||
--> $DIR/const-size_of_val-align_of_val-extern-type.rs:12:45
|
||||
|
|
||||
LL | const _ALIGN: usize = unsafe { align_of_val(&4 as *const i32 as *const Opaque) };
|
||||
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
|
||||
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Opaque`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `MetaSized` is not implemented for `Opaque`
|
||||
= note: the trait bound `Opaque: MetaSized` is not satisfied
|
||||
note: required by a bound in `std::intrinsics::align_of_val`
|
||||
--> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | const _ALIGN: usize = unsafe { align_of_val(&(&4 as *const i32 as *const Opaque)) };
|
||||
| ++ +
|
||||
LL | const _ALIGN: usize = unsafe { align_of_val(&mut (&4 as *const i32 as *const Opaque)) };
|
||||
| ++++++ +
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@ error[E0277]: the trait bound `B<C>: Copy` is not satisfied
|
|||
--> $DIR/deriving-copyclone.rs:31:26
|
||||
|
|
||||
LL | is_copy(B { a: 1, b: C });
|
||||
| ------- ^ the trait `Copy` is not implemented for `B<C>`
|
||||
| |
|
||||
| ------- ^
|
||||
| | |
|
||||
| | the trait `Copy` is not implemented for `B<C>`
|
||||
| | help: consider borrowing here: `&`
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required for `B<C>` to implement `Copy`
|
||||
|
|
@ -16,17 +18,15 @@ note: required by a bound in `is_copy`
|
|||
|
|
||||
LL | fn is_copy<T: Copy>(_: T) {}
|
||||
| ^^^^ required by this bound in `is_copy`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | is_copy(B { a: 1, b: &C });
|
||||
| +
|
||||
|
||||
error[E0277]: the trait bound `B<C>: Clone` is not satisfied
|
||||
--> $DIR/deriving-copyclone.rs:32:27
|
||||
|
|
||||
LL | is_clone(B { a: 1, b: C });
|
||||
| -------- ^ the trait `Clone` is not implemented for `B<C>`
|
||||
| |
|
||||
| -------- ^
|
||||
| | |
|
||||
| | the trait `Clone` is not implemented for `B<C>`
|
||||
| | help: consider borrowing here: `&`
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required for `B<C>` to implement `Clone`
|
||||
|
|
@ -39,17 +39,15 @@ note: required by a bound in `is_clone`
|
|||
|
|
||||
LL | fn is_clone<T: Clone>(_: T) {}
|
||||
| ^^^^^ required by this bound in `is_clone`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | is_clone(B { a: 1, b: &C });
|
||||
| +
|
||||
|
||||
error[E0277]: the trait bound `B<D>: Copy` is not satisfied
|
||||
--> $DIR/deriving-copyclone.rs:35:26
|
||||
|
|
||||
LL | is_copy(B { a: 1, b: D });
|
||||
| ------- ^ the trait `Copy` is not implemented for `B<D>`
|
||||
| |
|
||||
| ------- ^
|
||||
| | |
|
||||
| | the trait `Copy` is not implemented for `B<D>`
|
||||
| | help: consider borrowing here: `&`
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required for `B<D>` to implement `Copy`
|
||||
|
|
@ -62,10 +60,6 @@ note: required by a bound in `is_copy`
|
|||
|
|
||||
LL | fn is_copy<T: Copy>(_: T) {}
|
||||
| ^^^^ required by this bound in `is_copy`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | is_copy(B { a: 1, b: &D });
|
||||
| +
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ note: required by a bound in `Box::<T>::from_raw`
|
|||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | Box::from_raw(&0 as *mut _)
|
||||
| +
|
||||
LL | Box::from_raw(&mut 0 as *mut _)
|
||||
| ++++
|
||||
LL | Box::from_raw(&(0 as *mut _))
|
||||
| ++ +
|
||||
LL | Box::from_raw(&mut (0 as *mut _))
|
||||
| ++++++ +
|
||||
|
||||
error[E0277]: the size for values of type `Device` cannot be known
|
||||
--> $DIR/unsized-extern-derefmove.rs:11:5
|
||||
|
|
|
|||
|
|
@ -2,14 +2,13 @@ error[E0277]: `dyn Iterator<Item = &'a mut u8>` is not an iterator
|
|||
--> $DIR/issue-20605.rs:6:17
|
||||
|
|
||||
LL | for item in *things { *item = 0 }
|
||||
| ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
|
||||
| -^^^^^^
|
||||
| |
|
||||
| the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
|
||||
| help: consider mutably borrowing here: `&mut`
|
||||
|
|
||||
= note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
|
||||
= note: required for `dyn Iterator<Item = &'a mut u8>` to implement `IntoIterator`
|
||||
help: consider mutably borrowing here
|
||||
|
|
||||
LL | for item in &mut *things { *item = 0 }
|
||||
| ++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -2,14 +2,13 @@ error[E0277]: `dyn Iterator<Item = &'a mut u8>` is not an iterator
|
|||
--> $DIR/issue-20605.rs:6:17
|
||||
|
|
||||
LL | for item in *things { *item = 0 }
|
||||
| ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
|
||||
| -^^^^^^
|
||||
| |
|
||||
| the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
|
||||
| help: consider mutably borrowing here: `&mut`
|
||||
|
|
||||
= note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
|
||||
= note: required for `dyn Iterator<Item = &'a mut u8>` to implement `IntoIterator`
|
||||
help: consider mutably borrowing here
|
||||
|
|
||||
LL | for item in &mut *things { *item = 0 }
|
||||
| ++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@ LL | fn a(self: impl Receiver<Target=Self>) -> u32 {
|
|||
| ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::a`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | &foo.a();
|
||||
| +
|
||||
LL | &mut foo.a();
|
||||
| ++++
|
||||
LL | (&foo).a();
|
||||
| ++ +
|
||||
LL | (&mut foo).a();
|
||||
| +++++ +
|
||||
|
||||
error[E0277]: the trait bound `Foo: Deref` is not satisfied
|
||||
--> $DIR/arbitrary_self_types_generic_over_receiver.rs:21:9
|
||||
|
|
@ -48,10 +48,10 @@ LL | fn b(self: impl Deref<Target=Self>) -> u32 {
|
|||
| ^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::b`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | &foo.b();
|
||||
| +
|
||||
LL | &mut foo.b();
|
||||
| ++++
|
||||
LL | (&foo).b();
|
||||
| ++ +
|
||||
LL | (&mut foo).b();
|
||||
| +++++ +
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,10 @@ error[E0277]: the trait bound `S: Trait` is not satisfied
|
|||
--> $DIR/imm-ref-trait-object-literal.rs:13:7
|
||||
|
|
||||
LL | foo(s);
|
||||
| --- ^ the trait `Trait` is not implemented for `S`
|
||||
| |
|
||||
| --- ^
|
||||
| | |
|
||||
| | the trait `Trait` is not implemented for `S`
|
||||
| | help: consider mutably borrowing here: `&mut`
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `foo`
|
||||
|
|
@ -30,10 +32,6 @@ note: required by a bound in `foo`
|
|||
|
|
||||
LL | fn foo<X: Trait>(_: X) {}
|
||||
| ^^^^^ required by this bound in `foo`
|
||||
help: consider mutably borrowing here
|
||||
|
|
||||
LL | foo(&mut s);
|
||||
| ++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -18,17 +18,15 @@ error[E0277]: the trait bound `String: Pattern` is not satisfied
|
|||
--> $DIR/issue-104961.rs:9:19
|
||||
|
|
||||
LL | x.starts_with("hi".to_string())
|
||||
| ----------- ^^^^^^^^^^^^^^^^ the trait `Pattern` is not implemented for `String`
|
||||
| |
|
||||
| ----------- -^^^^^^^^^^^^^^^
|
||||
| | |
|
||||
| | the trait `Pattern` is not implemented for `String`
|
||||
| | help: consider borrowing here: `&`
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= note: required for `String` to implement `Pattern`
|
||||
note: required by a bound in `core::str::<impl str>::starts_with`
|
||||
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | x.starts_with(&"hi".to_string())
|
||||
| +
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -2,17 +2,15 @@ error[E0277]: the trait bound `String: Pattern` is not satisfied
|
|||
--> $DIR/issue-62843.rs:4:32
|
||||
|
|
||||
LL | println!("{:?}", line.find(pattern));
|
||||
| ---- ^^^^^^^ the trait `Pattern` is not implemented for `String`
|
||||
| |
|
||||
| ---- -^^^^^^
|
||||
| | |
|
||||
| | the trait `Pattern` is not implemented for `String`
|
||||
| | help: consider borrowing here: `&`
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= note: required for `String` to implement `Pattern`
|
||||
note: required by a bound in `core::str::<impl str>::find`
|
||||
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | println!("{:?}", line.find(&pattern));
|
||||
| +
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@ error[E0277]: the trait bound `i32: Tr` is not satisfied
|
|||
--> $DIR/issue-84973-2.rs:11:9
|
||||
|
|
||||
LL | foo(a);
|
||||
| --- ^ the trait `Tr` is not implemented for `i32`
|
||||
| |
|
||||
| --- ^
|
||||
| | |
|
||||
| | the trait `Tr` is not implemented for `i32`
|
||||
| | help: consider mutably borrowing here: `&mut`
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `foo`
|
||||
|
|
@ -11,10 +13,6 @@ note: required by a bound in `foo`
|
|||
|
|
||||
LL | fn foo<T: Tr>(i: T) {}
|
||||
| ^^ required by this bound in `foo`
|
||||
help: consider mutably borrowing here
|
||||
|
|
||||
LL | foo(&mut a);
|
||||
| ++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@ error[E0277]: the trait bound `f32: Tr` is not satisfied
|
|||
--> $DIR/issue-84973-negative.rs:11:9
|
||||
|
|
||||
LL | bar(b);
|
||||
| --- ^ the trait `Tr` is not implemented for `f32`
|
||||
| |
|
||||
| --- ^
|
||||
| | |
|
||||
| | the trait `Tr` is not implemented for `f32`
|
||||
| | help: consider borrowing here: `&`
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `bar`
|
||||
|
|
@ -26,10 +28,6 @@ note: required by a bound in `bar`
|
|||
|
|
||||
LL | fn bar<T: Tr>(t: T) {}
|
||||
| ^^ required by this bound in `bar`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | bar(&b);
|
||||
| +
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@ error[E0277]: the trait bound `Fancy: SomeTrait` is not satisfied
|
|||
--> $DIR/issue-84973.rs:6:24
|
||||
|
|
||||
LL | let o = Other::new(f);
|
||||
| ---------- ^ the trait `SomeTrait` is not implemented for `Fancy`
|
||||
| |
|
||||
| ---------- ^
|
||||
| | |
|
||||
| | the trait `SomeTrait` is not implemented for `Fancy`
|
||||
| | help: consider borrowing here: `&`
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `Other::<'a, G>::new`
|
||||
|
|
@ -14,10 +16,6 @@ LL | G: SomeTrait,
|
|||
LL | {
|
||||
LL | pub fn new(g: G) -> Self {
|
||||
| --- required by a bound in this associated function
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | let o = Other::new(&f);
|
||||
| +
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -2,23 +2,19 @@ error[E0277]: the trait bound `&mut usize: Default` is not satisfied
|
|||
--> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:13:9
|
||||
|
|
||||
LL | foo(Default::default());
|
||||
| ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&mut usize`
|
||||
|
|
||||
help: consider mutably borrowing here
|
||||
|
|
||||
LL | foo(&mut Default::default());
|
||||
| ++++
|
||||
| -^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| the trait `Default` is not implemented for `&mut usize`
|
||||
| help: consider mutably borrowing here: `&mut`
|
||||
|
||||
error[E0277]: the trait bound `&usize: Default` is not satisfied
|
||||
--> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:14:9
|
||||
|
|
||||
LL | bar(Default::default());
|
||||
| ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&usize`
|
||||
|
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | bar(&Default::default());
|
||||
| +
|
||||
| -^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| the trait `Default` is not implemented for `&usize`
|
||||
| help: consider borrowing here: `&`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,10 @@ error[E0277]: the trait bound `B: Trait` is not satisfied
|
|||
--> $DIR/suggest-imm-mut-trait-implementations.rs:21:9
|
||||
|
|
||||
LL | foo(b);
|
||||
| --- ^ the trait `Trait` is not implemented for `B`
|
||||
| |
|
||||
| --- ^
|
||||
| | |
|
||||
| | the trait `Trait` is not implemented for `B`
|
||||
| | help: consider borrowing here: `&`
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `foo`
|
||||
|
|
@ -31,17 +33,15 @@ note: required by a bound in `foo`
|
|||
|
|
||||
LL | fn foo<X: Trait>(_: X) {}
|
||||
| ^^^^^ required by this bound in `foo`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | foo(&b);
|
||||
| +
|
||||
|
||||
error[E0277]: the trait bound `C: Trait` is not satisfied
|
||||
--> $DIR/suggest-imm-mut-trait-implementations.rs:22:9
|
||||
|
|
||||
LL | foo(c);
|
||||
| --- ^ the trait `Trait` is not implemented for `C`
|
||||
| |
|
||||
| --- ^
|
||||
| | |
|
||||
| | the trait `Trait` is not implemented for `C`
|
||||
| | help: consider mutably borrowing here: `&mut`
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `foo`
|
||||
|
|
@ -49,10 +49,6 @@ note: required by a bound in `foo`
|
|||
|
|
||||
LL | fn foo<X: Trait>(_: X) {}
|
||||
| ^^^^^ required by this bound in `foo`
|
||||
help: consider mutably borrowing here
|
||||
|
|
||||
LL | foo(&mut c);
|
||||
| ++++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -61,8 +61,10 @@ error[E0277]: `dummy2::TestType` cannot be sent between threads safely
|
|||
--> $DIR/negated-auto-traits-error.rs:48:13
|
||||
|
|
||||
LL | is_send(Box::new(TestType));
|
||||
| ------- ^^^^^^^^^^^^^^^^^^ the trait `Send` is not implemented for `Unique<dummy2::TestType>`
|
||||
| |
|
||||
| ------- -^^^^^^^^^^^^^^^^^
|
||||
| | |
|
||||
| | the trait `Send` is not implemented for `Unique<dummy2::TestType>`
|
||||
| | help: consider borrowing here: `&`
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= note: the trait bound `Unique<dummy2::TestType>: Send` is not satisfied
|
||||
|
|
@ -74,10 +76,6 @@ note: required by a bound in `is_send`
|
|||
|
|
||||
LL | fn is_send<T: Send>(_: T) {}
|
||||
| ^^^^ required by this bound in `is_send`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | is_send(&Box::new(TestType));
|
||||
| +
|
||||
|
||||
error[E0277]: `dummy3::TestType` cannot be sent between threads safely
|
||||
--> $DIR/negated-auto-traits-error.rs:56:13
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue