Skip to content

Commit

Permalink
Suggest constraining type parameter with Clone
Browse files Browse the repository at this point in the history
Fix #34896.
  • Loading branch information
estebank committed Dec 15, 2022
1 parent 984eab5 commit f194880
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
15 changes: 14 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ use rustc_hir_analysis::astconv::AstConv;
use rustc_infer::infer;
use rustc_infer::traits::{self, StatementAsExpression};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Binder, DefIdTree, IsSuggestable, Ty};
use rustc_middle::ty::{
self, suggest_constraining_type_params, Binder, DefIdTree, IsSuggestable, Ty,
};
use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::symbol::sym;
use rustc_span::Span;
Expand Down Expand Up @@ -1293,6 +1295,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"`{expected_ty}` does not implement `Clone`, so `{found_ty}` was cloned instead"
),
);
let owner = self.tcx.hir().enclosing_body_owner(expr.hir_id);
if let ty::Param(param) = expected_ty.kind()
&& let Some(generics) = self.tcx.hir().get_generics(owner)
{
suggest_constraining_type_params(
self.tcx,
generics,
diag,
vec![(param.name.as_str(), "Clone", Some(clone_trait_did))].into_iter(),
);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// run-rustfix
fn wat<T: Clone>(t: &T) -> T {
t.clone() //~ ERROR E0308
}

fn main() {
wat(&42);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// run-rustfix
fn wat<T>(t: &T) -> T {
t.clone() //~ ERROR E0308
}

fn main() {
wat(&42);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
error[E0308]: mismatched types
--> $DIR/clone-on-unconstrained-borrowed-type-param.rs:3:5
|
LL | fn wat<T>(t: &T) -> T {
| - - expected `T` because of return type
| |
| this type parameter
LL | t.clone()
| ^^^^^^^^^ expected type parameter `T`, found `&T`
|
= note: expected type parameter `T`
found reference `&T`
note: `T` does not implement `Clone`, so `&T` was cloned instead
--> $DIR/clone-on-unconstrained-borrowed-type-param.rs:3:5
|
LL | t.clone()
| ^
help: consider restricting type parameter `T`
|
LL | fn wat<T: Clone>(t: &T) -> T {
| +++++++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

0 comments on commit f194880

Please sign in to comment.