Skip to content

Don't merge distinct impl candidates - #161386

Open
bit-aloo wants to merge 8 commits into
rust-lang:mainfrom
bit-aloo:2026-08-17-merge-impls
Open

bit-aloo wants to merge 8 commits into
rust-lang:mainfrom
bit-aloo:2026-08-17-merge-impls

Conversation

@bit-aloo

Copy link
Copy Markdown
Member

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Aug 20, 2026
@bit-aloo

Copy link
Copy Markdown
Member Author

I am not very confident about fallout bless's: 994cca7

@rust-log-analyzer

This comment has been minimized.

Comment thread compiler/rustc_next_trait_solver/src/solve/trait_goals.rs Outdated
Comment thread compiler/rustc_next_trait_solver/src/solve/trait_goals.rs Outdated
Comment thread compiler/rustc_next_trait_solver/src/solve/trait_goals.rs Outdated
@lcnr

lcnr commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

this fails to bootstrap, probably something related to specialization 🤔 😁 please minimize and look into why

@rust-cloud-vms
rust-cloud-vms Bot force-pushed the 2026-08-17-merge-impls branch from 994cca7 to 36d20a8 Compare August 20, 2026 07:53
@rust-log-analyzer

This comment has been minimized.

@lcnr

lcnr commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 25, 2026
@rust-cloud-vms
rust-cloud-vms Bot force-pushed the 2026-08-17-merge-impls branch from 36d20a8 to 083fa89 Compare September 3, 2026 12:52
@bit-aloo
bit-aloo requested a review from lcnr September 8, 2026 02:12
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Sep 8, 2026
Comment thread tests/ui/traits/next-solver/assembly/merge-marker-trait-impls.rs Outdated
}
}

fn has_distinct_impl_candidates(

@lcnr lcnr Sep 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

maybe instead have a try_merge_impl_candidates which returns a Option<CanonicalResponse<I>> and is None if there are no impls. That might make fn merge_trait_candidates nicer to read 🤔

fn has_distinct_impl_candidates is definitely kinda meh as it checks trait_is_marker in whcih case we allow distinct candidates.

also, please add comments where applicable

the behavior itself lgtm

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Added try_merge_impl_candidates here: 76f0d90, and updated the docs. Thanks.

@rust-cloud-vms
rust-cloud-vms Bot force-pushed the 2026-08-17-merge-impls branch 2 times, most recently from 4fee497 to 76f0d90 Compare September 19, 2026 15:54
@bit-aloo
bit-aloo requested a review from lcnr September 19, 2026 15:57
@rust-cloud-vms
rust-cloud-vms Bot force-pushed the 2026-08-17-merge-impls branch from 76f0d90 to 53e9bd8 Compare September 19, 2026 15:58
Comment on lines 1634 to 1648
self.flounder(&candidates).map(|r| (r, None))
match self.try_merge_impl_candidates(trait_def_id, &candidates) {
Some(response) => Ok((response, Some(proven_via))),
None => self.flounder(&candidates).map(|r| (r, None)),
}

@lcnr lcnr Sep 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

hmm, can you do another change to the structure to make it easier to read (for me)

use

self.try_merge_candidates(&alias_bounds) {
                Ok((response, Some(TraitGoalProvenVia::AliasBound)))
            } else {
                Ok((self.bail_with_ambiguity(&alias_bounds), None))
            };

in the TraitGoalProvenVia::ParamEnv arm. Though, maybe change this pattern to use a new function, like merge_candidates_or_bail_with_ambiguity(&alias_bounds, TraitGoalProvenVia::AliasBound).

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Added helpers here: 6302baf

Comment on lines +1509 to +1522
if !self.cx().trait_is_marker(trait_def_id) {
let impl_count = candidates
.iter()
.filter(|candidate| matches!(candidate.source, CandidateSource::Impl(_)))
.count();
let has_builtin_impl = candidates
.iter()
.any(|candidate| matches!(candidate.source, CandidateSource::BuiltinImpl(_)));
if impl_count + usize::from(has_builtin_impl) > 1 {
return None;
}
}

self.try_merge_candidates(candidates).map(|(response, _)| response)

@lcnr lcnr Sep 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

could you change this to

if is_marker || candidates
                .iter()
                .all(|candidate| matches!(candidate.source, CandidateSource::BuiltinImpl(_))) {
    self.try_merge_candidates(candidates).map(|(response, _)| response)
} else if candidates.len() > 1 {
    None
} else {
    candidates.first().copied() or sth like this
}

View changes since the review

@lcnr lcnr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

some impl style nits, then r=me

sry 😅 i hope you at least agree with me that it makes the code a bit nicer to read

View changes since this review

@rust-cloud-vms
rust-cloud-vms Bot force-pushed the 2026-08-17-merge-impls branch from 53e9bd8 to 6302baf Compare September 22, 2026 03:33
@bit-aloo
bit-aloo requested a review from lcnr September 22, 2026 03:33
trait_def_id: I::TraitId,
candidates: &[Candidate<I>],
) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolution> {
match self.try_merge_impl_candidates(trait_def_id, candidates) {

@lcnr lcnr Sep 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

can you add a debug assert that all candidates are actually impl candidates here?

View changes since the review

Comment on lines +1650 to +1656
let only_global_where_bounds = !candidates.is_empty()
&& candidates
.iter()
.all(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::Global)));
if only_global_where_bounds {
Ok(self
.merge_candidates_or_bail_with_ambiguity(&candidates, TraitGoalProvenVia::ParamEnv))

@lcnr lcnr Sep 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

that !candidates.is_empty() is weird imo 🤔

do we just want to slap a single if candidates.is_empty() to the top of this function and then entirely rip out flounder?

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This makes sense, the only thing flounder added over bail_with_ambiguity was the empty check, so I moved that to the top of merge_trait_candidates as a single early return. With that, every branch now ends in bail_with_ambiguity.

@rust-cloud-vms
rust-cloud-vms Bot force-pushed the 2026-08-17-merge-impls branch from 6302baf to 0c27f4b Compare September 22, 2026 15:19
@bit-aloo
bit-aloo requested a review from lcnr September 22, 2026 15:22

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

overlapping impl candidates are no longer an error

4 participants