Skip to content

Commit 8e67570

Browse files
committed
review comments and rebase fix
1 parent c2b5373 commit 8e67570

File tree

2 files changed

+70
-48
lines changed

2 files changed

+70
-48
lines changed

src/librustc_typeck/check/op.rs

Lines changed: 61 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_middle::ty::adjustment::{
1010
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
1111
};
1212
use rustc_middle::ty::TyKind::{Adt, Array, Char, FnDef, Never, Ref, Str, Tuple, Uint};
13-
use rustc_middle::ty::{self, suggest_constraining_type_param, Ty, TypeFoldable};
13+
use rustc_middle::ty::{self, suggest_constraining_type_param, Ty, TyCtxt, TypeFoldable};
1414
use rustc_span::Span;
1515
use rustc_trait_selection::infer::InferCtxtExt;
1616

@@ -254,49 +254,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
254254
if !lhs_ty.references_error() {
255255
let source_map = self.tcx.sess.source_map();
256256

257-
let suggest_constraining_param =
258-
|mut err: &mut DiagnosticBuilder<'_>,
259-
missing_trait: &str,
260-
p: ty::ParamTy,
261-
set_output: bool| {
262-
let hir = self.tcx.hir();
263-
let msg =
264-
&format!("`{}` might need a bound for `{}`", lhs_ty, missing_trait);
265-
if let Some(def_id) = hir
266-
.find(hir.get_parent_item(expr.hir_id))
267-
.and_then(|node| node.hir_id())
268-
.and_then(|hir_id| hir.opt_local_def_id(hir_id))
269-
{
270-
let generics = self.tcx.generics_of(def_id);
271-
let param_def_id = generics.type_param(&p, self.tcx).def_id;
272-
if let Some(generics) = hir
273-
.as_local_hir_id(param_def_id)
274-
.and_then(|id| hir.find(hir.get_parent_item(id)))
275-
.as_ref()
276-
.and_then(|node| node.generics())
277-
{
278-
let output = if set_output {
279-
format!("<Output = {}>", rhs_ty)
280-
} else {
281-
String::new()
282-
};
283-
suggest_constraining_type_param(
284-
self.tcx,
285-
generics,
286-
&mut err,
287-
&format!("{}", lhs_ty),
288-
&format!("{}{}", missing_trait, output),
289-
None,
290-
);
291-
} else {
292-
let span = self.tcx.def_span(param_def_id);
293-
err.span_label(span, msg);
294-
}
295-
} else {
296-
err.note(&msg);
297-
}
298-
};
299-
300257
match is_assign {
301258
IsAssign::Yes => {
302259
let mut err = struct_span_err!(
@@ -362,7 +319,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
362319
// concatenation (e.g., "Hello " += "World!"). This means
363320
// we don't want the note in the else clause to be emitted
364321
} else if let ty::Param(p) = lhs_ty.kind {
365-
suggest_constraining_param(&mut err, missing_trait, p, false);
322+
suggest_constraining_param(
323+
self.tcx,
324+
&mut err,
325+
lhs_ty,
326+
rhs_ty,
327+
&expr,
328+
missing_trait,
329+
p,
330+
false,
331+
);
366332
} else if !suggested_deref {
367333
suggest_impl_missing(&mut err, lhs_ty, &missing_trait);
368334
}
@@ -514,7 +480,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
514480
// we don't want the note in the else clause to be emitted
515481
} else if let ty::Param(p) = lhs_ty.kind {
516482
suggest_constraining_param(
483+
self.tcx,
517484
&mut err,
485+
lhs_ty,
486+
rhs_ty,
487+
&expr,
518488
missing_trait,
519489
p,
520490
use_output,
@@ -965,3 +935,49 @@ fn suggest_impl_missing(err: &mut DiagnosticBuilder<'_>, ty: Ty<'_>, missing_tra
965935
}
966936
}
967937
}
938+
939+
fn suggest_constraining_param(
940+
tcx: TyCtxt<'_>,
941+
mut err: &mut DiagnosticBuilder<'_>,
942+
lhs_ty: Ty<'_>,
943+
rhs_ty: Ty<'_>,
944+
expr: &hir::Expr<'_>,
945+
missing_trait: &str,
946+
p: ty::ParamTy,
947+
set_output: bool,
948+
) {
949+
let hir = tcx.hir();
950+
let msg = &format!("`{}` might need a bound for `{}`", lhs_ty, missing_trait);
951+
// Try to find the def-id and details for the parameter p. We have only the index,
952+
// so we have to find the enclosing function's def-id, then look through its declared
953+
// generic parameters to get the declaration.
954+
if let Some(def_id) = hir
955+
.find(hir.get_parent_item(expr.hir_id))
956+
.and_then(|node| node.hir_id())
957+
.and_then(|hir_id| hir.opt_local_def_id(hir_id))
958+
{
959+
let generics = tcx.generics_of(def_id);
960+
let param_def_id = generics.type_param(&p, tcx).def_id;
961+
if let Some(generics) = hir
962+
.as_local_hir_id(param_def_id)
963+
.and_then(|id| hir.find(hir.get_parent_item(id)))
964+
.as_ref()
965+
.and_then(|node| node.generics())
966+
{
967+
let output = if set_output { format!("<Output = {}>", rhs_ty) } else { String::new() };
968+
suggest_constraining_type_param(
969+
tcx,
970+
generics,
971+
&mut err,
972+
&format!("{}", lhs_ty),
973+
&format!("{}{}", missing_trait, output),
974+
None,
975+
);
976+
} else {
977+
let span = tcx.def_span(param_def_id);
978+
err.span_label(span, msg);
979+
}
980+
} else {
981+
err.note(&msg);
982+
}
983+
}

src/test/ui/issues/issue-20005.stderr

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,18 @@ LL | trait From<Src> {
55
| --- required by this bound in `From`
66
...
77
LL | ) -> <Dst as From<Self>>::Result where Dst: From<Self> {
8-
| ^^^^^^^^^^- help: consider further restricting `Self`: `, Self: std::marker::Sized`
9-
| |
10-
| doesn't have a size known at compile-time
8+
| ^^^^^^^^^^ doesn't have a size known at compile-time
119
|
1210
= help: the trait `std::marker::Sized` is not implemented for `Self`
1311
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
12+
help: consider further restricting `Self`
13+
|
14+
LL | ) -> <Dst as From<Self>>::Result where Dst: From<Self>, Self: std::marker::Sized {
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
16+
help: consider relaxing the implicit `Sized` restriction
17+
|
18+
LL | trait From<Src: ?Sized> {
19+
| ^^^^^^^^
1420

1521
error: aborting due to previous error
1622

0 commit comments

Comments
 (0)