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:
commit
2270bde01f
@ -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)
|
||||
};
|
||||
|
@ -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.
|
||||
|
@ -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> {
|
||||
|
@ -1,3 +1,4 @@
|
||||
// compile-flags: -Ztrait-solver=next
|
||||
// check-pass
|
||||
|
||||
trait Mirror {
|
||||
|
13
tests/ui/traits/new-solver/destruct.rs
Normal file
13
tests/ui/traits/new-solver/destruct.rs
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user