Auto merge of #66567 - estebank:suggest-copy, r=Centril
Use structured suggestion when requiring `Copy` constraint in type param
This commit is contained in:
commit
861e96f2e9
@ -39,6 +39,7 @@ use syntax::ast;
|
||||
use syntax::symbol::{sym, kw};
|
||||
use syntax_pos::{DUMMY_SP, Span, ExpnKind, MultiSpan};
|
||||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
use syntax_pos::source_map::SourceMap;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
@ -1091,7 +1092,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
fn suggest_restricting_param_bound(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
mut err: &mut DiagnosticBuilder<'_>,
|
||||
trait_ref: &ty::PolyTraitRef<'_>,
|
||||
body_id: hir::HirId,
|
||||
) {
|
||||
@ -1102,7 +1103,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let mut suggest_restriction = |generics: &hir::Generics, msg| {
|
||||
let suggest_restriction = |
|
||||
generics: &hir::Generics,
|
||||
msg,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
| {
|
||||
let span = generics.where_clause.span_for_predicates_or_empty_place();
|
||||
if !span.from_expansion() && span.desugaring_kind().is_none() {
|
||||
err.span_suggestion(
|
||||
@ -1132,7 +1137,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
kind: hir::TraitItemKind::Method(..), ..
|
||||
}) if param_ty && self_ty == self.tcx.types.self_param => {
|
||||
// Restricting `Self` for a single method.
|
||||
suggest_restriction(&generics, "`Self`");
|
||||
suggest_restriction(&generics, "`Self`", err);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1154,7 +1159,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
kind: hir::ItemKind::Impl(_, _, _, generics, ..), ..
|
||||
}) if projection.is_some() => {
|
||||
// Missing associated type bound.
|
||||
suggest_restriction(&generics, "the associated type");
|
||||
suggest_restriction(&generics, "the associated type", err);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1183,68 +1188,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
hir::Node::ImplItem(hir::ImplItem { generics, span, .. })
|
||||
if param_ty => {
|
||||
// Missing generic type parameter bound.
|
||||
let restrict_msg = "consider further restricting this bound";
|
||||
let param_name = self_ty.to_string();
|
||||
for param in generics.params.iter().filter(|p| {
|
||||
p.name.ident().as_str() == param_name
|
||||
}) {
|
||||
if param_name.starts_with("impl ") {
|
||||
// `impl Trait` in argument:
|
||||
// `fn foo(x: impl Trait) {}` → `fn foo(t: impl Trait + Trait2) {}`
|
||||
err.span_suggestion(
|
||||
param.span,
|
||||
restrict_msg,
|
||||
// `impl CurrentTrait + MissingTrait`
|
||||
format!("{} + {}", param.name.ident(), trait_ref),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else if generics.where_clause.predicates.is_empty() &&
|
||||
param.bounds.is_empty()
|
||||
{
|
||||
// If there are no bounds whatsoever, suggest adding a constraint
|
||||
// to the type parameter:
|
||||
// `fn foo<T>(t: T) {}` → `fn foo<T: Trait>(t: T) {}`
|
||||
err.span_suggestion(
|
||||
param.span,
|
||||
"consider restricting this bound",
|
||||
format!("{}", trait_ref.to_predicate()),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else if !generics.where_clause.predicates.is_empty() {
|
||||
// There is a `where` clause, so suggest expanding it:
|
||||
// `fn foo<T>(t: T) where T: Debug {}` →
|
||||
// `fn foo<T>(t: T) where T: Debug, T: Trait {}`
|
||||
err.span_suggestion(
|
||||
generics.where_clause.span().unwrap().shrink_to_hi(),
|
||||
&format!(
|
||||
"consider further restricting type parameter `{}`",
|
||||
param_name,
|
||||
),
|
||||
format!(", {}", trait_ref.to_predicate()),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
// If there is no `where` clause lean towards constraining to the
|
||||
// type parameter:
|
||||
// `fn foo<X: Bar, T>(t: T, x: X) {}` → `fn foo<T: Trait>(t: T) {}`
|
||||
// `fn foo<T: Bar>(t: T) {}` → `fn foo<T: Bar + Trait>(t: T) {}`
|
||||
let sp = param.span.with_hi(span.hi());
|
||||
let span = self.tcx.sess.source_map()
|
||||
.span_through_char(sp, ':');
|
||||
if sp != param.span && sp != span {
|
||||
// Only suggest if we have high certainty that the span
|
||||
// covers the colon in `foo<T: Trait>`.
|
||||
err.span_suggestion(span, restrict_msg, format!(
|
||||
"{} + ",
|
||||
trait_ref.to_predicate(),
|
||||
), Applicability::MachineApplicable);
|
||||
} else {
|
||||
err.span_label(param.span, &format!(
|
||||
"consider adding a `where {}` bound",
|
||||
trait_ref.to_predicate(),
|
||||
));
|
||||
}
|
||||
}
|
||||
let constraint = trait_ref.to_string();
|
||||
if suggest_constraining_type_param(
|
||||
generics,
|
||||
&mut err,
|
||||
¶m_name,
|
||||
&constraint,
|
||||
self.tcx.sess.source_map(),
|
||||
*span,
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2546,3 +2499,76 @@ impl ArgKind {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Suggest restricting a type param with a new bound.
|
||||
pub fn suggest_constraining_type_param(
|
||||
generics: &hir::Generics,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
param_name: &str,
|
||||
constraint: &str,
|
||||
source_map: &SourceMap,
|
||||
span: Span,
|
||||
) -> bool {
|
||||
let restrict_msg = "consider further restricting this bound";
|
||||
if let Some(param) = generics.params.iter().filter(|p| {
|
||||
p.name.ident().as_str() == param_name
|
||||
}).next() {
|
||||
if param_name.starts_with("impl ") {
|
||||
// `impl Trait` in argument:
|
||||
// `fn foo(x: impl Trait) {}` → `fn foo(t: impl Trait + Trait2) {}`
|
||||
err.span_suggestion(
|
||||
param.span,
|
||||
restrict_msg,
|
||||
// `impl CurrentTrait + MissingTrait`
|
||||
format!("{} + {}", param_name, constraint),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else if generics.where_clause.predicates.is_empty() &&
|
||||
param.bounds.is_empty()
|
||||
{
|
||||
// If there are no bounds whatsoever, suggest adding a constraint
|
||||
// to the type parameter:
|
||||
// `fn foo<T>(t: T) {}` → `fn foo<T: Trait>(t: T) {}`
|
||||
err.span_suggestion(
|
||||
param.span,
|
||||
"consider restricting this bound",
|
||||
format!("{}: {}", param_name, constraint),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else if !generics.where_clause.predicates.is_empty() {
|
||||
// There is a `where` clause, so suggest expanding it:
|
||||
// `fn foo<T>(t: T) where T: Debug {}` →
|
||||
// `fn foo<T>(t: T) where T: Debug, T: Trait {}`
|
||||
err.span_suggestion(
|
||||
generics.where_clause.span().unwrap().shrink_to_hi(),
|
||||
&format!("consider further restricting type parameter `{}`", param_name),
|
||||
format!(", {}: {}", param_name, constraint),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
// If there is no `where` clause lean towards constraining to the
|
||||
// type parameter:
|
||||
// `fn foo<X: Bar, T>(t: T, x: X) {}` → `fn foo<T: Trait>(t: T) {}`
|
||||
// `fn foo<T: Bar>(t: T) {}` → `fn foo<T: Bar + Trait>(t: T) {}`
|
||||
let sp = param.span.with_hi(span.hi());
|
||||
let span = source_map.span_through_char(sp, ':');
|
||||
if sp != param.span && sp != span {
|
||||
// Only suggest if we have high certainty that the span
|
||||
// covers the colon in `foo<T: Trait>`.
|
||||
err.span_suggestion(
|
||||
span,
|
||||
restrict_msg,
|
||||
format!("{}: {} + ", param_name, constraint),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
err.span_label(
|
||||
param.span,
|
||||
&format!("consider adding a `where {}: {}` bound", param_name, constraint),
|
||||
);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ use rustc::mir::{
|
||||
PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm,
|
||||
};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::traits::error_reporting::suggest_constraining_type_param;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||
@ -231,13 +232,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
if let ty::Param(param_ty) = ty.kind {
|
||||
let tcx = self.infcx.tcx;
|
||||
let generics = tcx.generics_of(self.mir_def_id);
|
||||
let def_id = generics.type_param(¶m_ty, tcx).def_id;
|
||||
if let Some(sp) = tcx.hir().span_if_local(def_id) {
|
||||
err.span_label(
|
||||
sp,
|
||||
"consider adding a `Copy` constraint to this type argument",
|
||||
);
|
||||
}
|
||||
let param = generics.type_param(¶m_ty, tcx);
|
||||
let generics = tcx.hir().get_generics(self.mir_def_id).unwrap();
|
||||
suggest_constraining_type_param(
|
||||
generics,
|
||||
&mut err,
|
||||
¶m.name.as_str(),
|
||||
"Copy",
|
||||
tcx.sess.source_map(),
|
||||
span,
|
||||
);
|
||||
}
|
||||
let span = if let Some(local) = place.as_local() {
|
||||
let decl = &self.body.local_decls[local];
|
||||
|
@ -2,9 +2,9 @@ error[E0382]: use of moved value: `lhs`
|
||||
--> $DIR/binop-consume-args.rs:7:10
|
||||
|
|
||||
LL | fn add<A: Add<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `A: Copy +`
|
||||
LL | lhs + rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -16,7 +16,7 @@ error[E0382]: use of moved value: `rhs`
|
||||
LL | fn add<A: Add<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider restricting this bound: `B: Copy`
|
||||
LL | lhs + rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -27,9 +27,9 @@ error[E0382]: use of moved value: `lhs`
|
||||
--> $DIR/binop-consume-args.rs:13:10
|
||||
|
|
||||
LL | fn sub<A: Sub<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `A: Copy +`
|
||||
LL | lhs - rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -41,7 +41,7 @@ error[E0382]: use of moved value: `rhs`
|
||||
LL | fn sub<A: Sub<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider restricting this bound: `B: Copy`
|
||||
LL | lhs - rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -52,9 +52,9 @@ error[E0382]: use of moved value: `lhs`
|
||||
--> $DIR/binop-consume-args.rs:19:10
|
||||
|
|
||||
LL | fn mul<A: Mul<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `A: Copy +`
|
||||
LL | lhs * rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -66,7 +66,7 @@ error[E0382]: use of moved value: `rhs`
|
||||
LL | fn mul<A: Mul<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider restricting this bound: `B: Copy`
|
||||
LL | lhs * rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -77,9 +77,9 @@ error[E0382]: use of moved value: `lhs`
|
||||
--> $DIR/binop-consume-args.rs:25:10
|
||||
|
|
||||
LL | fn div<A: Div<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `A: Copy +`
|
||||
LL | lhs / rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -91,7 +91,7 @@ error[E0382]: use of moved value: `rhs`
|
||||
LL | fn div<A: Div<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider restricting this bound: `B: Copy`
|
||||
LL | lhs / rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -102,9 +102,9 @@ error[E0382]: use of moved value: `lhs`
|
||||
--> $DIR/binop-consume-args.rs:31:10
|
||||
|
|
||||
LL | fn rem<A: Rem<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `A: Copy +`
|
||||
LL | lhs % rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -116,7 +116,7 @@ error[E0382]: use of moved value: `rhs`
|
||||
LL | fn rem<A: Rem<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider restricting this bound: `B: Copy`
|
||||
LL | lhs % rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -127,9 +127,9 @@ error[E0382]: use of moved value: `lhs`
|
||||
--> $DIR/binop-consume-args.rs:37:10
|
||||
|
|
||||
LL | fn bitand<A: BitAnd<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `A: Copy +`
|
||||
LL | lhs & rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -141,7 +141,7 @@ error[E0382]: use of moved value: `rhs`
|
||||
LL | fn bitand<A: BitAnd<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider restricting this bound: `B: Copy`
|
||||
LL | lhs & rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -152,9 +152,9 @@ error[E0382]: use of moved value: `lhs`
|
||||
--> $DIR/binop-consume-args.rs:43:10
|
||||
|
|
||||
LL | fn bitor<A: BitOr<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `A: Copy +`
|
||||
LL | lhs | rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -166,7 +166,7 @@ error[E0382]: use of moved value: `rhs`
|
||||
LL | fn bitor<A: BitOr<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider restricting this bound: `B: Copy`
|
||||
LL | lhs | rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -177,9 +177,9 @@ error[E0382]: use of moved value: `lhs`
|
||||
--> $DIR/binop-consume-args.rs:49:10
|
||||
|
|
||||
LL | fn bitxor<A: BitXor<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `A: Copy +`
|
||||
LL | lhs ^ rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -191,7 +191,7 @@ error[E0382]: use of moved value: `rhs`
|
||||
LL | fn bitxor<A: BitXor<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider restricting this bound: `B: Copy`
|
||||
LL | lhs ^ rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -202,9 +202,9 @@ error[E0382]: use of moved value: `lhs`
|
||||
--> $DIR/binop-consume-args.rs:55:10
|
||||
|
|
||||
LL | fn shl<A: Shl<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `A: Copy +`
|
||||
LL | lhs << rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -216,7 +216,7 @@ error[E0382]: use of moved value: `rhs`
|
||||
LL | fn shl<A: Shl<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider restricting this bound: `B: Copy`
|
||||
LL | lhs << rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -227,9 +227,9 @@ error[E0382]: use of moved value: `lhs`
|
||||
--> $DIR/binop-consume-args.rs:61:10
|
||||
|
|
||||
LL | fn shr<A: Shr<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `A: Copy +`
|
||||
LL | lhs >> rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
@ -241,7 +241,7 @@ error[E0382]: use of moved value: `rhs`
|
||||
LL | fn shr<A: Shr<B, Output=()>, B>(lhs: A, rhs: B) {
|
||||
| - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider restricting this bound: `B: Copy`
|
||||
LL | lhs >> rhs;
|
||||
| --- value moved here
|
||||
LL | drop(lhs);
|
||||
|
@ -2,9 +2,9 @@ error[E0382]: use of moved value: `x`
|
||||
--> $DIR/binop-move-semantics.rs:8:5
|
||||
|
|
||||
LL | fn double_move<T: Add<Output=()>>(x: T) {
|
||||
| - - move occurs because `x` has type `T`, which does not implement the `Copy` trait
|
||||
| -- - move occurs because `x` has type `T`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `T: Copy +`
|
||||
LL | x
|
||||
| - value moved here
|
||||
LL | +
|
||||
@ -15,9 +15,9 @@ error[E0382]: borrow of moved value: `x`
|
||||
--> $DIR/binop-move-semantics.rs:14:5
|
||||
|
|
||||
LL | fn move_then_borrow<T: Add<Output=()> + Clone>(x: T) {
|
||||
| - - move occurs because `x` has type `T`, which does not implement the `Copy` trait
|
||||
| -- - move occurs because `x` has type `T`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `T: Copy +`
|
||||
LL | x
|
||||
| - value moved here
|
||||
LL | +
|
||||
|
@ -20,9 +20,9 @@ error[E0382]: use of moved value: `f`
|
||||
--> $DIR/borrowck-unboxed-closures.rs:12:5
|
||||
|
|
||||
LL | fn c<F:FnOnce(isize, isize) -> isize>(f: F) {
|
||||
| - - move occurs because `f` has type `F`, which does not implement the `Copy` trait
|
||||
| -- - move occurs because `f` has type `F`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `F: Copy +`
|
||||
LL | f(1, 2);
|
||||
| - value moved here
|
||||
LL | f(1, 2);
|
||||
|
@ -7,7 +7,7 @@ LL | where B : for<'ccx> Bar<'ccx>
|
||||
| ------------------- required by this bound in `want_bar_for_any_ccx`
|
||||
...
|
||||
LL | where B : Qux
|
||||
| - help: consider further restricting type parameter `B`: `, for<'ccx> B: Bar<'ccx>`
|
||||
| - help: consider further restricting type parameter `B`: `, B: for<'ccx> Bar<'ccx>`
|
||||
...
|
||||
LL | want_bar_for_any_ccx(b);
|
||||
| ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
|
||||
|
@ -2,7 +2,7 @@ error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied
|
||||
--> $DIR/hrtb-higher-ranker-supertraits.rs:18:26
|
||||
|
|
||||
LL | where F : Foo<'x>
|
||||
| - help: consider further restricting type parameter `F`: `, for<'tcx> F: Foo<'tcx>`
|
||||
| - help: consider further restricting type parameter `F`: `, F: for<'tcx> Foo<'tcx>`
|
||||
...
|
||||
LL | want_foo_for_any_tcx(f);
|
||||
| ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
|
||||
@ -16,7 +16,7 @@ error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
|
||||
--> $DIR/hrtb-higher-ranker-supertraits.rs:35:26
|
||||
|
|
||||
LL | where B : Bar<'x>
|
||||
| - help: consider further restricting type parameter `B`: `, for<'ccx> B: Bar<'ccx>`
|
||||
| - help: consider further restricting type parameter `B`: `, B: for<'ccx> Bar<'ccx>`
|
||||
...
|
||||
LL | want_bar_for_any_ccx(b);
|
||||
| ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
|
||||
|
34
src/test/ui/issues/issue-34721.fixed
Normal file
34
src/test/ui/issues/issue-34721.fixed
Normal file
@ -0,0 +1,34 @@
|
||||
// run-rustfix
|
||||
|
||||
pub trait Foo {
|
||||
fn zero(self) -> Self;
|
||||
}
|
||||
|
||||
impl Foo for u32 {
|
||||
fn zero(self) -> u32 { 0u32 }
|
||||
}
|
||||
|
||||
pub mod bar {
|
||||
pub use Foo;
|
||||
pub fn bar<T: Foo>(x: T) -> T {
|
||||
x.zero()
|
||||
}
|
||||
}
|
||||
|
||||
mod baz {
|
||||
use bar;
|
||||
use Foo;
|
||||
pub fn baz<T: Copy + Foo>(x: T) -> T {
|
||||
if 0 == 1 {
|
||||
bar::bar(x.zero())
|
||||
} else {
|
||||
x.zero()
|
||||
};
|
||||
x.zero()
|
||||
//~^ ERROR use of moved value
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = baz::baz(0u32);
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
// run-rustfix
|
||||
|
||||
pub trait Foo {
|
||||
fn zero(self) -> Self;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/issue-34721.rs:25:9
|
||||
--> $DIR/issue-34721.rs:27:9
|
||||
|
|
||||
LL | pub fn baz<T: Foo>(x: T) -> T {
|
||||
| - - move occurs because `x` has type `T`, which does not implement the `Copy` trait
|
||||
| -- - move occurs because `x` has type `T`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `T: Copy +`
|
||||
LL | if 0 == 1 {
|
||||
LL | bar::bar(x.zero())
|
||||
| - value moved here
|
||||
|
@ -11,9 +11,9 @@ error[E0382]: borrow of moved value: `f`
|
||||
--> $DIR/moves-based-on-type-no-recursive-stack-closure.rs:32:5
|
||||
|
|
||||
LL | fn conspirator<F>(mut f: F) where F: FnMut(&mut R, bool) {
|
||||
| - ----- move occurs because `f` has type `F`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| ----- - help: consider further restricting type parameter `F`: `, F: Copy`
|
||||
| |
|
||||
| move occurs because `f` has type `F`, which does not implement the `Copy` trait
|
||||
LL | let mut r = R {c: Box::new(f)};
|
||||
| - value moved here
|
||||
LL | f(&mut r, false)
|
||||
|
@ -2,9 +2,9 @@ error[E0382]: use of moved value: `blk`
|
||||
--> $DIR/once-cant-call-twice-on-heap.rs:9:5
|
||||
|
|
||||
LL | fn foo<F:FnOnce()>(blk: F) {
|
||||
| - --- move occurs because `blk` has type `F`, which does not implement the `Copy` trait
|
||||
| -- --- move occurs because `blk` has type `F`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `F: Copy +`
|
||||
LL | blk();
|
||||
| --- value moved here
|
||||
LL | blk();
|
||||
|
@ -2,9 +2,9 @@ error[E0382]: borrow of moved value: `x`
|
||||
--> $DIR/unop-move-semantics.rs:8:5
|
||||
|
|
||||
LL | fn move_then_borrow<T: Not<Output=T> + Clone>(x: T) {
|
||||
| - - move occurs because `x` has type `T`, which does not implement the `Copy` trait
|
||||
| -- - move occurs because `x` has type `T`, which does not implement the `Copy` trait
|
||||
| |
|
||||
| consider adding a `Copy` constraint to this type argument
|
||||
| help: consider further restricting this bound: `T: Copy +`
|
||||
LL | !x;
|
||||
| - value moved here
|
||||
LL |
|
||||
|
Loading…
Reference in New Issue
Block a user