-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
[DRAFT] Make alias bounds sound in the new solver #110628
Conversation
// 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( |
There was a problem hiding this comment.
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>>( |
There was a problem hiding this comment.
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.
// 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 }); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Always coinductive in the new solver. | ||
_ if tcx.trait_solver_next() => true, |
There was a problem hiding this comment.
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>` |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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
…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`
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.