Rollup merge of #109495 - compiler-errors:new-solver-destruct, r=eholk,lcnr

Implement non-const `Destruct` trait in new solver

Makes it so that we can call stdlib methods like `Option::map` in **non-const** environments, since *many* stdlib methods have `Destruct` bounds 😅

This doesn't bother to implement `const Destruct` yet, but it shouldn't be too hard to do so. Just didn't bother since we already don't have much support for const traits in the new solver anyways. I'd be happy to add skeleton support for `const Destruct`, though, if the reviewer desires.
This commit is contained in:
Matthias Krüger 2023-03-24 07:13:05 +01:00 committed by GitHub
commit 2270bde01f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 0 deletions

View File

@ -212,6 +212,11 @@ fn consider_builtin_discriminant_kind_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx>;
fn consider_builtin_destruct_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx>;
}
impl<'tcx> EvalCtxt<'_, 'tcx> {
@ -340,6 +345,8 @@ fn assemble_builtin_impl_candidates<G: GoalKind<'tcx>>(
G::consider_builtin_unsize_candidate(self, goal)
} else if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
G::consider_builtin_discriminant_kind_candidate(self, goal)
} else if lang_items.destruct_trait() == Some(trait_def_id) {
G::consider_builtin_destruct_candidate(self, goal)
} else {
Err(NoSolution)
};

View File

@ -487,6 +487,13 @@ fn consider_builtin_discriminant_kind_candidate(
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
}
fn consider_builtin_destruct_candidate(
_ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx> {
bug!("`Destruct` does not have an associated type: {:?}", goal);
}
}
/// This behavior is also implemented in `rustc_ty_utils` and in the old `project` code.

View File

@ -534,6 +534,20 @@ fn consider_builtin_discriminant_kind_candidate(
// `DiscriminantKind` is automatically implemented for every type.
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
fn consider_builtin_destruct_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx> {
if !goal.param_env.is_const() {
// `Destruct` is automatically implemented for every type in
// non-const environments.
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
} else {
// FIXME(-Ztrait-solver=next): Implement this when we get const working in the new solver
Err(NoSolution)
}
}
}
impl<'tcx> EvalCtxt<'_, 'tcx> {

View File

@ -1,3 +1,4 @@
// compile-flags: -Ztrait-solver=next
// check-pass
trait Mirror {

View File

@ -0,0 +1,13 @@
// compile-flags: -Ztrait-solver=next
// check-pass
#![feature(const_trait_impl)]
fn foo(_: impl std::marker::Destruct) {}
struct MyAdt;
fn main() {
foo(1);
foo(MyAdt);
}