about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-01-26 19:09:44 -0800
committerMichael Goulet <michael@errs.io>2022-01-26 19:09:44 -0800
commit1ab97dbc52b76fa5b4bc01a110f366d81560b81d (patch)
tree6b90a98becd7c224ef22fd56d0618abd3dc95efe
parent009c1d02484dcc18e1596a33b3d8989a90361c89 (diff)
downloadrust-1ab97dbc52b76fa5b4bc01a110f366d81560b81d.tar.gz
rust-1ab97dbc52b76fa5b4bc01a110f366d81560b81d.zip
add note suggesting that predicate is satisfied but is not const
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs9
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs22
-rw-r--r--src/test/ui/intrinsics/const-eval-select-bad.stderr5
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr5
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr5
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr5
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr5
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr5
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr10
9 files changed, 71 insertions, 0 deletions
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 6174c922e2d..2d8ee549f48 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -803,6 +803,10 @@ impl<'tcx> PolyTraitPredicate<'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 @@ impl<'tcx> ParamEnv<'tcx> {
         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 @@ impl<'tcx> PolyTraitRef<'tcx> {
             polarity: ty::ImplPolarity::Positive,
         })
     }
+
     #[inline]
     pub fn without_const(self) -> PolyTraitPredicate<'tcx> {
         self.with_constness(BoundConstness::NotConst)
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 37cf41a0ec2..081f823f851 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -439,6 +439,28 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                         } 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);
                         }
diff --git a/src/test/ui/intrinsics/const-eval-select-bad.stderr b/src/test/ui/intrinsics/const-eval-select-bad.stderr
index 083b0064538..06a7a2f63cf 100644
--- a/src/test/ui/intrinsics/const-eval-select-bad.stderr
+++ b/src/test/ui/intrinsics/const-eval-select-bad.stderr
@@ -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
diff --git a/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
index 429b9f3364b..0788b17a1c0 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
@@ -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
    |
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
index 13cffaba91a..35b7fe8e401 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
@@ -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
    |
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
index df776908a03..d280cd2556f 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr
@@ -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
    |
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
index df776908a03..d280cd2556f 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr
@@ -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
    |
diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr
index 05a74757b94..bc807507fd6 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr
@@ -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
    |
diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
index 903cd924ca5..f9b5d81c63b 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr
@@ -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
    |