Skip to content

Commit f194880

Browse files
committed
Suggest constraining type parameter with Clone
Fix #34896.
1 parent 984eab5 commit f194880

File tree

4 files changed

+55
-1
lines changed

4 files changed

+55
-1
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ use rustc_hir_analysis::astconv::AstConv;
1313
use rustc_infer::infer;
1414
use rustc_infer::traits::{self, StatementAsExpression};
1515
use rustc_middle::lint::in_external_macro;
16-
use rustc_middle::ty::{self, Binder, DefIdTree, IsSuggestable, Ty};
16+
use rustc_middle::ty::{
17+
self, suggest_constraining_type_params, Binder, DefIdTree, IsSuggestable, Ty,
18+
};
1719
use rustc_session::errors::ExprParenthesesNeeded;
1820
use rustc_span::symbol::sym;
1921
use rustc_span::Span;
@@ -1293,6 +1295,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12931295
"`{expected_ty}` does not implement `Clone`, so `{found_ty}` was cloned instead"
12941296
),
12951297
);
1298+
let owner = self.tcx.hir().enclosing_body_owner(expr.hir_id);
1299+
if let ty::Param(param) = expected_ty.kind()
1300+
&& let Some(generics) = self.tcx.hir().get_generics(owner)
1301+
{
1302+
suggest_constraining_type_params(
1303+
self.tcx,
1304+
generics,
1305+
diag,
1306+
vec![(param.name.as_str(), "Clone", Some(clone_trait_did))].into_iter(),
1307+
);
1308+
}
12961309
}
12971310
}
12981311

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// run-rustfix
2+
fn wat<T: Clone>(t: &T) -> T {
3+
t.clone() //~ ERROR E0308
4+
}
5+
6+
fn main() {
7+
wat(&42);
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// run-rustfix
2+
fn wat<T>(t: &T) -> T {
3+
t.clone() //~ ERROR E0308
4+
}
5+
6+
fn main() {
7+
wat(&42);
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/clone-on-unconstrained-borrowed-type-param.rs:3:5
3+
|
4+
LL | fn wat<T>(t: &T) -> T {
5+
| - - expected `T` because of return type
6+
| |
7+
| this type parameter
8+
LL | t.clone()
9+
| ^^^^^^^^^ expected type parameter `T`, found `&T`
10+
|
11+
= note: expected type parameter `T`
12+
found reference `&T`
13+
note: `T` does not implement `Clone`, so `&T` was cloned instead
14+
--> $DIR/clone-on-unconstrained-borrowed-type-param.rs:3:5
15+
|
16+
LL | t.clone()
17+
| ^
18+
help: consider restricting type parameter `T`
19+
|
20+
LL | fn wat<T: Clone>(t: &T) -> T {
21+
| +++++++
22+
23+
error: aborting due to previous error
24+
25+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)