From 9fb446d4726c88490c1dd069fa6982c7e5718643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 19 Nov 2019 17:11:55 -0800 Subject: [PATCH] Deduplicate type param constraint suggestion code --- src/librustc/hir/mod.rs | 77 +++++++++++++++++- src/librustc/traits/error_reporting.rs | 81 ++++--------------- .../borrow_check/conflict_errors.rs | 64 ++------------- src/test/ui/binop/binop-consume-args.stderr | 40 ++++----- src/test/ui/binop/binop-move-semantics.stderr | 4 +- .../borrowck/borrowck-unboxed-closures.stderr | 2 +- ...igher-ranker-supertraits-transitive.stderr | 2 +- .../hrtb-higher-ranker-supertraits.stderr | 4 +- src/test/ui/issues/issue-34721.fixed | 2 +- src/test/ui/issues/issue-34721.stderr | 2 +- .../ui/once-cant-call-twice-on-heap.stderr | 2 +- src/test/ui/unop-move-semantics.stderr | 2 +- 12 files changed, 128 insertions(+), 154 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 66bb3a8d883..0b79f624709 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -16,9 +16,9 @@ use crate::ty::AdtKind; use crate::ty::query::Providers; use crate::util::nodemap::{NodeMap, FxHashSet}; -use errors::FatalError; +use errors::{Applicability, DiagnosticBuilder, FatalError}; use syntax_pos::{Span, DUMMY_SP, MultiSpan}; -use syntax::source_map::Spanned; +use syntax::source_map::{Spanned, SourceMap}; use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect}; use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy}; pub use syntax::ast::{Mutability, Constness, Unsafety, Movability, CaptureBy}; @@ -644,6 +644,79 @@ impl Generics { self.params.iter().map(|p| p.span).collect::>().into() } } + + /// Suggest restricting a type param with a new bound. + pub fn suggest_constraining_type_param( + &self, + 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) = self.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 self.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) {}` → `fn foo(t: T) {}` + err.span_suggestion( + param.span, + "consider restricting this bound", + format!("{}: {}", param_name, constraint), + Applicability::MachineApplicable, + ); + } else if !self.where_clause.predicates.is_empty() { + // There is a `where` clause, so suggest expanding it: + // `fn foo(t: T) where T: Debug {}` → + // `fn foo(t: T) where T: Debug, T: Trait {}` + err.span_suggestion( + self.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(t: T, x: X) {}` → `fn foo(t: T) {}` + // `fn foo(t: T) {}` → `fn foo(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`. + 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 + } } /// Synthetic type parameters are converted to another form during lowering; this allows diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 65d08ab03aa..db7c5c3f778 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1091,7 +1091,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 +1102,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 +1136,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 +1158,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 +1187,15 @@ 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) {}` → `fn foo(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) where T: Debug {}` → - // `fn foo(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(t: T, x: X) {}` → `fn foo(t: T) {}` - // `fn foo(t: T) {}` → `fn foo(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`. - 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 generics.suggest_constraining_type_param( + &mut err, + ¶m_name, + &constraint, + self.tcx.sess.source_map(), + *span, + ) { return; } } diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs index e3da090a62d..e9065abcebe 100644 --- a/src/librustc_mir/borrow_check/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/conflict_errors.rs @@ -233,63 +233,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let generics = tcx.generics_of(self.mir_def_id); let param = generics.type_param(¶m_ty, tcx); let generics = tcx.hir().get_generics(self.mir_def_id).unwrap(); - let msg = "consider adding a `Copy` constraint to this type argument"; - for param in generics.params.iter().filter(|p| { - p.name.ident().as_str() == param.name.as_str() - }) { - let param_name = param.name.ident().as_str(); - 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, - msg, - // `impl CurrentTrait + MissingTrait` - format!("{} + Copy", param_name), - 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) {}` → `fn foo(t: T) {}` - err.span_suggestion( - param.span, - msg, - format!("{}: Copy", param_name), - Applicability::MachineApplicable, - ); - } else if !generics.where_clause.predicates.is_empty() { - // There is a `where` clause, so suggest expanding it: - // `fn foo(t: T) where T: Debug {}` → - // `fn foo(t: T) where T: Debug, T: Trait {}` - err.span_suggestion( - generics.where_clause.span().unwrap().shrink_to_hi(), - msg, - format!(", {}: Copy", param_name), - Applicability::MachineApplicable, - ); - } else { - // If there is no `where` clause lean towards constraining to the - // type parameter: - // `fn foo(t: T, x: X) {}` → `fn foo(t: T) {}` - // `fn foo(t: T) {}` → `fn foo(t: T) {}` - let sp = param.span.with_hi(span.hi()); - let span = 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`. - err.span_suggestion(span, msg, format!( - "{}: Copy +", - param_name, - ), Applicability::MachineApplicable); - } else { - err.span_label(param.span, msg); - } - } - } + generics.suggest_constraining_type_param( + &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]; diff --git a/src/test/ui/binop/binop-consume-args.stderr b/src/test/ui/binop/binop-consume-args.stderr index 5a6a2f92583..876e984ecb0 100644 --- a/src/test/ui/binop/binop-consume-args.stderr +++ b/src/test/ui/binop/binop-consume-args.stderr @@ -4,7 +4,7 @@ error[E0382]: use of moved value: `lhs` LL | fn add, B>(lhs: A, rhs: B) { | -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `A: Copy +` + | 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, B>(lhs: A, rhs: B) { | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `B: Copy` + | help: consider restricting this bound: `B: Copy` LL | lhs + rhs; | --- value moved here LL | drop(lhs); @@ -29,7 +29,7 @@ error[E0382]: use of moved value: `lhs` LL | fn sub, B>(lhs: A, rhs: B) { | -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `A: Copy +` + | 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, B>(lhs: A, rhs: B) { | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `B: Copy` + | help: consider restricting this bound: `B: Copy` LL | lhs - rhs; | --- value moved here LL | drop(lhs); @@ -54,7 +54,7 @@ error[E0382]: use of moved value: `lhs` LL | fn mul, B>(lhs: A, rhs: B) { | -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `A: Copy +` + | 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, B>(lhs: A, rhs: B) { | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `B: Copy` + | help: consider restricting this bound: `B: Copy` LL | lhs * rhs; | --- value moved here LL | drop(lhs); @@ -79,7 +79,7 @@ error[E0382]: use of moved value: `lhs` LL | fn div, B>(lhs: A, rhs: B) { | -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `A: Copy +` + | 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, B>(lhs: A, rhs: B) { | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `B: Copy` + | help: consider restricting this bound: `B: Copy` LL | lhs / rhs; | --- value moved here LL | drop(lhs); @@ -104,7 +104,7 @@ error[E0382]: use of moved value: `lhs` LL | fn rem, B>(lhs: A, rhs: B) { | -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `A: Copy +` + | 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, B>(lhs: A, rhs: B) { | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `B: Copy` + | help: consider restricting this bound: `B: Copy` LL | lhs % rhs; | --- value moved here LL | drop(lhs); @@ -129,7 +129,7 @@ error[E0382]: use of moved value: `lhs` LL | fn bitand, B>(lhs: A, rhs: B) { | -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `A: Copy +` + | 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, B>(lhs: A, rhs: B) { | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `B: Copy` + | help: consider restricting this bound: `B: Copy` LL | lhs & rhs; | --- value moved here LL | drop(lhs); @@ -154,7 +154,7 @@ error[E0382]: use of moved value: `lhs` LL | fn bitor, B>(lhs: A, rhs: B) { | -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `A: Copy +` + | 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, B>(lhs: A, rhs: B) { | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `B: Copy` + | help: consider restricting this bound: `B: Copy` LL | lhs | rhs; | --- value moved here LL | drop(lhs); @@ -179,7 +179,7 @@ error[E0382]: use of moved value: `lhs` LL | fn bitxor, B>(lhs: A, rhs: B) { | -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `A: Copy +` + | 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, B>(lhs: A, rhs: B) { | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `B: Copy` + | help: consider restricting this bound: `B: Copy` LL | lhs ^ rhs; | --- value moved here LL | drop(lhs); @@ -204,7 +204,7 @@ error[E0382]: use of moved value: `lhs` LL | fn shl, B>(lhs: A, rhs: B) { | -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `A: Copy +` + | 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, B>(lhs: A, rhs: B) { | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `B: Copy` + | help: consider restricting this bound: `B: Copy` LL | lhs << rhs; | --- value moved here LL | drop(lhs); @@ -229,7 +229,7 @@ error[E0382]: use of moved value: `lhs` LL | fn shr, B>(lhs: A, rhs: B) { | -- --- move occurs because `lhs` has type `A`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `A: Copy +` + | 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, B>(lhs: A, rhs: B) { | - --- move occurs because `rhs` has type `B`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `B: Copy` + | help: consider restricting this bound: `B: Copy` LL | lhs >> rhs; | --- value moved here LL | drop(lhs); diff --git a/src/test/ui/binop/binop-move-semantics.stderr b/src/test/ui/binop/binop-move-semantics.stderr index 8efb73657fa..7552dc66974 100644 --- a/src/test/ui/binop/binop-move-semantics.stderr +++ b/src/test/ui/binop/binop-move-semantics.stderr @@ -4,7 +4,7 @@ error[E0382]: use of moved value: `x` LL | fn double_move>(x: T) { | -- - move occurs because `x` has type `T`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `T: Copy +` + | help: consider further restricting this bound: `T: Copy +` LL | x | - value moved here LL | + @@ -17,7 +17,7 @@ error[E0382]: borrow of moved value: `x` LL | fn move_then_borrow + Clone>(x: T) { | -- - move occurs because `x` has type `T`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `T: Copy +` + | help: consider further restricting this bound: `T: Copy +` LL | x | - value moved here LL | + diff --git a/src/test/ui/borrowck/borrowck-unboxed-closures.stderr b/src/test/ui/borrowck/borrowck-unboxed-closures.stderr index 5a0afda013e..5cd0471cd0d 100644 --- a/src/test/ui/borrowck/borrowck-unboxed-closures.stderr +++ b/src/test/ui/borrowck/borrowck-unboxed-closures.stderr @@ -22,7 +22,7 @@ error[E0382]: use of moved value: `f` LL | fn c isize>(f: F) { | -- - move occurs because `f` has type `F`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `F: Copy +` + | help: consider further restricting this bound: `F: Copy +` LL | f(1, 2); | - value moved here LL | f(1, 2); diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr index afcb467ad47..5c38f47b363 100644 --- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr +++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr @@ -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` diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr index 20913b4f28c..768bc6c7184 100644 --- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr +++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr @@ -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` diff --git a/src/test/ui/issues/issue-34721.fixed b/src/test/ui/issues/issue-34721.fixed index 88f0345bde6..ba2810ee3d7 100644 --- a/src/test/ui/issues/issue-34721.fixed +++ b/src/test/ui/issues/issue-34721.fixed @@ -18,7 +18,7 @@ pub mod bar { mod baz { use bar; use Foo; - pub fn baz(x: T) -> T { + pub fn baz(x: T) -> T { if 0 == 1 { bar::bar(x.zero()) } else { diff --git a/src/test/ui/issues/issue-34721.stderr b/src/test/ui/issues/issue-34721.stderr index abf65afd7ed..3002b07e8c9 100644 --- a/src/test/ui/issues/issue-34721.stderr +++ b/src/test/ui/issues/issue-34721.stderr @@ -4,7 +4,7 @@ error[E0382]: use of moved value: `x` LL | pub fn baz(x: T) -> T { | -- - move occurs because `x` has type `T`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `T: Copy +` + | help: consider further restricting this bound: `T: Copy +` LL | if 0 == 1 { LL | bar::bar(x.zero()) | - value moved here diff --git a/src/test/ui/once-cant-call-twice-on-heap.stderr b/src/test/ui/once-cant-call-twice-on-heap.stderr index 22f98c2a979..fd998060218 100644 --- a/src/test/ui/once-cant-call-twice-on-heap.stderr +++ b/src/test/ui/once-cant-call-twice-on-heap.stderr @@ -4,7 +4,7 @@ error[E0382]: use of moved value: `blk` LL | fn foo(blk: F) { | -- --- move occurs because `blk` has type `F`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `F: Copy +` + | help: consider further restricting this bound: `F: Copy +` LL | blk(); | --- value moved here LL | blk(); diff --git a/src/test/ui/unop-move-semantics.stderr b/src/test/ui/unop-move-semantics.stderr index 0dbd3b8cd0d..092c419d7cb 100644 --- a/src/test/ui/unop-move-semantics.stderr +++ b/src/test/ui/unop-move-semantics.stderr @@ -4,7 +4,7 @@ error[E0382]: borrow of moved value: `x` LL | fn move_then_borrow + Clone>(x: T) { | -- - move occurs because `x` has type `T`, which does not implement the `Copy` trait | | - | help: consider adding a `Copy` constraint to this type argument: `T: Copy +` + | help: consider further restricting this bound: `T: Copy +` LL | !x; | - value moved here LL |