Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] Make alias bounds sound in the new solver #110628

Conversation

compiler-errors
Copy link
Member

@compiler-errors compiler-errors commented Apr 20, 2023

r? @ghost

This is not complete (nor is it sound yet, nor is it necessarily ready to even consider yet). Putting this up for self-review with inline comments and discussion with @lcnr mostly.

@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 Apr 20, 2023
// since they're not implied by the well-formedness of the object type.
fn consider_object_bound_candidate(
// since they're not implied by the well-formedness of anything necessarily.
fn consider_non_wf_assumption(
Copy link
Member Author

Choose a reason for hiding this comment

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

This is a version of consider_implied_clause that registers all of the bounds relevant to a trait, namely its supertraits and item bounds. I assume we'll be using this in all of the built-in impls and for user impls too (or something like it).

Naming bikeshed I guess.

@@ -602,4 +612,56 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
}
self.flounder(&responses)
}

#[instrument(level = "debug", skip(self), ret)]
pub(super) fn evaluate_alias_bound_self_is_well_formed<G: GoalKind<'tcx>>(
Copy link
Member Author

Choose a reason for hiding this comment

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

This is the logic we had discussed before, essentially that an alias bound only holds if the trait ref of the alias is satisfied via a param-env candidate.

Comment on lines +641 to +654
// FIXME: Bad bad bad bad bad !!!!!
let lang_items = self.tcx().lang_items();
let trait_def_id = projection_trait_ref.def_id;
let funky_built_in_res = if lang_items.pointee_trait() == Some(trait_def_id) {
G::consider_builtin_pointee_candidate(self, goal)
} else if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
G::consider_builtin_discriminant_kind_candidate(self, goal)
} else {
Err(NoSolution)
};
if let Ok(result) = funky_built_in_res {
param_env_candidates
.push(Candidate { source: CandidateSource::BuiltinImpl, result });
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Comment on lines +525 to +526
// Always coinductive in the new solver.
_ if tcx.trait_solver_next() => true,
Copy link
Member Author

Choose a reason for hiding this comment

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

@@ -0,0 +1,18 @@
error[E0275]: overflow evaluating the requirement `for<'a> dyn for<'a> Trait<'a, for<'a> Item = ()>: Trait<'a>`
Copy link
Member Author

Choose a reason for hiding this comment

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

This goal causes one of those infinite runaways of placeholders in increasingly higher universes, like we see with WF goals currently.

// Can't come up with an example yet, though, and the worst case
// we can have is a compiler stack overflow...
self.assemble_param_env_candidates(trait_goal, &mut param_env_candidates);
self.assemble_alias_bound_candidates(trait_goal, &mut param_env_candidates);
Copy link
Member Author

Choose a reason for hiding this comment

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

We need to consider nested alias bounds here I think - https://hackmd.io/frHMYxD5S4-rWlxkx_eWNw#3-Nested-alias-bound-candidates

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request May 10, 2023
…lcnr

Make alias bounds sound in the new solver (take 2)

Make alias bounds sound in the new solver (in a way that does not require coinduction) by only considering them for projection types whose corresponding trait refs come from a param-env candidate.

That is, given `<T as Trait>::Assoc: Bound`, we only *really* need to consider the alias bound if `T: Trait` is satisfied via a param-env candidate. If it's instead satisfied, e.g., via an user provided impl candidate or a , then that impl should have a concrete type to which we could otherwise normalize `<T as Trait>::Assoc`, and that concrete type is then responsible to prove the `Bound` on it.

Similar consideration is given to opaque types, since we only need to consider alias bounds if we're *not* in reveal-all mode, since similarly we'd be able to reveal the opaque types and prove any bounds that way.

This does not remove that hacky "eager projection replacement" logic from object bounds, which are somewhat like alias bounds. But removing this eager normalization behavior (added in rust-lang#108333) would require full coinduction to be enabled. Compare to rust-lang#110628, which does remove this object-bound custom logic but requires coinduction to be sound.

r? `@lcnr`
@compiler-errors compiler-errors deleted the new-solver-alias-bound-aaaaa branch August 11, 2023 20:08
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.

2 participants