Rollup merge of #108841 - jackh726:issue-90528, r=compiler-errors
Add suggestion to diagnostic when user has array but trait wants slice. (rebased) Rebase of #91314, except for change to multipart suggestion Resolves #90528 r? ``@compiler-errors`` since you requested the multipart suggestion
This commit is contained in:
commit
67c9dbfe02
@ -1024,7 +1024,7 @@ fn report_selection_error(
|
|||||||
// Can't show anything else useful, try to find similar impls.
|
// Can't show anything else useful, try to find similar impls.
|
||||||
let impl_candidates = self.find_similar_impl_candidates(trait_predicate);
|
let impl_candidates = self.find_similar_impl_candidates(trait_predicate);
|
||||||
if !self.report_similar_impl_candidates(
|
if !self.report_similar_impl_candidates(
|
||||||
impl_candidates,
|
&impl_candidates,
|
||||||
trait_ref,
|
trait_ref,
|
||||||
body_def_id,
|
body_def_id,
|
||||||
&mut err,
|
&mut err,
|
||||||
@ -1060,7 +1060,7 @@ fn report_selection_error(
|
|||||||
let impl_candidates =
|
let impl_candidates =
|
||||||
self.find_similar_impl_candidates(trait_pred);
|
self.find_similar_impl_candidates(trait_pred);
|
||||||
self.report_similar_impl_candidates(
|
self.report_similar_impl_candidates(
|
||||||
impl_candidates,
|
&impl_candidates,
|
||||||
trait_ref,
|
trait_ref,
|
||||||
body_def_id,
|
body_def_id,
|
||||||
&mut err,
|
&mut err,
|
||||||
@ -1068,6 +1068,13 @@ fn report_selection_error(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.maybe_suggest_convert_to_slice(
|
||||||
|
&mut err,
|
||||||
|
trait_ref,
|
||||||
|
impl_candidates.as_slice(),
|
||||||
|
span,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Changing mutability doesn't make a difference to whether we have
|
// Changing mutability doesn't make a difference to whether we have
|
||||||
@ -1514,7 +1521,7 @@ fn find_similar_impl_candidates(
|
|||||||
|
|
||||||
fn report_similar_impl_candidates(
|
fn report_similar_impl_candidates(
|
||||||
&self,
|
&self,
|
||||||
impl_candidates: Vec<ImplCandidate<'tcx>>,
|
impl_candidates: &[ImplCandidate<'tcx>],
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
body_def_id: LocalDefId,
|
body_def_id: LocalDefId,
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
@ -2004,7 +2011,7 @@ fn find_similar_impl_candidates(
|
|||||||
|
|
||||||
fn report_similar_impl_candidates(
|
fn report_similar_impl_candidates(
|
||||||
&self,
|
&self,
|
||||||
impl_candidates: Vec<ImplCandidate<'tcx>>,
|
impl_candidates: &[ImplCandidate<'tcx>],
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
body_def_id: LocalDefId,
|
body_def_id: LocalDefId,
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
@ -2113,7 +2120,8 @@ fn report_similar_impl_candidates(
|
|||||||
// Prefer more similar candidates first, then sort lexicographically
|
// Prefer more similar candidates first, then sort lexicographically
|
||||||
// by their normalized string representation.
|
// by their normalized string representation.
|
||||||
let mut normalized_impl_candidates_and_similarities = impl_candidates
|
let mut normalized_impl_candidates_and_similarities = impl_candidates
|
||||||
.into_iter()
|
.iter()
|
||||||
|
.copied()
|
||||||
.map(|ImplCandidate { trait_ref, similarity }| {
|
.map(|ImplCandidate { trait_ref, similarity }| {
|
||||||
// FIXME(compiler-errors): This should be using `NormalizeExt::normalize`
|
// FIXME(compiler-errors): This should be using `NormalizeExt::normalize`
|
||||||
let normalized = self
|
let normalized = self
|
||||||
@ -2326,7 +2334,7 @@ fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) {
|
|||||||
);
|
);
|
||||||
if impl_candidates.len() < 10 {
|
if impl_candidates.len() < 10 {
|
||||||
self.report_similar_impl_candidates(
|
self.report_similar_impl_candidates(
|
||||||
impl_candidates,
|
impl_candidates.as_slice(),
|
||||||
trait_ref,
|
trait_ref,
|
||||||
obligation.cause.body_id,
|
obligation.cause.body_id,
|
||||||
&mut err,
|
&mut err,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// ignore-tidy-filelength
|
// ignore-tidy-filelength
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
DefIdOrName, FindExprBySpan, Obligation, ObligationCause, ObligationCauseCode,
|
DefIdOrName, FindExprBySpan, ImplCandidate, Obligation, ObligationCause, ObligationCauseCode,
|
||||||
PredicateObligation,
|
PredicateObligation,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -382,6 +382,14 @@ fn probe_assoc_types_at_expr(
|
|||||||
body_id: hir::HirId,
|
body_id: hir::HirId,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> Vec<Option<(Span, (DefId, Ty<'tcx>))>>;
|
) -> Vec<Option<(Span, (DefId, Ty<'tcx>))>>;
|
||||||
|
|
||||||
|
fn maybe_suggest_convert_to_slice(
|
||||||
|
&self,
|
||||||
|
err: &mut Diagnostic,
|
||||||
|
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||||
|
candidate_impls: &[ImplCandidate<'tcx>],
|
||||||
|
span: Span,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) -> (Span, String) {
|
fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) -> (Span, String) {
|
||||||
@ -3826,6 +3834,73 @@ fn probe_assoc_types_at_expr(
|
|||||||
}
|
}
|
||||||
assocs_in_this_method
|
assocs_in_this_method
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If the type that failed selection is an array or a reference to an array,
|
||||||
|
/// but the trait is implemented for slices, suggest that the user converts
|
||||||
|
/// the array into a slice.
|
||||||
|
fn maybe_suggest_convert_to_slice(
|
||||||
|
&self,
|
||||||
|
err: &mut Diagnostic,
|
||||||
|
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||||
|
candidate_impls: &[ImplCandidate<'tcx>],
|
||||||
|
span: Span,
|
||||||
|
) {
|
||||||
|
// Three cases where we can make a suggestion:
|
||||||
|
// 1. `[T; _]` (array of T)
|
||||||
|
// 2. `&[T; _]` (reference to array of T)
|
||||||
|
// 3. `&mut [T; _]` (mutable reference to array of T)
|
||||||
|
let (element_ty, mut mutability) = match *trait_ref.skip_binder().self_ty().kind() {
|
||||||
|
ty::Array(element_ty, _) => (element_ty, None),
|
||||||
|
|
||||||
|
ty::Ref(_, pointee_ty, mutability) => match *pointee_ty.kind() {
|
||||||
|
ty::Array(element_ty, _) => (element_ty, Some(mutability)),
|
||||||
|
_ => return,
|
||||||
|
},
|
||||||
|
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Go through all the candidate impls to see if any of them is for
|
||||||
|
// slices of `element_ty` with `mutability`.
|
||||||
|
let mut is_slice = |candidate: Ty<'tcx>| match *candidate.kind() {
|
||||||
|
ty::RawPtr(ty::TypeAndMut { ty: t, mutbl: m }) | ty::Ref(_, t, m) => {
|
||||||
|
if matches!(*t.kind(), ty::Slice(e) if e == element_ty)
|
||||||
|
&& m == mutability.unwrap_or(m)
|
||||||
|
{
|
||||||
|
// Use the candidate's mutability going forward.
|
||||||
|
mutability = Some(m);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Grab the first candidate that matches, if any, and make a suggestion.
|
||||||
|
if let Some(slice_ty) = candidate_impls
|
||||||
|
.iter()
|
||||||
|
.map(|trait_ref| trait_ref.trait_ref.self_ty())
|
||||||
|
.filter(|t| is_slice(*t))
|
||||||
|
.next()
|
||||||
|
{
|
||||||
|
let msg = &format!("convert the array to a `{}` slice instead", slice_ty);
|
||||||
|
|
||||||
|
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||||
|
let mut suggestions = vec![];
|
||||||
|
if snippet.starts_with('&') {
|
||||||
|
} else if let Some(hir::Mutability::Mut) = mutability {
|
||||||
|
suggestions.push((span.shrink_to_lo(), "&mut ".into()));
|
||||||
|
} else {
|
||||||
|
suggestions.push((span.shrink_to_lo(), "&".into()));
|
||||||
|
}
|
||||||
|
suggestions.push((span.shrink_to_hi(), "[..]".into()));
|
||||||
|
err.multipart_suggestion_verbose(msg, suggestions, Applicability::MaybeIncorrect);
|
||||||
|
} else {
|
||||||
|
err.span_help(span, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a hint to add a missing borrow or remove an unnecessary one.
|
/// Add a hint to add a missing borrow or remove an unnecessary one.
|
||||||
|
20
tests/ui/dst/issue-90528-unsizing-suggestion-1.rs
Normal file
20
tests/ui/dst/issue-90528-unsizing-suggestion-1.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Issue #90528: provide helpful suggestions when a trait bound is unsatisfied
|
||||||
|
// due to a missed unsizing coercion.
|
||||||
|
//
|
||||||
|
// This test exercises array literals and a trait implemented on immutable slices.
|
||||||
|
|
||||||
|
trait Read {}
|
||||||
|
|
||||||
|
impl Read for &[u8] {}
|
||||||
|
|
||||||
|
fn wants_read(_: impl Read) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
wants_read([0u8]);
|
||||||
|
//~^ ERROR the trait bound `[u8; 1]: Read` is not satisfied
|
||||||
|
wants_read(&[0u8]);
|
||||||
|
//~^ ERROR the trait bound `&[u8; 1]: Read` is not satisfied
|
||||||
|
wants_read(&[0u8][..]);
|
||||||
|
wants_read(&mut [0u8]);
|
||||||
|
//~^ ERROR the trait bound `&mut [u8; 1]: Read` is not satisfied
|
||||||
|
}
|
56
tests/ui/dst/issue-90528-unsizing-suggestion-1.stderr
Normal file
56
tests/ui/dst/issue-90528-unsizing-suggestion-1.stderr
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
error[E0277]: the trait bound `[u8; 1]: Read` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-1.rs:13:16
|
||||||
|
|
|
||||||
|
LL | wants_read([0u8]);
|
||||||
|
| ---------- ^^^^^ the trait `Read` is not implemented for `[u8; 1]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Read` is implemented for `&[u8]`
|
||||||
|
note: required by a bound in `wants_read`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-1.rs:10:23
|
||||||
|
|
|
||||||
|
LL | fn wants_read(_: impl Read) {}
|
||||||
|
| ^^^^ required by this bound in `wants_read`
|
||||||
|
help: convert the array to a `&[u8]` slice instead
|
||||||
|
|
|
||||||
|
LL | wants_read(&[0u8][..]);
|
||||||
|
| + ++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&[u8; 1]: Read` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-1.rs:15:16
|
||||||
|
|
|
||||||
|
LL | wants_read(&[0u8]);
|
||||||
|
| ---------- ^^^^^^ the trait `Read` is not implemented for `&[u8; 1]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Read` is implemented for `&[u8]`
|
||||||
|
note: required by a bound in `wants_read`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-1.rs:10:23
|
||||||
|
|
|
||||||
|
LL | fn wants_read(_: impl Read) {}
|
||||||
|
| ^^^^ required by this bound in `wants_read`
|
||||||
|
help: convert the array to a `&[u8]` slice instead
|
||||||
|
|
|
||||||
|
LL | wants_read(&[0u8][..]);
|
||||||
|
| ++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&mut [u8; 1]: Read` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-1.rs:18:16
|
||||||
|
|
|
||||||
|
LL | wants_read(&mut [0u8]);
|
||||||
|
| ---------- ^^^^^^^^^^ the trait `Read` is not implemented for `&mut [u8; 1]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Read` is implemented for `&[u8]`
|
||||||
|
note: required by a bound in `wants_read`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-1.rs:10:23
|
||||||
|
|
|
||||||
|
LL | fn wants_read(_: impl Read) {}
|
||||||
|
| ^^^^ required by this bound in `wants_read`
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
28
tests/ui/dst/issue-90528-unsizing-suggestion-2.rs
Normal file
28
tests/ui/dst/issue-90528-unsizing-suggestion-2.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Issue #90528: provide helpful suggestions when a trait bound is unsatisfied
|
||||||
|
// due to a missed unsizing coercion.
|
||||||
|
//
|
||||||
|
// This test exercises array variables and a trait implemented on immmutable slices.
|
||||||
|
|
||||||
|
trait Read {}
|
||||||
|
|
||||||
|
impl Read for &[u8] {}
|
||||||
|
|
||||||
|
fn wants_read(_: impl Read) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = [0u8];
|
||||||
|
wants_read(x);
|
||||||
|
//~^ ERROR the trait bound `[u8; 1]: Read` is not satisfied
|
||||||
|
wants_read(&x);
|
||||||
|
//~^ ERROR the trait bound `&[u8; 1]: Read` is not satisfied
|
||||||
|
wants_read(&x[..]);
|
||||||
|
|
||||||
|
let x = &[0u8];
|
||||||
|
wants_read(x);
|
||||||
|
//~^ ERROR the trait bound `&[u8; 1]: Read` is not satisfied
|
||||||
|
wants_read(&x);
|
||||||
|
//~^ ERROR the trait bound `&&[u8; 1]: Read` is not satisfied
|
||||||
|
wants_read(*x);
|
||||||
|
//~^ ERROR the trait bound `[u8; 1]: Read` is not satisfied
|
||||||
|
wants_read(&x[..]);
|
||||||
|
}
|
94
tests/ui/dst/issue-90528-unsizing-suggestion-2.stderr
Normal file
94
tests/ui/dst/issue-90528-unsizing-suggestion-2.stderr
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
error[E0277]: the trait bound `[u8; 1]: Read` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-2.rs:14:16
|
||||||
|
|
|
||||||
|
LL | wants_read(x);
|
||||||
|
| ---------- ^ the trait `Read` is not implemented for `[u8; 1]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Read` is implemented for `&[u8]`
|
||||||
|
note: required by a bound in `wants_read`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-2.rs:10:23
|
||||||
|
|
|
||||||
|
LL | fn wants_read(_: impl Read) {}
|
||||||
|
| ^^^^ required by this bound in `wants_read`
|
||||||
|
help: convert the array to a `&[u8]` slice instead
|
||||||
|
|
|
||||||
|
LL | wants_read(&x[..]);
|
||||||
|
| + ++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&[u8; 1]: Read` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-2.rs:16:16
|
||||||
|
|
|
||||||
|
LL | wants_read(&x);
|
||||||
|
| ---------- ^^ the trait `Read` is not implemented for `&[u8; 1]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Read` is implemented for `&[u8]`
|
||||||
|
note: required by a bound in `wants_read`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-2.rs:10:23
|
||||||
|
|
|
||||||
|
LL | fn wants_read(_: impl Read) {}
|
||||||
|
| ^^^^ required by this bound in `wants_read`
|
||||||
|
help: convert the array to a `&[u8]` slice instead
|
||||||
|
|
|
||||||
|
LL | wants_read(&x[..]);
|
||||||
|
| ++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&[u8; 1]: Read` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-2.rs:21:16
|
||||||
|
|
|
||||||
|
LL | wants_read(x);
|
||||||
|
| ---------- ^ the trait `Read` is not implemented for `&[u8; 1]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Read` is implemented for `&[u8]`
|
||||||
|
note: required by a bound in `wants_read`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-2.rs:10:23
|
||||||
|
|
|
||||||
|
LL | fn wants_read(_: impl Read) {}
|
||||||
|
| ^^^^ required by this bound in `wants_read`
|
||||||
|
help: convert the array to a `&[u8]` slice instead
|
||||||
|
|
|
||||||
|
LL | wants_read(&x[..]);
|
||||||
|
| + ++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&&[u8; 1]: Read` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-2.rs:23:16
|
||||||
|
|
|
||||||
|
LL | wants_read(&x);
|
||||||
|
| ---------- ^^ the trait `Read` is not implemented for `&&[u8; 1]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Read` is implemented for `&[u8]`
|
||||||
|
note: required by a bound in `wants_read`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-2.rs:10:23
|
||||||
|
|
|
||||||
|
LL | fn wants_read(_: impl Read) {}
|
||||||
|
| ^^^^ required by this bound in `wants_read`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `[u8; 1]: Read` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-2.rs:25:16
|
||||||
|
|
|
||||||
|
LL | wants_read(*x);
|
||||||
|
| ---------- ^^ the trait `Read` is not implemented for `[u8; 1]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Read` is implemented for `&[u8]`
|
||||||
|
note: required by a bound in `wants_read`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-2.rs:10:23
|
||||||
|
|
|
||||||
|
LL | fn wants_read(_: impl Read) {}
|
||||||
|
| ^^^^ required by this bound in `wants_read`
|
||||||
|
help: convert the array to a `&[u8]` slice instead
|
||||||
|
|
|
||||||
|
LL | wants_read(&*x[..]);
|
||||||
|
| + ++++
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
22
tests/ui/dst/issue-90528-unsizing-suggestion-3.rs
Normal file
22
tests/ui/dst/issue-90528-unsizing-suggestion-3.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Issue #90528: provide helpful suggestions when a trait bound is unsatisfied
|
||||||
|
// due to a missed unsizing coercion.
|
||||||
|
//
|
||||||
|
// This test exercises array literals and a trait implemented on mutable slices.
|
||||||
|
|
||||||
|
trait Write {}
|
||||||
|
|
||||||
|
impl Write for &mut [u8] {}
|
||||||
|
|
||||||
|
fn wants_write(_: impl Write) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
wants_write([0u8]);
|
||||||
|
//~^ ERROR the trait bound `[u8; 1]: Write` is not satisfied
|
||||||
|
wants_write(&mut [0u8]);
|
||||||
|
//~^ ERROR the trait bound `&mut [u8; 1]: Write` is not satisfied
|
||||||
|
wants_write(&mut [0u8][..]);
|
||||||
|
wants_write(&[0u8]);
|
||||||
|
//~^ ERROR the trait bound `&[u8; 1]: Write` is not satisfied
|
||||||
|
wants_write(&[0u8][..]);
|
||||||
|
//~^ ERROR the trait bound `&[u8]: Write` is not satisfied
|
||||||
|
}
|
75
tests/ui/dst/issue-90528-unsizing-suggestion-3.stderr
Normal file
75
tests/ui/dst/issue-90528-unsizing-suggestion-3.stderr
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
error[E0277]: the trait bound `[u8; 1]: Write` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-3.rs:13:17
|
||||||
|
|
|
||||||
|
LL | wants_write([0u8]);
|
||||||
|
| ----------- ^^^^^ the trait `Write` is not implemented for `[u8; 1]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Write` is implemented for `&mut [u8]`
|
||||||
|
note: required by a bound in `wants_write`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-3.rs:10:24
|
||||||
|
|
|
||||||
|
LL | fn wants_write(_: impl Write) {}
|
||||||
|
| ^^^^^ required by this bound in `wants_write`
|
||||||
|
help: convert the array to a `&mut [u8]` slice instead
|
||||||
|
|
|
||||||
|
LL | wants_write(&mut [0u8][..]);
|
||||||
|
| ++++ ++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&mut [u8; 1]: Write` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-3.rs:15:17
|
||||||
|
|
|
||||||
|
LL | wants_write(&mut [0u8]);
|
||||||
|
| ----------- ^^^^^^^^^^ the trait `Write` is not implemented for `&mut [u8; 1]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Write` is implemented for `&mut [u8]`
|
||||||
|
note: required by a bound in `wants_write`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-3.rs:10:24
|
||||||
|
|
|
||||||
|
LL | fn wants_write(_: impl Write) {}
|
||||||
|
| ^^^^^ required by this bound in `wants_write`
|
||||||
|
help: convert the array to a `&mut [u8]` slice instead
|
||||||
|
|
|
||||||
|
LL | wants_write(&mut [0u8][..]);
|
||||||
|
| ++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&[u8; 1]: Write` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-3.rs:18:17
|
||||||
|
|
|
||||||
|
LL | wants_write(&[0u8]);
|
||||||
|
| ----------- ^^^^^^ the trait `Write` is not implemented for `&[u8; 1]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Write` is implemented for `&mut [u8]`
|
||||||
|
note: required by a bound in `wants_write`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-3.rs:10:24
|
||||||
|
|
|
||||||
|
LL | fn wants_write(_: impl Write) {}
|
||||||
|
| ^^^^^ required by this bound in `wants_write`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&[u8]: Write` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-3.rs:20:17
|
||||||
|
|
|
||||||
|
LL | wants_write(&[0u8][..]);
|
||||||
|
| ----------- ^^^^^^^^^^ the trait `Write` is not implemented for `&[u8]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Write` is implemented for `&mut [u8]`
|
||||||
|
note: required by a bound in `wants_write`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-3.rs:10:24
|
||||||
|
|
|
||||||
|
LL | fn wants_write(_: impl Write) {}
|
||||||
|
| ^^^^^ required by this bound in `wants_write`
|
||||||
|
help: consider changing this borrow's mutability
|
||||||
|
|
|
||||||
|
LL | wants_write(&mut [0u8][..]);
|
||||||
|
| ~~~~
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
26
tests/ui/dst/issue-90528-unsizing-suggestion-4.rs
Normal file
26
tests/ui/dst/issue-90528-unsizing-suggestion-4.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Issue #90528: provide helpful suggestions when a trait bound is unsatisfied
|
||||||
|
// due to a missed unsizing coercion.
|
||||||
|
//
|
||||||
|
// This test exercises array variables and a trait implemented on mutable slices.
|
||||||
|
|
||||||
|
trait Write {}
|
||||||
|
|
||||||
|
impl Write for &mut [u8] {}
|
||||||
|
|
||||||
|
fn wants_write(_: impl Write) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut x = [0u8];
|
||||||
|
wants_write(x);
|
||||||
|
//~^ ERROR the trait bound `[u8; 1]: Write` is not satisfied
|
||||||
|
wants_write(&mut x);
|
||||||
|
//~^ ERROR the trait bound `&mut [u8; 1]: Write` is not satisfied
|
||||||
|
wants_write(&mut x[..]);
|
||||||
|
|
||||||
|
let x = &mut [0u8];
|
||||||
|
wants_write(x);
|
||||||
|
//~^ ERROR the trait bound `&mut [u8; 1]: Write` is not satisfied
|
||||||
|
wants_write(*x);
|
||||||
|
//~^ ERROR the trait bound `[u8; 1]: Write` is not satisfied
|
||||||
|
wants_write(&mut x[..]);
|
||||||
|
}
|
79
tests/ui/dst/issue-90528-unsizing-suggestion-4.stderr
Normal file
79
tests/ui/dst/issue-90528-unsizing-suggestion-4.stderr
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
error[E0277]: the trait bound `[u8; 1]: Write` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-4.rs:14:17
|
||||||
|
|
|
||||||
|
LL | wants_write(x);
|
||||||
|
| ----------- ^ the trait `Write` is not implemented for `[u8; 1]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Write` is implemented for `&mut [u8]`
|
||||||
|
note: required by a bound in `wants_write`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-4.rs:10:24
|
||||||
|
|
|
||||||
|
LL | fn wants_write(_: impl Write) {}
|
||||||
|
| ^^^^^ required by this bound in `wants_write`
|
||||||
|
help: convert the array to a `&mut [u8]` slice instead
|
||||||
|
|
|
||||||
|
LL | wants_write(&mut x[..]);
|
||||||
|
| ++++ ++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&mut [u8; 1]: Write` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-4.rs:16:17
|
||||||
|
|
|
||||||
|
LL | wants_write(&mut x);
|
||||||
|
| ----------- ^^^^^^ the trait `Write` is not implemented for `&mut [u8; 1]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Write` is implemented for `&mut [u8]`
|
||||||
|
note: required by a bound in `wants_write`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-4.rs:10:24
|
||||||
|
|
|
||||||
|
LL | fn wants_write(_: impl Write) {}
|
||||||
|
| ^^^^^ required by this bound in `wants_write`
|
||||||
|
help: convert the array to a `&mut [u8]` slice instead
|
||||||
|
|
|
||||||
|
LL | wants_write(&mut x[..]);
|
||||||
|
| ++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&mut [u8; 1]: Write` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-4.rs:21:17
|
||||||
|
|
|
||||||
|
LL | wants_write(x);
|
||||||
|
| ----------- ^ the trait `Write` is not implemented for `&mut [u8; 1]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Write` is implemented for `&mut [u8]`
|
||||||
|
note: required by a bound in `wants_write`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-4.rs:10:24
|
||||||
|
|
|
||||||
|
LL | fn wants_write(_: impl Write) {}
|
||||||
|
| ^^^^^ required by this bound in `wants_write`
|
||||||
|
help: convert the array to a `&mut [u8]` slice instead
|
||||||
|
|
|
||||||
|
LL | wants_write(&mut x[..]);
|
||||||
|
| ++++ ++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `[u8; 1]: Write` is not satisfied
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-4.rs:23:17
|
||||||
|
|
|
||||||
|
LL | wants_write(*x);
|
||||||
|
| ----------- ^^ the trait `Write` is not implemented for `[u8; 1]`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Write` is implemented for `&mut [u8]`
|
||||||
|
note: required by a bound in `wants_write`
|
||||||
|
--> $DIR/issue-90528-unsizing-suggestion-4.rs:10:24
|
||||||
|
|
|
||||||
|
LL | fn wants_write(_: impl Write) {}
|
||||||
|
| ^^^^^ required by this bound in `wants_write`
|
||||||
|
help: convert the array to a `&mut [u8]` slice instead
|
||||||
|
|
|
||||||
|
LL | wants_write(&mut *x[..]);
|
||||||
|
| ++++ ++++
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Reference in New Issue
Block a user