Skip to content

Commit 528137f

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 8483293 commit 528137f

22 files changed

+128
-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
@@ -839,6 +839,34 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
839839
)) {
840840
diag.downgrade_to_delayed_bug();
841841
}
842+
for candidate in self.find_similar_impl_candidates(trait_ref) {
843+
let CandidateSimilarity::Exact { .. } = candidate.similarity else { continue };
844+
let impl_did = candidate.impl_def_id;
845+
let trait_did = candidate.trait_ref.def_id;
846+
let impl_span = self.tcx.def_span(impl_did);
847+
let trait_name = self.tcx.item_name(trait_did);
848+
849+
if self.tcx.is_const_trait(trait_did) && !self.tcx.is_const_trait_impl(impl_did) {
850+
if let Some(impl_did) = impl_did.as_local()
851+
&& let item = self.tcx.hir_expect_item(impl_did)
852+
&& let hir::ItemKind::Impl(item) = item.kind
853+
&& let Some(of_trait) = item.of_trait
854+
{
855+
// trait is const, impl is local and not const
856+
diag.span_suggestion_verbose(
857+
of_trait.trait_ref.path.span.shrink_to_lo(),
858+
format!("make the `impl` of trait `{trait_name}` `const`"),
859+
"const ".to_string(),
860+
Applicability::MaybeIncorrect,
861+
);
862+
} else {
863+
diag.span_note(
864+
impl_span,
865+
format!("trait `{trait_name}` is implemented but not `const`"),
866+
);
867+
}
868+
}
869+
}
842870
diag
843871
}
844872

tests/ui/consts/const_cmp_type_id.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ error[E0277]: the trait bound `TypeId: const PartialOrd` is not satisfied
33
|
44
LL | let _a = TypeId::of::<u8>() < TypeId::of::<u16>();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: trait `PartialOrd` is implemented but not `const`
8+
--> $SRC_DIR/core/src/any.rs:LL:COL
69

710
error: aborting due to 1 previous error
811

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

0 commit comments

Comments
 (0)