about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Wood <david.wood2@arm.com>2025-02-24 08:11:02 +0000
committerDavid Wood <david.wood2@arm.com>2025-02-24 08:52:29 +0000
commit21d41b09dfb782d44da4c487d5c377bf36e9bddc (patch)
tree3816a71d62b3ee035723ed91032105e3db026dfc
parentad27045c31a9f37ad7d44ca2a403de52d1a896d3 (diff)
downloadrust-21d41b09dfb782d44da4c487d5c377bf36e9bddc.tar.gz
rust-21d41b09dfb782d44da4c487d5c377bf36e9bddc.zip
trait_sel: resolve vars in host effects
In the standard library, the `Extend` impl for `Iterator` (specialised
with `TrustedLen`) has a parameter which is constrained by a projection
predicate. This projection predicate provides a value for an inference
variable but host effect evaluation wasn't resolving variables first.

Adding the extra resolve can the number of errors in some tests when they
gain host effect predicates, but this is not unexpected as calls to
`resolve_vars_if_possible` can cause more error tainting to happen.

Co-authored-by: Boxy <rust@boxyuwu.dev>
-rw-r--r--compiler/rustc_trait_selection/src/traits/effects.rs2
-rw-r--r--tests/ui/traits/const-traits/unconstrained-var-specialization.rs36
2 files changed, 38 insertions, 0 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs
index b32909efe0b..3c127416cbf 100644
--- a/compiler/rustc_trait_selection/src/traits/effects.rs
+++ b/compiler/rustc_trait_selection/src/traits/effects.rs
@@ -31,6 +31,8 @@ pub fn evaluate_host_effect_obligation<'tcx>(
         );
     }
 
+    let ref obligation = selcx.infcx.resolve_vars_if_possible(obligation.clone());
+
     // Force ambiguity for infer self ty.
     if obligation.predicate.self_ty().is_ty_var() {
         return Err(EvaluationFailure::Ambiguous);
diff --git a/tests/ui/traits/const-traits/unconstrained-var-specialization.rs b/tests/ui/traits/const-traits/unconstrained-var-specialization.rs
new file mode 100644
index 00000000000..43a33114450
--- /dev/null
+++ b/tests/ui/traits/const-traits/unconstrained-var-specialization.rs
@@ -0,0 +1,36 @@
+//@ check-pass
+//@ compile-flags: --crate-type=lib
+#![no_std]
+#![allow(internal_features)]
+#![feature(rustc_attrs, min_specialization, const_trait_impl)]
+
+// In the default impl below, `A` is constrained by the projection predicate, and if the host effect
+// predicate for `const Foo` doesn't resolve vars, then specialization will fail.
+
+#[const_trait]
+trait Foo {}
+
+pub trait Iterator {
+    type Item;
+}
+
+#[rustc_unsafe_specialization_marker]
+pub trait MoreSpecificThanIterator: Iterator {}
+
+pub trait Tr {
+    fn foo();
+}
+
+impl<A: const Foo, Iter> Tr for Iter
+    where
+        Iter: Iterator<Item = A>,
+{
+    default fn foo() {}
+}
+
+impl<A: const Foo, Iter> Tr for Iter
+    where
+        Iter: MoreSpecificThanIterator<Item = A>,
+{
+    fn foo() {}
+}