Skip to content

Commit

Permalink
trait_sel: resolve vars in host effects
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
davidtwco and BoxyUwU committed Feb 24, 2025
1 parent ad27045 commit 21d41b0
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_trait_selection/src/traits/effects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
36 changes: 36 additions & 0 deletions tests/ui/traits/const-traits/unconstrained-var-specialization.rs
Original file line number Diff line number Diff line change
@@ -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() {}
}

0 comments on commit 21d41b0

Please sign in to comment.