Skip to content

Commit 63be7a2

Browse files
Suggest calling ctor when trait is unimplemented
1 parent a24a020 commit 63be7a2

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
817817

818818
let (def_id, output_ty, callable) = match *self_ty.kind() {
819819
ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig().output(), "closure"),
820-
ty::FnDef(def_id, _) => (def_id, self_ty.fn_sig(self.tcx).output(), "function"),
820+
ty::FnDef(def_id, _) => (
821+
def_id,
822+
self_ty.fn_sig(self.tcx).output(),
823+
match self.tcx.def_kind(def_id) {
824+
DefKind::Ctor(..) => "constructor",
825+
_ => "function",
826+
},
827+
),
821828
_ => return false,
822829
};
823830
let msg = format!("use parentheses to call the {}", callable);
@@ -878,6 +885,16 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
878885
let sugg = format!("({})", args);
879886
(format!("{}{}", ident, sugg), sugg)
880887
}
888+
Some(hir::Node::Ctor(data)) => {
889+
let name = self.tcx.def_path_str(def_id);
890+
err.span_label(
891+
self.tcx.def_span(def_id),
892+
format!("consider calling the constructor for `{}`", name),
893+
);
894+
let args = data.fields().iter().map(|_| "_").collect::<Vec<_>>().join(", ");
895+
let sugg = format!("({})", args);
896+
(format!("{name}{sugg}"), sugg)
897+
}
881898
_ => return false,
882899
};
883900
if matches!(obligation.cause.code(), ObligationCauseCode::FunctionArgumentObligation { .. })
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
fn main() {
2+
insert_resource(Marker);
3+
insert_resource(Time);
4+
//~^ ERROR the trait bound `fn(u32) -> Time {Time}: Resource` is not satisfied
5+
//~| HELP use parentheses to call the constructor
6+
}
7+
8+
trait Resource {}
9+
10+
fn insert_resource<R: Resource>(resource: R) {}
11+
12+
struct Marker;
13+
impl Resource for Marker {}
14+
15+
struct Time(u32);
16+
17+
impl Resource for Time {}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0277]: the trait bound `fn(u32) -> Time {Time}: Resource` is not satisfied
2+
--> $DIR/call-on-unimplemented-ctor.rs:3:21
3+
|
4+
LL | insert_resource(Time);
5+
| --------------- ^^^^ the trait `Resource` is not implemented for fn item `fn(u32) -> Time {Time}`
6+
| |
7+
| required by a bound introduced by this call
8+
...
9+
LL | struct Time(u32);
10+
| ----------- consider calling the constructor for `Time`
11+
|
12+
note: required by a bound in `insert_resource`
13+
--> $DIR/call-on-unimplemented-ctor.rs:10:23
14+
|
15+
LL | fn insert_resource<R: Resource>(resource: R) {}
16+
| ^^^^^^^^ required by this bound in `insert_resource`
17+
help: use parentheses to call the constructor
18+
|
19+
LL | insert_resource(Time(_));
20+
| +++
21+
22+
error: aborting due to previous error
23+
24+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)