Skip to content

Commit de81007

Browse files
Consolidate trait upcasting and unsize into one normalization
1 parent c02d1a6 commit de81007

File tree

4 files changed

+237
-197
lines changed

4 files changed

+237
-197
lines changed

compiler/rustc_trait_selection/src/solve/assembly/mod.rs

+10-15
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ pub(super) enum CandidateSource {
9494
#[derive(Debug, Clone, Copy)]
9595
pub(super) enum BuiltinImplSource {
9696
TraitUpcasting,
97+
TupleUnsize,
9798
Object,
9899
Misc,
99100
Ambiguity,
@@ -281,20 +282,19 @@ pub(super) trait GoalKind<'tcx>:
281282
goal: Goal<'tcx, Self>,
282283
) -> QueryResult<'tcx>;
283284

285+
/// Consider (possibly several) goals to upcast or unsize a type to another
286+
/// type.
287+
///
284288
/// The most common forms of unsizing are array to slice, and concrete (Sized)
285289
/// type into a `dyn Trait`. ADTs and Tuples can also have their final field
286290
/// unsized if it's generic.
287-
fn consider_builtin_unsize_candidate(
288-
ecx: &mut EvalCtxt<'_, 'tcx>,
289-
goal: Goal<'tcx, Self>,
290-
) -> QueryResult<'tcx>;
291-
291+
///
292292
/// `dyn Trait1` can be unsized to `dyn Trait2` if they are the same trait, or
293293
/// if `Trait2` is a (transitive) supertrait of `Trait2`.
294-
fn consider_builtin_dyn_upcast_candidates(
295-
ecx: &mut EvalCtxt<'_, 'tcx>,
294+
fn consider_builtin_unsize_and_upcast_candidates(
295+
_ecx: &mut EvalCtxt<'_, 'tcx>,
296296
goal: Goal<'tcx, Self>,
297-
) -> Vec<CanonicalResponse<'tcx>>;
297+
) -> Vec<(CanonicalResponse<'tcx>, BuiltinImplSource)>;
298298

299299
fn consider_builtin_discriminant_kind_candidate(
300300
ecx: &mut EvalCtxt<'_, 'tcx>,
@@ -610,8 +610,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
610610
G::consider_builtin_future_candidate(self, goal)
611611
} else if lang_items.gen_trait() == Some(trait_def_id) {
612612
G::consider_builtin_generator_candidate(self, goal)
613-
} else if lang_items.unsize_trait() == Some(trait_def_id) {
614-
G::consider_builtin_unsize_candidate(self, goal)
615613
} else if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
616614
G::consider_builtin_discriminant_kind_candidate(self, goal)
617615
} else if lang_items.destruct_trait() == Some(trait_def_id) {
@@ -633,11 +631,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
633631
// There may be multiple unsize candidates for a trait with several supertraits:
634632
// `trait Foo: Bar<A> + Bar<B>` and `dyn Foo: Unsize<dyn Bar<_>>`
635633
if lang_items.unsize_trait() == Some(trait_def_id) {
636-
for result in G::consider_builtin_dyn_upcast_candidates(self, goal) {
637-
candidates.push(Candidate {
638-
source: CandidateSource::BuiltinImpl(BuiltinImplSource::TraitUpcasting),
639-
result,
640-
});
634+
for (result, source) in G::consider_builtin_unsize_and_upcast_candidates(self, goal) {
635+
candidates.push(Candidate { source: CandidateSource::BuiltinImpl(source), result });
641636
}
642637
}
643638
}

compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,19 @@ impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> {
116116
),
117117
) => rematch_object(self, goal, nested_obligations),
118118

119-
(Certainty::Maybe(_), CandidateSource::BuiltinImpl(BuiltinImplSource::Misc))
119+
(
120+
Certainty::Maybe(_),
121+
CandidateSource::BuiltinImpl(
122+
BuiltinImplSource::Misc | BuiltinImplSource::TupleUnsize,
123+
),
124+
) if self.tcx.lang_items().unsize_trait() == Some(goal.predicate.def_id()) => {
125+
rematch_unsize(self, goal, nested_obligations)
126+
}
127+
128+
(Certainty::Yes, CandidateSource::BuiltinImpl(BuiltinImplSource::TupleUnsize))
120129
if self.tcx.lang_items().unsize_trait() == Some(goal.predicate.def_id()) =>
121130
{
122-
rematch_unsize(self, goal, nested_obligations)
131+
Ok(Some(ImplSource::TupleUnsizing(nested_obligations)))
123132
}
124133

125134
// Technically some builtin impls have nested obligations, but if

compiler/rustc_trait_selection/src/solve/project_goals.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::traits::specialization_graph;
22

3-
use super::assembly::{self, structural_traits};
3+
use super::assembly::{self, structural_traits, BuiltinImplSource};
44
use super::EvalCtxt;
55
use rustc_hir::def::DefKind;
66
use rustc_hir::def_id::DefId;
@@ -502,17 +502,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
502502
)
503503
}
504504

505-
fn consider_builtin_unsize_candidate(
505+
fn consider_builtin_unsize_and_upcast_candidates(
506506
_ecx: &mut EvalCtxt<'_, 'tcx>,
507507
goal: Goal<'tcx, Self>,
508-
) -> QueryResult<'tcx> {
509-
bug!("`Unsize` does not have an associated type: {:?}", goal);
510-
}
511-
512-
fn consider_builtin_dyn_upcast_candidates(
513-
_ecx: &mut EvalCtxt<'_, 'tcx>,
514-
goal: Goal<'tcx, Self>,
515-
) -> Vec<CanonicalResponse<'tcx>> {
508+
) -> Vec<(CanonicalResponse<'tcx>, BuiltinImplSource)> {
516509
bug!("`Unsize` does not have an associated type: {:?}", goal);
517510
}
518511

0 commit comments

Comments
 (0)