From d0e4c679ff1772e7ec0f9ca983ac229ffd3db2dc Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 30 Jul 2022 01:33:51 +0000 Subject: [PATCH] Built-in implementation of Tuple trait --- compiler/rustc_middle/src/traits/mod.rs | 11 ++++- compiler/rustc_middle/src/traits/select.rs | 3 ++ .../src/traits/structural_impls.rs | 2 + .../src/traits/project.rs | 6 ++- .../src/traits/select/candidate_assembly.rs | 44 +++++++++++++++++++ .../src/traits/select/confirmation.rs | 2 + .../src/traits/select/mod.rs | 9 ++-- compiler/rustc_ty_utils/src/instance.rs | 3 +- 8 files changed, 72 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 72b848c3ee2..53d22eb0070 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -634,6 +634,10 @@ pub enum ImplSource<'tcx, N> { /// ImplSource for a `const Drop` implementation. ConstDestruct(ImplSourceConstDestructData), + + /// ImplSource for a `std::marker::Tuple` implementation. + /// This has no nested predicates ever, so no data. + Tuple, } impl<'tcx, N> ImplSource<'tcx, N> { @@ -648,7 +652,8 @@ pub fn nested_obligations(self) -> Vec { ImplSource::Object(d) => d.nested, ImplSource::FnPointer(d) => d.nested, ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) - | ImplSource::Pointee(ImplSourcePointeeData) => Vec::new(), + | ImplSource::Pointee(ImplSourcePointeeData) + | ImplSource::Tuple => Vec::new(), ImplSource::TraitAlias(d) => d.nested, ImplSource::TraitUpcasting(d) => d.nested, ImplSource::ConstDestruct(i) => i.nested, @@ -666,7 +671,8 @@ pub fn borrow_nested_obligations(&self) -> &[N] { ImplSource::Object(d) => &d.nested, ImplSource::FnPointer(d) => &d.nested, ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) - | ImplSource::Pointee(ImplSourcePointeeData) => &[], + | ImplSource::Pointee(ImplSourcePointeeData) + | ImplSource::Tuple => &[], ImplSource::TraitAlias(d) => &d.nested, ImplSource::TraitUpcasting(d) => &d.nested, ImplSource::ConstDestruct(i) => &i.nested, @@ -733,6 +739,7 @@ pub fn map(self, f: F) -> ImplSource<'tcx, M> nested: i.nested.into_iter().map(f).collect(), }) } + ImplSource::Tuple => ImplSource::Tuple, } } } diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index e836ba47eed..53af3e90534 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -160,6 +160,9 @@ pub enum SelectionCandidate<'tcx> { /// Implementation of `const Destruct`, optionally from a custom `impl const Drop`. ConstDestructCandidate(Option), + + /// Witnesses the fact that a type is a tuple. + TupleCandidate, } /// The result of trait evaluation. The order is important diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs index 7fbd57ac735..c526344e1f2 100644 --- a/compiler/rustc_middle/src/traits/structural_impls.rs +++ b/compiler/rustc_middle/src/traits/structural_impls.rs @@ -34,6 +34,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d), super::ImplSource::ConstDestruct(ref d) => write!(f, "{:?}", d), + + super::ImplSource::Tuple => write!(f, "ImplSource::Tuple"), } } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index adf47ece69d..f73dce39764 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1625,7 +1625,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( super::ImplSource::AutoImpl(..) | super::ImplSource::Builtin(..) | super::ImplSource::TraitUpcasting(_) - | super::ImplSource::ConstDestruct(_) => { + | super::ImplSource::ConstDestruct(_) + | super::ImplSource::Tuple => { // These traits have no associated types. selcx.tcx().sess.delay_span_bug( obligation.cause.span, @@ -1700,7 +1701,8 @@ fn confirm_select_candidate<'cx, 'tcx>( | super::ImplSource::Builtin(..) | super::ImplSource::TraitUpcasting(_) | super::ImplSource::TraitAlias(..) - | super::ImplSource::ConstDestruct(_) => { + | super::ImplSource::ConstDestruct(_) + | super::ImplSource::Tuple => { // we don't create Select candidates with this kind of resolution span_bug!( obligation.cause.span, diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 50e9b95a445..4d738a49468 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -309,6 +309,8 @@ pub(super) fn assemble_candidates<'o>( // User-defined transmutability impls are permitted. self.assemble_candidates_from_impls(obligation, &mut candidates); self.assemble_candidates_for_transmutability(obligation, &mut candidates); + } else if lang_items.tuple_trait() == Some(def_id) { + self.assemble_candidate_for_tuple(obligation, &mut candidates); } else { if lang_items.clone_trait() == Some(def_id) { // Same builtin conditions as `Copy`, i.e., every type which has builtin support @@ -1009,4 +1011,46 @@ fn assemble_const_destruct_candidates( } } } + + fn assemble_candidate_for_tuple( + &mut self, + obligation: &TraitObligation<'tcx>, + candidates: &mut SelectionCandidateSet<'tcx>, + ) { + let self_ty = self.infcx().shallow_resolve(obligation.self_ty().skip_binder()); + match self_ty.kind() { + ty::Tuple(_) => { + candidates.vec.push(TupleCandidate); + } + ty::Infer(ty::TyVar(_)) => { + candidates.ambiguous = true; + } + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Adt(_, _) + | ty::Foreign(_) + | ty::Str + | ty::Array(_, _) + | ty::Slice(_) + | ty::RawPtr(_) + | ty::Ref(_, _, _) + | ty::FnDef(_, _) + | ty::FnPtr(_) + | ty::Dynamic(_, _) + | ty::Closure(_, _) + | ty::Generator(_, _, _) + | ty::GeneratorWitness(_) + | ty::Never + | ty::Projection(_) + | ty::Opaque(_, _) + | ty::Param(_) + | ty::Bound(_, _) + | ty::Error(_) + | ty::Infer(_) + | ty::Placeholder(_) => {} + } + } } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 2a1099fc82a..ef631167478 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -126,6 +126,8 @@ pub(super) fn confirm_candidate( let data = self.confirm_const_destruct_candidate(obligation, def_id)?; ImplSource::ConstDestruct(data) } + + TupleCandidate => ImplSource::Tuple, }; if !obligation.predicate.is_const_if_const() { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index c01ac197991..561a3e1c038 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1618,7 +1618,8 @@ fn candidate_should_be_dropped_in_favor_of( }; // (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`, - // `DiscriminantKindCandidate`, and `ConstDestructCandidate` to anything else. + // `DiscriminantKindCandidate`, `ConstDestructCandidate`, and `TupleCandidate` + // to anything else. // // This is a fix for #53123 and prevents winnowing from accidentally extending the // lifetime of a variable. @@ -1638,7 +1639,8 @@ fn candidate_should_be_dropped_in_favor_of( BuiltinCandidate { has_nested: false } | DiscriminantKindCandidate | PointeeCandidate - | ConstDestructCandidate(_), + | ConstDestructCandidate(_) + | TupleCandidate, _, ) => true, ( @@ -1646,7 +1648,8 @@ fn candidate_should_be_dropped_in_favor_of( BuiltinCandidate { has_nested: false } | DiscriminantKindCandidate | PointeeCandidate - | ConstDestructCandidate(_), + | ConstDestructCandidate(_) + | TupleCandidate, ) => false, (ParamCandidate(other), ParamCandidate(victim)) => { diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index bd1d568cd9a..8075cb77757 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -397,7 +397,8 @@ fn resolve_associated_item<'tcx>( | traits::ImplSource::DiscriminantKind(..) | traits::ImplSource::Pointee(..) | traits::ImplSource::TraitUpcasting(_) - | traits::ImplSource::ConstDestruct(_) => None, + | traits::ImplSource::ConstDestruct(_) + | traits::ImplSource::Tuple => None, }) } -- 2.44.0