Skip to content

Commit b4c6c7a

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 51f5892 commit b4c6c7a

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

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)