about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-10-02 16:24:05 +0000
committerbors <bors@rust-lang.org>2024-10-02 16:24:05 +0000
commit5384697e9e73709301850a414e1cc40324e6460b (patch)
tree125ebc0214a035ac43fd09ee1a5edade5a3b1603 /compiler/rustc_trait_selection/src
parent44722bd9ba50426191f78d12138a2ae1a12affe7 (diff)
parentb38f7ad9b18ae2bc7e8073e7ec64453ac617f516 (diff)
downloadrust-5384697e9e73709301850a414e1cc40324e6460b.tar.gz
rust-5384697e9e73709301850a414e1cc40324e6460b.zip
Auto merge of #131158 - matthiaskrgr:rollup-3x2vado, r=matthiaskrgr
Rollup of 7 pull requests

Successful merges:

 - #130863 (Relax a debug assertion for dyn principal *equality* in codegen)
 - #131016 (Apple: Do not specify an SDK version in `rlib` object files)
 - #131140 (Handle `rustc_hir_analysis` cases of `potential_query_instability` lint)
 - #131141 (mpmc doctest: make sure main thread waits for child threads)
 - #131150 (only query `params_in_repr` if def kind is adt)
 - #131151 (Replace zero-width whitespace with a visible `\` in the PR template)
 - #131152 (Improve const traits diagnostics for new desugaring)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_trait_selection/src')
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs86
1 files changed, 68 insertions, 18 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 34a0f182ab4..5af117a3f48 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -19,8 +19,8 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::print::{
-    FmtPrinter, Print, PrintTraitPredicateExt as _, PrintTraitRefExt as _,
-    with_forced_trimmed_paths,
+    FmtPrinter, Print, PrintPolyTraitPredicateExt, PrintTraitPredicateExt as _,
+    PrintTraitRefExt as _, with_forced_trimmed_paths,
 };
 use rustc_middle::ty::{
     self, ToPolyTraitRef, TraitRef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, Upcast,
@@ -154,6 +154,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         } else {
                             (leaf_trait_predicate, &obligation)
                         };
+
+                        let (main_trait_predicate, leaf_trait_predicate, predicate_constness) = self.get_effects_trait_pred_override(main_trait_predicate, leaf_trait_predicate, span);
+
                         let main_trait_ref = main_trait_predicate.to_poly_trait_ref();
                         let leaf_trait_ref = leaf_trait_predicate.to_poly_trait_ref();
 
@@ -164,9 +167,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             return guar;
                         }
 
-                        // FIXME(effects)
-                        let predicate_is_const = false;
-
                         if let Err(guar) = leaf_trait_predicate.error_reported()
                         {
                             return guar;
@@ -227,7 +227,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         let err_msg = self.get_standard_error_message(
                             main_trait_predicate,
                             message,
-                            predicate_is_const,
+                            predicate_constness,
                             append_const_msg,
                             post_message,
                         );
@@ -286,7 +286,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         }
 
                         if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Drop)
-                            && predicate_is_const
+                            && matches!(predicate_constness, ty::BoundConstness::ConstIfConst | ty::BoundConstness::Const)
                         {
                             err.note("`~const Drop` was renamed to `~const Destruct`");
                             err.note("See <https://github.com/rust-lang/rust/pull/94901> for more details");
@@ -2187,29 +2187,34 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         &self,
         trait_predicate: ty::PolyTraitPredicate<'tcx>,
         message: Option<String>,
-        predicate_is_const: bool,
+        predicate_constness: ty::BoundConstness,
         append_const_msg: Option<AppendConstMessage>,
         post_message: String,
     ) -> String {
         message
             .and_then(|cannot_do_this| {
-                match (predicate_is_const, append_const_msg) {
+                match (predicate_constness, append_const_msg) {
                     // do nothing if predicate is not const
-                    (false, _) => Some(cannot_do_this),
+                    (ty::BoundConstness::NotConst, _) => Some(cannot_do_this),
                     // suggested using default post message
-                    (true, Some(AppendConstMessage::Default)) => {
-                        Some(format!("{cannot_do_this} in const contexts"))
-                    }
+                    (
+                        ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst,
+                        Some(AppendConstMessage::Default),
+                    ) => Some(format!("{cannot_do_this} in const contexts")),
                     // overridden post message
-                    (true, Some(AppendConstMessage::Custom(custom_msg, _))) => {
-                        Some(format!("{cannot_do_this}{custom_msg}"))
-                    }
+                    (
+                        ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst,
+                        Some(AppendConstMessage::Custom(custom_msg, _)),
+                    ) => Some(format!("{cannot_do_this}{custom_msg}")),
                     // fallback to generic message
-                    (true, None) => None,
+                    (ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst, None) => None,
                 }
             })
             .unwrap_or_else(|| {
-                format!("the trait bound `{trait_predicate}` is not satisfied{post_message}")
+                format!(
+                    "the trait bound `{}` is not satisfied{post_message}",
+                    trait_predicate.print_with_bound_constness(predicate_constness)
+                )
             })
     }
 
@@ -2333,6 +2338,51 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         }
     }
 
+    /// For effects predicates such as `<u32 as Add>::Effects: Compat<host>`, pretend that the
+    /// predicate that failed was `u32: Add`. Return the constness of such predicate to later
+    /// print as `u32: ~const Add`.
+    fn get_effects_trait_pred_override(
+        &self,
+        p: ty::PolyTraitPredicate<'tcx>,
+        leaf: ty::PolyTraitPredicate<'tcx>,
+        span: Span,
+    ) -> (ty::PolyTraitPredicate<'tcx>, ty::PolyTraitPredicate<'tcx>, ty::BoundConstness) {
+        let trait_ref = p.to_poly_trait_ref();
+        if !self.tcx.is_lang_item(trait_ref.def_id(), LangItem::EffectsCompat) {
+            return (p, leaf, ty::BoundConstness::NotConst);
+        }
+
+        let Some(ty::Alias(ty::AliasTyKind::Projection, projection)) =
+            trait_ref.self_ty().no_bound_vars().map(Ty::kind)
+        else {
+            return (p, leaf, ty::BoundConstness::NotConst);
+        };
+
+        let constness = trait_ref.skip_binder().args.const_at(1);
+
+        let constness = if constness == self.tcx.consts.true_ || constness.is_ct_infer() {
+            ty::BoundConstness::NotConst
+        } else if constness == self.tcx.consts.false_ {
+            ty::BoundConstness::Const
+        } else if matches!(constness.kind(), ty::ConstKind::Param(_)) {
+            ty::BoundConstness::ConstIfConst
+        } else {
+            self.dcx().span_bug(span, format!("Unknown constness argument: {constness:?}"));
+        };
+
+        let new_pred = p.map_bound(|mut trait_pred| {
+            trait_pred.trait_ref = projection.trait_ref(self.tcx);
+            trait_pred
+        });
+
+        let new_leaf = leaf.map_bound(|mut trait_pred| {
+            trait_pred.trait_ref = projection.trait_ref(self.tcx);
+            trait_pred
+        });
+
+        (new_pred, new_leaf, constness)
+    }
+
     fn add_tuple_trait_message(
         &self,
         obligation_cause_code: &ObligationCauseCode<'tcx>,