about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDeadbeef <ent3rm4n@gmail.com>2022-07-26 13:57:19 +0000
committerDeadbeef <ent3rm4n@gmail.com>2022-07-26 14:14:21 +0000
commit71e162e6caf3aa64f727f3bc2aa8744f771eb12b (patch)
treef52d38165b3d4774c94123434567bdaaf98a6505
parentd60ebe366bcc6b51e5ae1337288837a0be60ed36 (diff)
downloadrust-71e162e6caf3aa64f727f3bc2aa8744f771eb12b.tar.gz
rust-71e162e6caf3aa64f727f3bc2aa8744f771eb12b.zip
Fix diagnostics for unfulfilled obligations
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs18
-rw-r--r--src/test/ui/const-generics/issues/issue-90318.stderr2
-rw-r--r--src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr10
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-generic-method-fail.stderr8
5 files changed, 20 insertions, 26 deletions
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 281a1265546..31c523aaca9 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -829,6 +829,14 @@ impl<'tcx> TraitPredicate<'tcx> {
     pub fn is_const_if_const(self) -> bool {
         self.constness == BoundConstness::ConstIfConst
     }
+
+    pub fn is_constness_satisfied_by(self, constness: hir::Constness) -> bool {
+        match (self.constness, constness) {
+            (BoundConstness::NotConst, _)
+            | (BoundConstness::ConstIfConst, hir::Constness::Const) => true,
+            (BoundConstness::ConstIfConst, hir::Constness::NotConst) => false,
+        }
+    }
 }
 
 impl<'tcx> PolyTraitPredicate<'tcx> {
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 41c5087c43d..c77540b2f46 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -666,7 +666,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                             );
                         } else if !suggested {
                             // Can't show anything else useful, try to find similar impls.
-                            let impl_candidates = self.find_similar_impl_candidates(trait_ref);
+                            let impl_candidates = self.find_similar_impl_candidates(trait_predicate);
                             if !self.report_similar_impl_candidates(
                                 impl_candidates,
                                 trait_ref,
@@ -701,7 +701,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                                 {
                                     let trait_ref = trait_pred.to_poly_trait_ref();
                                     let impl_candidates =
-                                        self.find_similar_impl_candidates(trait_ref);
+                                        self.find_similar_impl_candidates(trait_pred);
                                     self.report_similar_impl_candidates(
                                         impl_candidates,
                                         trait_ref,
@@ -1325,7 +1325,7 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
 
     fn find_similar_impl_candidates(
         &self,
-        trait_ref: ty::PolyTraitRef<'tcx>,
+        trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> Vec<ImplCandidate<'tcx>>;
 
     fn report_similar_impl_candidates(
@@ -1694,18 +1694,22 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
 
     fn find_similar_impl_candidates(
         &self,
-        trait_ref: ty::PolyTraitRef<'tcx>,
+        trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> Vec<ImplCandidate<'tcx>> {
         self.tcx
-            .all_impls(trait_ref.def_id())
+            .all_impls(trait_pred.def_id())
             .filter_map(|def_id| {
-                if self.tcx.impl_polarity(def_id) == ty::ImplPolarity::Negative {
+                if self.tcx.impl_polarity(def_id) == ty::ImplPolarity::Negative
+                    || !trait_pred
+                        .skip_binder()
+                        .is_constness_satisfied_by(self.tcx.constness(def_id))
+                {
                     return None;
                 }
 
                 let imp = self.tcx.impl_trait_ref(def_id).unwrap();
 
-                self.fuzzy_match_tys(trait_ref.skip_binder().self_ty(), imp.self_ty(), false)
+                self.fuzzy_match_tys(trait_pred.skip_binder().self_ty(), imp.self_ty(), false)
                     .map(|similarity| ImplCandidate { trait_ref: imp, similarity })
             })
             .collect()
diff --git a/src/test/ui/const-generics/issues/issue-90318.stderr b/src/test/ui/const-generics/issues/issue-90318.stderr
index 30eb4eba4a6..aba4b5c1a8d 100644
--- a/src/test/ui/const-generics/issues/issue-90318.stderr
+++ b/src/test/ui/const-generics/issues/issue-90318.stderr
@@ -10,7 +10,6 @@ note: the trait `PartialEq<_>` is implemented for `TypeId`, but that implementat
    |
 LL |     If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
    |                            ^^
-   = help: the trait `PartialEq` is implemented for `TypeId`
 
 error[E0277]: can't compare `TypeId` with `_` in const contexts
   --> $DIR/issue-90318.rs:21:28
@@ -24,7 +23,6 @@ note: the trait `PartialEq<_>` is implemented for `TypeId`, but that implementat
    |
 LL |     If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
    |                            ^^
-   = help: the trait `PartialEq` is implemented for `TypeId`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr
index 02d01445aa1..8a1b20a3345 100644
--- a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr
+++ b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr
@@ -10,16 +10,6 @@ note: the trait `PartialEq<_>` is implemented for `fn()`, but that implementatio
    |
 LL |     unsafe { x == y }
    |                ^^
-   = help: the following other types implement trait `PartialEq<Rhs>`:
-             extern "C" fn() -> Ret
-             extern "C" fn(A, B) -> Ret
-             extern "C" fn(A, B, ...) -> Ret
-             extern "C" fn(A, B, C) -> Ret
-             extern "C" fn(A, B, C, ...) -> Ret
-             extern "C" fn(A, B, C, D) -> Ret
-             extern "C" fn(A, B, C, D, ...) -> Ret
-             extern "C" fn(A, B, C, D, E) -> Ret
-           and 68 others
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-fail.stderr b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-fail.stderr
index b011a2916fb..83d395dda19 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-fail.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-fail.stderr
@@ -9,13 +9,7 @@ note: the trait `PartialEq<_>` is implemented for `T`, but that implementation i
    |
 LL |     *t == *t
    |        ^^
-   = help: the following other types implement trait `PartialEq<Rhs>`:
-             <&A as PartialEq<&B>>
-             <&A as PartialEq<&mut B>>
-             <&mut A as PartialEq<&B>>
-             <&mut A as PartialEq<&mut B>>
-             <*const T as PartialEq>
-             <*mut T as PartialEq>
+   = help: the trait `PartialEq<&B>` is implemented for `&A`
 
 error: aborting due to previous error