Skip to content

Commit 5eeb1c4

Browse files
Rollup merge of rust-lang#155861 - oli-obk:effect-bound-suggestions, r=jdonszelmann
Suggest `[const] Trait` bounds in more places Right now we have some special logic in the const checker for emitting `[const] Trait` suggestions, but I'm trying to handle that similarly to how it is handled for normal `Trait` clauses. This is just a small step in how it will look on the UX side, which should make my follow-up PRs affect tests less and just be a refactoring
2 parents 6a43d3c + 61e876f commit 5eeb1c4

8 files changed

Lines changed: 63 additions & 7 deletions

File tree

compiler/rustc_hir_analysis/src/check/always_applicable.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,16 +217,26 @@ fn ensure_all_fields_are_const_destruct<'tcx>(
217217
unreachable!()
218218
};
219219
let field_ty = eff.trait_ref.self_ty();
220-
let diag = struct_span_code_err!(
220+
let mut diag = struct_span_code_err!(
221221
tcx.dcx(),
222222
error.root_obligation.cause.span,
223223
E0367,
224224
"`{field_ty}` does not implement `[const] Destruct`",
225225
)
226226
.with_span_note(impl_span, "required for this `Drop` impl");
227-
if field_ty.has_param() {
228-
// FIXME: suggest adding `[const] Destruct` by teaching
229-
// `suggest_restricting_param_bound` about const traits.
227+
if field_ty.has_param()
228+
&& let Some(generics) = tcx.hir_node_by_def_id(impl_def_id).generics()
229+
{
230+
let destruct_def_id = tcx.lang_items().destruct_trait();
231+
ty::suggest_constraining_type_param(
232+
tcx,
233+
generics,
234+
&mut diag,
235+
&field_ty.to_string(),
236+
"[const] Destruct",
237+
destruct_def_id,
238+
None,
239+
);
230240
}
231241
Err(diag.emit())
232242
})

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

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ use rustc_middle::traits::select::OverflowError;
2525
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
2626
use rustc_middle::ty::error::{ExpectedFound, TypeError};
2727
use rustc_middle::ty::print::{
28-
PrintPolyTraitPredicateExt, PrintTraitPredicateExt as _, PrintTraitRefExt as _,
29-
with_forced_trimmed_paths,
28+
PrintPolyTraitPredicateExt, PrintPolyTraitRefExt as _, PrintTraitPredicateExt as _,
29+
PrintTraitRefExt as _, with_forced_trimmed_paths,
3030
};
3131
use rustc_middle::ty::{
3232
self, GenericArgKind, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
@@ -886,6 +886,23 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
886886
);
887887
}
888888
}
889+
} else if let ty::Param(param) = trait_ref.self_ty().skip_binder().kind()
890+
&& let Some(generics) =
891+
self.tcx.hir_node_by_def_id(main_obligation.cause.body_id).generics()
892+
{
893+
let constraint = ty::print::with_no_trimmed_paths!(format!(
894+
"[const] {}",
895+
trait_ref.map_bound(|tr| tr.trait_ref).print_trait_sugared(),
896+
));
897+
ty::suggest_constraining_type_param(
898+
self.tcx,
899+
generics,
900+
&mut diag,
901+
param.name.as_str(),
902+
&constraint,
903+
Some(trait_ref.def_id()),
904+
None,
905+
);
889906
}
890907
diag
891908
}
@@ -2708,7 +2725,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
27082725
fn predicate_can_apply(
27092726
&self,
27102727
param_env: ty::ParamEnv<'tcx>,
2711-
pred: ty::PolyTraitPredicate<'tcx>,
2728+
pred: impl Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>> + TypeFoldable<TyCtxt<'tcx>>,
27122729
) -> bool {
27132730
struct ParamToVarFolder<'a, 'tcx> {
27142731
infcx: &'a InferCtxt<'tcx>,

tests/ui/consts/drop-impl-nonconst-drop-field.stderr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ note: required for this `Drop` impl
2121
|
2222
LL | impl<T> const Drop for ConstDrop2<T> {
2323
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24+
help: consider restricting type parameter `T` with unstable trait `Destruct`
25+
|
26+
LL | impl<T: [const] Destruct> const Drop for ConstDrop2<T> {
27+
| ++++++++++++++++++
2428

2529
error: aborting due to 2 previous errors
2630

tests/ui/consts/trait_alias.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] Baz` is not satisfied
33
|
44
LL | x.baz();
55
| ^^^
6+
|
7+
help: consider further restricting type parameter `T` with trait `Baz`
8+
|
9+
LL | const fn foo<T: [const] Foo + [const] Baz>(x: &T) {
10+
| +++++++++++++
611

712
error: aborting due to 1 previous error
813

tests/ui/consts/trait_alias.next_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] Baz` is not satisfied
33
|
44
LL | x.baz();
55
| ^^^
6+
|
7+
help: consider further restricting type parameter `T` with trait `Baz`
8+
|
9+
LL | const fn foo<T: [const] Foo + [const] Baz>(x: &T) {
10+
| +++++++++++++
611

712
error: aborting due to 1 previous error
813

tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ error[E0277]: the trait bound `T: [const] Foo` is not satisfied
1515
|
1616
LL | x.a();
1717
| ^
18+
|
19+
help: consider further restricting type parameter `T` with trait `Foo`
20+
|
21+
LL | const fn foo<T: Bar + [const] Foo>(x: &T) {
22+
| +++++++++++++
1823

1924
error: aborting due to 2 previous errors
2025

tests/ui/traits/const-traits/super-traits-fail-2.yy.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] Foo` is not satisfied
33
|
44
LL | x.a();
55
| ^
6+
|
7+
help: consider further restricting type parameter `T` with trait `Foo`
8+
|
9+
LL | const fn foo<T: Bar + [const] Foo>(x: &T) {
10+
| +++++++++++++
611

712
error: aborting due to 1 previous error
813

tests/ui/traits/const-traits/super-traits-fail-3.yyn.stderr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ error[E0277]: the trait bound `T: [const] Foo` is not satisfied
3838
|
3939
LL | x.a();
4040
| ^
41+
|
42+
help: consider further restricting type parameter `T` with trait `Foo`
43+
|
44+
LL | const fn foo<T: [const] Bar + [const] Foo>(x: &T) {
45+
| +++++++++++++
4146

4247
error: aborting due to 4 previous errors
4348

0 commit comments

Comments
 (0)