From 21d41b09dfb782d44da4c487d5c377bf36e9bddc Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 24 Feb 2025 08:11:02 +0000 Subject: [PATCH] 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 --- .../src/traits/effects.rs | 2 ++ .../unconstrained-var-specialization.rs | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 tests/ui/traits/const-traits/unconstrained-var-specialization.rs diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index b32909efe0be7..3c127416cbf7c 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 0000000000000..43a3311445012 --- /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 Tr for Iter + where + Iter: Iterator, +{ + default fn foo() {} +} + +impl Tr for Iter + where + Iter: MoreSpecificThanIterator, +{ + fn foo() {} +}