Skip to content

Commit 1ab97db

Browse files
add note suggesting that predicate is satisfied but is not const
1 parent 009c1d0 commit 1ab97db

File tree

9 files changed

+71
-0
lines changed

9 files changed

+71
-0
lines changed

compiler/rustc_middle/src/ty/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,10 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
803803
p
804804
});
805805
}
806+
807+
pub fn is_const(self) -> bool {
808+
self.skip_binder().constness == BoundConstness::ConstIfConst
809+
}
806810
}
807811

808812
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
@@ -1388,6 +1392,10 @@ impl<'tcx> ParamEnv<'tcx> {
13881392
self.packed.tag().constness
13891393
}
13901394

1395+
pub fn is_const(self) -> bool {
1396+
self.packed.tag().constness == hir::Constness::Const
1397+
}
1398+
13911399
/// Construct a trait environment with no where-clauses in scope
13921400
/// where the values of all `impl Trait` and other hidden types
13931401
/// are revealed. This is suitable for monomorphized, post-typeck
@@ -1503,6 +1511,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
15031511
polarity: ty::ImplPolarity::Positive,
15041512
})
15051513
}
1514+
15061515
#[inline]
15071516
pub fn without_const(self) -> PolyTraitPredicate<'tcx> {
15081517
self.with_constness(BoundConstness::NotConst)

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

+22
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,28 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
439439
} else {
440440
err.span_label(span, explanation);
441441
}
442+
443+
if trait_predicate.is_const() && obligation.param_env.is_const() {
444+
let non_const_predicate = trait_ref.without_const();
445+
let non_const_obligation = Obligation {
446+
cause: obligation.cause.clone(),
447+
param_env: obligation.param_env.without_const(),
448+
predicate: non_const_predicate.to_predicate(tcx),
449+
recursion_depth: obligation.recursion_depth,
450+
};
451+
if self.predicate_may_hold(&non_const_obligation) {
452+
err.span_note(
453+
span,
454+
&format!(
455+
"the trait `{}` is implemented for `{}`, \
456+
but that implementation is not `const`",
457+
non_const_predicate.print_modifiers_and_trait_path(),
458+
trait_ref.skip_binder().self_ty(),
459+
),
460+
);
461+
}
462+
}
463+
442464
if let Some((msg, span)) = type_def {
443465
err.span_label(span, &msg);
444466
}

src/test/ui/intrinsics/const-eval-select-bad.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ LL | const_eval_select((), || {}, || {});
77
| required by a bound introduced by this call
88
|
99
= help: the trait `~const FnOnce<()>` is not implemented for `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:32]`
10+
note: the trait `FnOnce<()>` is implemented for `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:32]`, but that implementation is not `const`
11+
--> $DIR/const-eval-select-bad.rs:6:27
12+
|
13+
LL | const_eval_select((), || {}, || {});
14+
| ^^^^^
1015
= note: wrap the `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:32]` in a closure with no arguments: `|| { /* code */ }`
1116
note: required by a bound in `const_eval_select`
1217
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL

src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ LL | type Bar = NonConstAdd;
55
| ^^^^^^^^^^^ no implementation for `NonConstAdd + NonConstAdd`
66
|
77
= help: the trait `~const Add` is not implemented for `NonConstAdd`
8+
note: the trait `Add` is implemented for `NonConstAdd`, but that implementation is not `const`
9+
--> $DIR/assoc-type.rs:18:16
10+
|
11+
LL | type Bar = NonConstAdd;
12+
| ^^^^^^^^^^^
813
note: required by a bound in `Foo::Bar`
914
--> $DIR/assoc-type.rs:14:15
1015
|

src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ LL | pub const EQ: bool = equals_self(&S);
77
| required by a bound introduced by this call
88
|
99
= help: the trait `~const PartialEq` is not implemented for `S`
10+
note: the trait `PartialEq` is implemented for `S`, but that implementation is not `const`
11+
--> $DIR/call-generic-method-nonconst.rs:19:34
12+
|
13+
LL | pub const EQ: bool = equals_self(&S);
14+
| ^^
1015
note: required by a bound in `equals_self`
1116
--> $DIR/call-generic-method-nonconst.rs:12:25
1217
|

src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ LL | const _: () = check($exp);
2828
LL | ConstImplWithDropGlue(NonTrivialDrop),
2929
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Drop` is not implemented for `NonTrivialDrop`
3030
|
31+
note: the trait `Drop` is implemented for `NonTrivialDrop`, but that implementation is not `const`
32+
--> $DIR/const-drop-fail.rs:46:5
33+
|
34+
LL | ConstImplWithDropGlue(NonTrivialDrop),
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3136
note: required because it appears within the type `ConstImplWithDropGlue`
3237
--> $DIR/const-drop-fail.rs:17:8
3338
|

src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ LL | const _: () = check($exp);
2828
LL | ConstImplWithDropGlue(NonTrivialDrop),
2929
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Drop` is not implemented for `NonTrivialDrop`
3030
|
31+
note: the trait `Drop` is implemented for `NonTrivialDrop`, but that implementation is not `const`
32+
--> $DIR/const-drop-fail.rs:46:5
33+
|
34+
LL | ConstImplWithDropGlue(NonTrivialDrop),
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3136
note: required because it appears within the type `ConstImplWithDropGlue`
3237
--> $DIR/const-drop-fail.rs:17:8
3338
|

src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied
44
LL | foo::<()>();
55
| ^^ the trait `~const Tr` is not implemented for `()`
66
|
7+
note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
8+
--> $DIR/default-method-body-is-const-body-checking.rs:12:15
9+
|
10+
LL | foo::<()>();
11+
| ^^
712
note: required by a bound in `foo`
813
--> $DIR/default-method-body-is-const-body-checking.rs:7:28
914
|

src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr

+10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ error[E0277]: the trait bound `T: ~const Bar` is not satisfied
44
LL | T::b();
55
| ^^^^ the trait `~const Bar` is not implemented for `T`
66
|
7+
note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
8+
--> $DIR/trait-where-clause.rs:14:5
9+
|
10+
LL | T::b();
11+
| ^^^^
712
note: required by a bound in `Foo::b`
813
--> $DIR/trait-where-clause.rs:8:24
914
|
@@ -20,6 +25,11 @@ error[E0277]: the trait bound `T: ~const Bar` is not satisfied
2025
LL | T::c::<T>();
2126
| ^^^^^^^^^ the trait `~const Bar` is not implemented for `T`
2227
|
28+
note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
29+
--> $DIR/trait-where-clause.rs:16:5
30+
|
31+
LL | T::c::<T>();
32+
| ^^^^^^^^^
2333
note: required by a bound in `Foo::c`
2434
--> $DIR/trait-where-clause.rs:9:13
2535
|

0 commit comments

Comments
 (0)