Skip to content

Commit 50d1168

Browse files
committed
Point at non-const trait impl when encountering unmet [const] bound
When encountering an unmet `Ty: [const] Trait` bound, if `Trait` is `#[const_trait]` and there's an `impl Trait for Ty` point at it. If local, suggest `impl const Trait for Ty`, otherwise just point at it. ``` error[E0277]: the trait bound `NonConstAdd: [const] Add` is not satisfied --> $DIR/assoc-type.rs:37:16 | LL | type Bar = NonConstAdd; | ^^^^^^^^^^^ | note: required by a bound in `Foo::Bar` --> $DIR/assoc-type.rs:33:15 | LL | type Bar: [const] Add; | ^^^^^^^^^^^ required by this bound in `Foo::Bar` help: make the `impl` of trait `Add` `const` | LL | impl const Add for NonConstAdd { | +++++ ``` ``` error[E0277]: the trait bound `T: [const] PartialEq` is not satisfied --> tests/ui/traits/const-traits/call-generic-method-fail.rs:5:5 | 5 | *t == *t | ^^^^^^^^ | note: trait `PartialEq` is implemented but not `const` --> /home/gh-estebank/rust/library/core/src/ptr/const_ptr.rs:1590:1 | 1590 | impl<T: PointeeSized> PartialEq for *const T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: trait `PartialEq` is implemented but not `const` --> /home/gh-estebank/rust/library/core/src/ptr/mut_ptr.rs:2011:1 | 2011 | impl<T: PointeeSized> PartialEq for *mut T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ```
1 parent 8231065 commit 50d1168

23 files changed

+130
-0
lines changed

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,34 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
806806
)) {
807807
diag.downgrade_to_delayed_bug();
808808
}
809+
for candidate in self.find_similar_impl_candidates(trait_ref) {
810+
let CandidateSimilarity::Exact { .. } = candidate.similarity else { continue };
811+
let impl_did = candidate.impl_def_id;
812+
let trait_did = candidate.trait_ref.def_id;
813+
let impl_span = self.tcx.def_span(impl_did);
814+
let trait_name = self.tcx.item_name(trait_did);
815+
816+
if self.tcx.is_const_trait(trait_did) && !self.tcx.is_const_trait_impl(impl_did) {
817+
if let Some(impl_did) = impl_did.as_local()
818+
&& let item = self.tcx.hir_expect_item(impl_did)
819+
&& let hir::ItemKind::Impl(item) = item.kind
820+
&& let Some(of_trait) = item.of_trait
821+
{
822+
// trait is const, impl is local and not const
823+
diag.span_suggestion_verbose(
824+
of_trait.path.span.shrink_to_lo(),
825+
format!("make the `impl` of trait `{trait_name}` `const`"),
826+
"const ".to_string(),
827+
Applicability::MachineApplicable,
828+
);
829+
} else {
830+
diag.span_note(
831+
impl_span,
832+
format!("trait `{trait_name}` is implemented but not `const`"),
833+
);
834+
}
835+
}
836+
}
809837
diag
810838
}
811839

tests/ui/traits/const-traits/assoc-type.current.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ note: required by a bound in `Foo::Bar`
99
|
1010
LL | type Bar: [const] Add;
1111
| ^^^^^^^^^^^ required by this bound in `Foo::Bar`
12+
help: make the `impl` of trait `Add` `const`
13+
|
14+
LL | impl const Add for NonConstAdd {
15+
| +++++
1216

1317
error: aborting due to 1 previous error
1418

tests/ui/traits/const-traits/assoc-type.next.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ note: required by a bound in `Foo::Bar`
99
|
1010
LL | type Bar: [const] Add;
1111
| ^^^^^^^^^^^ required by this bound in `Foo::Bar`
12+
help: make the `impl` of trait `Add` `const`
13+
|
14+
LL | impl const Add for NonConstAdd {
15+
| +++++
1216

1317
error: aborting due to 1 previous error
1418

tests/ui/traits/const-traits/call-const-closure.stderr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0277]: the trait bound `(): [const] Bar` is not satisfied
33
|
44
LL | (const || ().foo())();
55
| ^^^
6+
|
7+
help: make the `impl` of trait `Bar` `const`
8+
|
9+
LL | impl const Bar for () {
10+
| +++++
611

712
error: aborting due to 1 previous error
813

tests/ui/traits/const-traits/call-const-trait-method-fail.stderr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0277]: the trait bound `u32: [const] Plus` is not satisfied
33
|
44
LL | a.plus(b)
55
| ^
6+
|
7+
help: make the `impl` of trait `Plus` `const`
8+
|
9+
LL | impl const Plus for u32 {
10+
| +++++
611

712
error: aborting due to 1 previous error
813

tests/ui/traits/const-traits/call-generic-method-fail.stderr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0277]: the trait bound `T: [const] PartialEq` is not satisfied
33
|
44
LL | *t == *t
55
| ^^^^^^^^
6+
|
7+
note: trait `PartialEq` is implemented but not `const`
8+
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
9+
note: trait `PartialEq` is implemented but not `const`
10+
--> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
611

712
error: aborting due to 1 previous error
813

tests/ui/traits/const-traits/call-generic-method-nonconst.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ note: required by a bound in `equals_self`
1111
|
1212
LL | const fn equals_self<T: [const] Foo>(t: &T) -> bool {
1313
| ^^^^^^^^^^^ required by this bound in `equals_self`
14+
help: make the `impl` of trait `Foo` `const`
15+
|
16+
LL | impl const Foo for S {
17+
| +++++
1418

1519
error: aborting due to 1 previous error
1620

tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0277]: the trait bound `(): const Tr` is not satisfied
33
|
44
LL | const _: () = assert!(need_const_closure(Tr::a) == 42);
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
help: make the `impl` of trait `Tr` `const`
8+
|
9+
LL | impl const Tr for () {
10+
| +++++
611

712
error: aborting due to 1 previous error
813

tests/ui/traits/const-traits/const-default-method-bodies.stderr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error[E0277]: the trait bound `NonConstImpl: [const] ConstDefaultFn` is not sati
33
|
44
LL | NonConstImpl.a();
55
| ^
6+
|
7+
help: make the `impl` of trait `ConstDefaultFn` `const`
8+
|
9+
LL | impl const ConstDefaultFn for NonConstImpl {
10+
| +++++
611

712
error: aborting due to 1 previous error
813

tests/ui/traits/const-traits/const-drop-fail-2.precise.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ note: required by a bound in `check`
1616
|
1717
LL | const fn check<T: [const] Destruct>(_: T) {}
1818
| ^^^^^^^^^^^^^^^^ required by this bound in `check`
19+
help: make the `impl` of trait `A` `const`
20+
|
21+
LL | impl const A for NonTrivialDrop {}
22+
| +++++
1923

2024
error: aborting due to 1 previous error
2125

0 commit comments

Comments
 (0)