Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1143,6 +1143,12 @@ where
// See `tests/ui/winnowing/norm-where-bound-gt-alias-bound.rs`.
if candidates.iter().any(|c| matches!(c.source, CandidateSource::ParamEnv(_))) {
candidates.retain(|c| matches!(c.source, CandidateSource::ParamEnv(_)));
} else if matches!(goal.predicate.self_ty().kind(), ty::Dynamic(..)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should move this into assemble_and_evaluate_candidates as rn this doesn't handle cases where the self type is an alias, e.g. the following should still fail with ur PR

trait Trait {
    type Assoc;
}
trait Id {
    type This;
}
impl<T: ?Sized> Id for T {
    type This = T;
}

fn foo<T>(x: <dyn Trait<Assoc = T> as Trait>::Assoc) -> T
where
    <dyn Trait<Assoc = T> as Id>::This: Trait,
{
    x
}

Copy link
Contributor Author

@adwinwhite adwinwhite Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't fail (after fixing ?Sized bound). And the Assoc projection's self_ty is not alias?
The trait goal in param env has alias self_ty but it's irrelevant for the NormalizesTo goal.

Besides, the following doesn't fail either. Perhaps the self_ty is normalized somehow?

trait Trait {
    type Assoc;
}
trait Id {
    type This: ?Sized;
}
impl<T: ?Sized> Id for T {
    type This = T;
}

fn foo<T>(x: <<dyn Trait<Assoc = T> as Id>::This as Trait>::Assoc) -> T
where
    <dyn Trait<Assoc = T> as Id>::This: Trait,
{
    x
}

Nonetheless, I moved the code into assemble_and_evaluate_candidates and removed comments specific to NormalizesTo goal since trait goals also use this method.

Copy link
Contributor

@lcnr lcnr Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right. I messed up the example.

does the following fail with the old impl? I think the issue is that we otherwise first normalize the inner, and then the outer alias 🤔

trait Trait {
    type Assoc;
}
trait Id<'a> {
    type This: ?Sized;
}
impl<T: ?Sized> Id<'_> for T {
    type This = T;
}

fn foo<T>(x: for<'a> fn(
    <<dyn Trait<Assoc = T> as Id<'a>>::This as Trait>::Assoc
)) -> fn(T)
where
    dyn Trait<Assoc = T>: Trait,
{
    x
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't fail with my first commit.

It turns out when we add NormalizesTo goal for projection Assoc, we also add a nested AliasRelate goal for the inner projection This.
And we evaluate the inner projection before the outer one.
Thus when we evaluate the NormalizesTo goal of Assoc, the self_ty is already normalized.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yeah. we never actually need to normalize the self type for normalization goals 😅 can you still add that one as a test?

// Object candidate may be shadowed by where-bound for the trait goal, see
// `tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs`.
// Trait objects always have their associated types specified so `candidates`
// won't be empty.
self.assemble_object_bound_candidates(goal, &mut candidates);
} else if candidates.is_empty() {
// If the trait goal has been proven by using the environment, we want to treat
// aliases as rigid if there are no applicable projection bounds in the environment.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ compile-flags: -Znext-solver
//@ check-pass

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls add // Regression test for trait-system-refactor-initiative#whatever

trait Trait {
type Assoc;
}

// We have param env candidate for the trait goal but not the projection.
// Under such circumstance, consider object candidate if the self_ty is trait object.
fn foo<T>(x: <dyn Trait<Assoc = T> as Trait>::Assoc) -> T
where
dyn Trait<Assoc = T>: Trait,
{
x
}

fn main() {}
Loading