add note suggesting that predicate is satisfied but is not const
This commit is contained in:
parent
009c1d0248
commit
1ab97dbc52
@ -803,6 +803,10 @@ pub fn remap_constness_diag(&mut self, param_env: ParamEnv<'tcx>) {
|
||||
p
|
||||
});
|
||||
}
|
||||
|
||||
pub fn is_const(self) -> bool {
|
||||
self.skip_binder().constness == BoundConstness::ConstIfConst
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
|
||||
@ -1388,6 +1392,10 @@ pub fn constness(self) -> hir::Constness {
|
||||
self.packed.tag().constness
|
||||
}
|
||||
|
||||
pub fn is_const(self) -> bool {
|
||||
self.packed.tag().constness == hir::Constness::Const
|
||||
}
|
||||
|
||||
/// Construct a trait environment with no where-clauses in scope
|
||||
/// where the values of all `impl Trait` and other hidden types
|
||||
/// are revealed. This is suitable for monomorphized, post-typeck
|
||||
@ -1503,6 +1511,7 @@ pub fn with_constness(self, constness: BoundConstness) -> PolyTraitPredicate<'tc
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn without_const(self) -> PolyTraitPredicate<'tcx> {
|
||||
self.with_constness(BoundConstness::NotConst)
|
||||
|
@ -439,6 +439,28 @@ fn report_selection_error(
|
||||
} else {
|
||||
err.span_label(span, explanation);
|
||||
}
|
||||
|
||||
if trait_predicate.is_const() && obligation.param_env.is_const() {
|
||||
let non_const_predicate = trait_ref.without_const();
|
||||
let non_const_obligation = Obligation {
|
||||
cause: obligation.cause.clone(),
|
||||
param_env: obligation.param_env.without_const(),
|
||||
predicate: non_const_predicate.to_predicate(tcx),
|
||||
recursion_depth: obligation.recursion_depth,
|
||||
};
|
||||
if self.predicate_may_hold(&non_const_obligation) {
|
||||
err.span_note(
|
||||
span,
|
||||
&format!(
|
||||
"the trait `{}` is implemented for `{}`, \
|
||||
but that implementation is not `const`",
|
||||
non_const_predicate.print_modifiers_and_trait_path(),
|
||||
trait_ref.skip_binder().self_ty(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((msg, span)) = type_def {
|
||||
err.span_label(span, &msg);
|
||||
}
|
||||
|
@ -7,6 +7,11 @@ LL | const_eval_select((), || {}, || {});
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `~const FnOnce<()>` is not implemented for `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:32]`
|
||||
note: the trait `FnOnce<()>` is implemented for `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:32]`, but that implementation is not `const`
|
||||
--> $DIR/const-eval-select-bad.rs:6:27
|
||||
|
|
||||
LL | const_eval_select((), || {}, || {});
|
||||
| ^^^^^
|
||||
= note: wrap the `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:32]` in a closure with no arguments: `|| { /* code */ }`
|
||||
note: required by a bound in `const_eval_select`
|
||||
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||
|
@ -5,6 +5,11 @@ LL | type Bar = NonConstAdd;
|
||||
| ^^^^^^^^^^^ no implementation for `NonConstAdd + NonConstAdd`
|
||||
|
|
||||
= help: the trait `~const Add` is not implemented for `NonConstAdd`
|
||||
note: the trait `Add` is implemented for `NonConstAdd`, but that implementation is not `const`
|
||||
--> $DIR/assoc-type.rs:18:16
|
||||
|
|
||||
LL | type Bar = NonConstAdd;
|
||||
| ^^^^^^^^^^^
|
||||
note: required by a bound in `Foo::Bar`
|
||||
--> $DIR/assoc-type.rs:14:15
|
||||
|
|
||||
|
@ -7,6 +7,11 @@ LL | pub const EQ: bool = equals_self(&S);
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `~const PartialEq` is not implemented for `S`
|
||||
note: the trait `PartialEq` is implemented for `S`, but that implementation is not `const`
|
||||
--> $DIR/call-generic-method-nonconst.rs:19:34
|
||||
|
|
||||
LL | pub const EQ: bool = equals_self(&S);
|
||||
| ^^
|
||||
note: required by a bound in `equals_self`
|
||||
--> $DIR/call-generic-method-nonconst.rs:12:25
|
||||
|
|
||||
|
@ -28,6 +28,11 @@ LL | const _: () = check($exp);
|
||||
LL | ConstImplWithDropGlue(NonTrivialDrop),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Drop` is not implemented for `NonTrivialDrop`
|
||||
|
|
||||
note: the trait `Drop` is implemented for `NonTrivialDrop`, but that implementation is not `const`
|
||||
--> $DIR/const-drop-fail.rs:46:5
|
||||
|
|
||||
LL | ConstImplWithDropGlue(NonTrivialDrop),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: required because it appears within the type `ConstImplWithDropGlue`
|
||||
--> $DIR/const-drop-fail.rs:17:8
|
||||
|
|
||||
|
@ -28,6 +28,11 @@ LL | const _: () = check($exp);
|
||||
LL | ConstImplWithDropGlue(NonTrivialDrop),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Drop` is not implemented for `NonTrivialDrop`
|
||||
|
|
||||
note: the trait `Drop` is implemented for `NonTrivialDrop`, but that implementation is not `const`
|
||||
--> $DIR/const-drop-fail.rs:46:5
|
||||
|
|
||||
LL | ConstImplWithDropGlue(NonTrivialDrop),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: required because it appears within the type `ConstImplWithDropGlue`
|
||||
--> $DIR/const-drop-fail.rs:17:8
|
||||
|
|
||||
|
@ -4,6 +4,11 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied
|
||||
LL | foo::<()>();
|
||||
| ^^ the trait `~const Tr` is not implemented for `()`
|
||||
|
|
||||
note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
|
||||
--> $DIR/default-method-body-is-const-body-checking.rs:12:15
|
||||
|
|
||||
LL | foo::<()>();
|
||||
| ^^
|
||||
note: required by a bound in `foo`
|
||||
--> $DIR/default-method-body-is-const-body-checking.rs:7:28
|
||||
|
|
||||
|
@ -4,6 +4,11 @@ error[E0277]: the trait bound `T: ~const Bar` is not satisfied
|
||||
LL | T::b();
|
||||
| ^^^^ the trait `~const Bar` is not implemented for `T`
|
||||
|
|
||||
note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
|
||||
--> $DIR/trait-where-clause.rs:14:5
|
||||
|
|
||||
LL | T::b();
|
||||
| ^^^^
|
||||
note: required by a bound in `Foo::b`
|
||||
--> $DIR/trait-where-clause.rs:8:24
|
||||
|
|
||||
@ -20,6 +25,11 @@ error[E0277]: the trait bound `T: ~const Bar` is not satisfied
|
||||
LL | T::c::<T>();
|
||||
| ^^^^^^^^^ the trait `~const Bar` is not implemented for `T`
|
||||
|
|
||||
note: the trait `Bar` is implemented for `T`, but that implementation is not `const`
|
||||
--> $DIR/trait-where-clause.rs:16:5
|
||||
|
|
||||
LL | T::c::<T>();
|
||||
| ^^^^^^^^^
|
||||
note: required by a bound in `Foo::c`
|
||||
--> $DIR/trait-where-clause.rs:9:13
|
||||
|
|
||||
|
Loading…
Reference in New Issue
Block a user