about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-07-02 23:29:03 +0000
committerbors <bors@rust-lang.org>2025-07-02 23:29:03 +0000
commit25face9808491588e59b6d7844f2185b09eef479 (patch)
treeabcc3b9fad3d64a7be4fb2dc6f93293f5a39308b /compiler/rustc_trait_selection/src
parent6677875279b560442a07a08d5119b4cd6b3c5593 (diff)
parentbc8bcc7e8a9d4caf6405c3a2edc1a607df8340e9 (diff)
downloadrust-25face9808491588e59b6d7844f2185b09eef479.tar.gz
rust-25face9808491588e59b6d7844f2185b09eef479.zip
Auto merge of #143338 - matthiaskrgr:rollup-ykaxh04, r=matthiaskrgr
Rollup of 11 pull requests

Successful merges:

 - rust-lang/rust#131923 (Derive `Copy` and `Hash` for `IntErrorKind`)
 - rust-lang/rust#138340 (Remove some unsized tuple impls now that we don't support unsizing tuples anymore)
 - rust-lang/rust#141219 (Change `{Box,Arc,Rc,Weak}::into_raw` to only work with `A = Global`)
 - rust-lang/rust#142212 (bootstrap: validate `rust.codegen-backends` & `target.<triple>.codegen-backends`)
 - rust-lang/rust#142237 (Detect more cases of unused_parens around types)
 - rust-lang/rust#142964 (Attribute rework: a parser for single attributes without arguments)
 - rust-lang/rust#143070 (Rewrite `macro_rules!` parser to not use the MBE engine itself)
 - rust-lang/rust#143235 (Assemble const bounds via normal item bounds in old solver too)
 - rust-lang/rust#143261 (Feed `explicit_predicates_of` instead of `predicates_of`)
 - rust-lang/rust#143276 (loop match: handle opaque patterns)
 - rust-lang/rust#143306 (Add `track_caller` attributes to trace origin of Clippy lints)

r? `@ghost`
`@rustbot` modify labels: rollup

try-job: aarch64-apple
try-job: x86_64-msvc-1
try-job: x86_64-gnu
try-job: dist-i586-gnu-i586-i686-musl
try-job: test-various
Diffstat (limited to 'compiler/rustc_trait_selection/src')
-rw-r--r--compiler/rustc_trait_selection/src/traits/effects.rs67
1 files changed, 66 insertions, 1 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs
index fc95e42d67f..a294981b92d 100644
--- a/compiler/rustc_trait_selection/src/traits/effects.rs
+++ b/compiler/rustc_trait_selection/src/traits/effects.rs
@@ -44,6 +44,12 @@ pub fn evaluate_host_effect_obligation<'tcx>(
         Err(EvaluationFailure::NoSolution) => {}
     }
 
+    match evaluate_host_effect_from_conditionally_const_item_bounds(selcx, obligation) {
+        Ok(result) => return Ok(result),
+        Err(EvaluationFailure::Ambiguous) => return Err(EvaluationFailure::Ambiguous),
+        Err(EvaluationFailure::NoSolution) => {}
+    }
+
     match evaluate_host_effect_from_item_bounds(selcx, obligation) {
         Ok(result) => return Ok(result),
         Err(EvaluationFailure::Ambiguous) => return Err(EvaluationFailure::Ambiguous),
@@ -153,7 +159,9 @@ fn evaluate_host_effect_from_bounds<'tcx>(
     }
 }
 
-fn evaluate_host_effect_from_item_bounds<'tcx>(
+/// Assembles constness bounds from `~const` item bounds on alias types, which only
+/// hold if the `~const` where bounds also hold and the parent trait is `~const`.
+fn evaluate_host_effect_from_conditionally_const_item_bounds<'tcx>(
     selcx: &mut SelectionContext<'_, 'tcx>,
     obligation: &HostEffectObligation<'tcx>,
 ) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
@@ -232,6 +240,63 @@ fn evaluate_host_effect_from_item_bounds<'tcx>(
     }
 }
 
+/// Assembles constness bounds "normal" item bounds on aliases, which may include
+/// unconditionally `const` bounds that are *not* conditional and thus always hold.
+fn evaluate_host_effect_from_item_bounds<'tcx>(
+    selcx: &mut SelectionContext<'_, 'tcx>,
+    obligation: &HostEffectObligation<'tcx>,
+) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
+    let infcx = selcx.infcx;
+    let tcx = infcx.tcx;
+    let drcx = DeepRejectCtxt::relate_rigid_rigid(selcx.tcx());
+    let mut candidate = None;
+
+    let mut consider_ty = obligation.predicate.self_ty();
+    while let ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) = *consider_ty.kind() {
+        for clause in tcx.item_bounds(alias_ty.def_id).iter_instantiated(tcx, alias_ty.args) {
+            let bound_clause = clause.kind();
+            let ty::ClauseKind::HostEffect(data) = bound_clause.skip_binder() else {
+                continue;
+            };
+            let data = bound_clause.rebind(data);
+            if data.skip_binder().trait_ref.def_id != obligation.predicate.trait_ref.def_id {
+                continue;
+            }
+
+            if !drcx.args_may_unify(
+                obligation.predicate.trait_ref.args,
+                data.skip_binder().trait_ref.args,
+            ) {
+                continue;
+            }
+
+            let is_match =
+                infcx.probe(|_| match_candidate(selcx, obligation, data, true, |_, _| {}).is_ok());
+
+            if is_match {
+                if candidate.is_some() {
+                    return Err(EvaluationFailure::Ambiguous);
+                } else {
+                    candidate = Some(data);
+                }
+            }
+        }
+
+        if kind != ty::Projection {
+            break;
+        }
+
+        consider_ty = alias_ty.self_ty();
+    }
+
+    if let Some(data) = candidate {
+        Ok(match_candidate(selcx, obligation, data, true, |_, _| {})
+            .expect("candidate matched before, so it should match again"))
+    } else {
+        Err(EvaluationFailure::NoSolution)
+    }
+}
+
 fn evaluate_host_effect_from_builtin_impls<'tcx>(
     selcx: &mut SelectionContext<'_, 'tcx>,
     obligation: &HostEffectObligation<'tcx>,