Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 3194958

Browse files
committed
Auto merge of rust-lang#100251 - compiler-errors:tuple-trait-2, r=jackh726
Implement `std::marker::Tuple` Split out from rust-lang#99943 (rust-lang#99943 (review)). Implements part of rust-lang/compiler-team#537 r? `@jackh726`
2 parents fa521a4 + 109cc1d commit 3194958

File tree

15 files changed

+181
-11
lines changed

15 files changed

+181
-11
lines changed

compiler/rustc_hir/src/lang_items.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ language_item_table! {
289289

290290
Try, sym::Try, try_trait, Target::Trait, GenericRequirement::None;
291291

292+
Tuple, sym::tuple_trait, tuple_trait, Target::Trait, GenericRequirement::Exact(0);
293+
292294
SliceLen, sym::slice_len_fn, slice_len_fn, Target::Method(MethodKind::Inherent), GenericRequirement::None;
293295

294296
// Language items from AST lowering

compiler/rustc_middle/src/traits/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,10 @@ pub enum ImplSource<'tcx, N> {
651651

652652
/// ImplSource for a `const Drop` implementation.
653653
ConstDestruct(ImplSourceConstDestructData<N>),
654+
655+
/// ImplSource for a `std::marker::Tuple` implementation.
656+
/// This has no nested predicates ever, so no data.
657+
Tuple,
654658
}
655659

656660
impl<'tcx, N> ImplSource<'tcx, N> {
@@ -665,7 +669,8 @@ impl<'tcx, N> ImplSource<'tcx, N> {
665669
ImplSource::Object(d) => d.nested,
666670
ImplSource::FnPointer(d) => d.nested,
667671
ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
668-
| ImplSource::Pointee(ImplSourcePointeeData) => Vec::new(),
672+
| ImplSource::Pointee(ImplSourcePointeeData)
673+
| ImplSource::Tuple => Vec::new(),
669674
ImplSource::TraitAlias(d) => d.nested,
670675
ImplSource::TraitUpcasting(d) => d.nested,
671676
ImplSource::ConstDestruct(i) => i.nested,
@@ -683,7 +688,8 @@ impl<'tcx, N> ImplSource<'tcx, N> {
683688
ImplSource::Object(d) => &d.nested,
684689
ImplSource::FnPointer(d) => &d.nested,
685690
ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
686-
| ImplSource::Pointee(ImplSourcePointeeData) => &[],
691+
| ImplSource::Pointee(ImplSourcePointeeData)
692+
| ImplSource::Tuple => &[],
687693
ImplSource::TraitAlias(d) => &d.nested,
688694
ImplSource::TraitUpcasting(d) => &d.nested,
689695
ImplSource::ConstDestruct(i) => &i.nested,
@@ -750,6 +756,7 @@ impl<'tcx, N> ImplSource<'tcx, N> {
750756
nested: i.nested.into_iter().map(f).collect(),
751757
})
752758
}
759+
ImplSource::Tuple => ImplSource::Tuple,
753760
}
754761
}
755762
}

compiler/rustc_middle/src/traits/select.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ pub enum SelectionCandidate<'tcx> {
160160

161161
/// Implementation of `const Destruct`, optionally from a custom `impl const Drop`.
162162
ConstDestructCandidate(Option<DefId>),
163+
164+
/// Witnesses the fact that a type is a tuple.
165+
TupleCandidate,
163166
}
164167

165168
/// The result of trait evaluation. The order is important

compiler/rustc_middle/src/traits/structural_impls.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
3434
super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d),
3535

3636
super::ImplSource::ConstDestruct(ref d) => write!(f, "{:?}", d),
37+
38+
super::ImplSource::Tuple => write!(f, "ImplSource::Tuple"),
3739
}
3840
}
3941
}

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,6 +1497,7 @@ symbols! {
14971497
tuple,
14981498
tuple_from_req,
14991499
tuple_indexing,
1500+
tuple_trait,
15001501
two_phase,
15011502
ty,
15021503
type_alias_enum_variants,

compiler/rustc_trait_selection/src/traits/project.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1751,7 +1751,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
17511751
super::ImplSource::AutoImpl(..)
17521752
| super::ImplSource::Builtin(..)
17531753
| super::ImplSource::TraitUpcasting(_)
1754-
| super::ImplSource::ConstDestruct(_) => {
1754+
| super::ImplSource::ConstDestruct(_)
1755+
| super::ImplSource::Tuple => {
17551756
// These traits have no associated types.
17561757
selcx.tcx().sess.delay_span_bug(
17571758
obligation.cause.span,
@@ -1829,7 +1830,8 @@ fn confirm_select_candidate<'cx, 'tcx>(
18291830
| super::ImplSource::Builtin(..)
18301831
| super::ImplSource::TraitUpcasting(_)
18311832
| super::ImplSource::TraitAlias(..)
1832-
| super::ImplSource::ConstDestruct(_) => {
1833+
| super::ImplSource::ConstDestruct(_)
1834+
| super::ImplSource::Tuple => {
18331835
// we don't create Select candidates with this kind of resolution
18341836
span_bug!(
18351837
obligation.cause.span,

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
309309
// User-defined transmutability impls are permitted.
310310
self.assemble_candidates_from_impls(obligation, &mut candidates);
311311
self.assemble_candidates_for_transmutability(obligation, &mut candidates);
312+
} else if lang_items.tuple_trait() == Some(def_id) {
313+
self.assemble_candidate_for_tuple(obligation, &mut candidates);
312314
} else {
313315
if lang_items.clone_trait() == Some(def_id) {
314316
// Same builtin conditions as `Copy`, i.e., every type which has builtin support
@@ -1009,4 +1011,46 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10091011
}
10101012
}
10111013
}
1014+
1015+
fn assemble_candidate_for_tuple(
1016+
&mut self,
1017+
obligation: &TraitObligation<'tcx>,
1018+
candidates: &mut SelectionCandidateSet<'tcx>,
1019+
) {
1020+
let self_ty = self.infcx().shallow_resolve(obligation.self_ty().skip_binder());
1021+
match self_ty.kind() {
1022+
ty::Tuple(_) => {
1023+
candidates.vec.push(TupleCandidate);
1024+
}
1025+
ty::Infer(ty::TyVar(_)) => {
1026+
candidates.ambiguous = true;
1027+
}
1028+
ty::Bool
1029+
| ty::Char
1030+
| ty::Int(_)
1031+
| ty::Uint(_)
1032+
| ty::Float(_)
1033+
| ty::Adt(_, _)
1034+
| ty::Foreign(_)
1035+
| ty::Str
1036+
| ty::Array(_, _)
1037+
| ty::Slice(_)
1038+
| ty::RawPtr(_)
1039+
| ty::Ref(_, _, _)
1040+
| ty::FnDef(_, _)
1041+
| ty::FnPtr(_)
1042+
| ty::Dynamic(_, _)
1043+
| ty::Closure(_, _)
1044+
| ty::Generator(_, _, _)
1045+
| ty::GeneratorWitness(_)
1046+
| ty::Never
1047+
| ty::Projection(_)
1048+
| ty::Opaque(_, _)
1049+
| ty::Param(_)
1050+
| ty::Bound(_, _)
1051+
| ty::Error(_)
1052+
| ty::Infer(_)
1053+
| ty::Placeholder(_) => {}
1054+
}
1055+
}
10121056
}

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
126126
let data = self.confirm_const_destruct_candidate(obligation, def_id)?;
127127
ImplSource::ConstDestruct(data)
128128
}
129+
130+
TupleCandidate => ImplSource::Tuple,
129131
};
130132

131133
if !obligation.predicate.is_const_if_const() {

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,7 +1609,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16091609
};
16101610

16111611
// (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`,
1612-
// `DiscriminantKindCandidate`, and `ConstDestructCandidate` to anything else.
1612+
// `DiscriminantKindCandidate`, `ConstDestructCandidate`, and `TupleCandidate`
1613+
// to anything else.
16131614
//
16141615
// This is a fix for #53123 and prevents winnowing from accidentally extending the
16151616
// lifetime of a variable.
@@ -1629,15 +1630,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16291630
BuiltinCandidate { has_nested: false }
16301631
| DiscriminantKindCandidate
16311632
| PointeeCandidate
1632-
| ConstDestructCandidate(_),
1633+
| ConstDestructCandidate(_)
1634+
| TupleCandidate,
16331635
_,
16341636
) => true,
16351637
(
16361638
_,
16371639
BuiltinCandidate { has_nested: false }
16381640
| DiscriminantKindCandidate
16391641
| PointeeCandidate
1640-
| ConstDestructCandidate(_),
1642+
| ConstDestructCandidate(_)
1643+
| TupleCandidate,
16411644
) => false,
16421645

16431646
(ParamCandidate(other), ParamCandidate(victim)) => {

compiler/rustc_ty_utils/src/instance.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,8 @@ fn resolve_associated_item<'tcx>(
291291
| traits::ImplSource::DiscriminantKind(..)
292292
| traits::ImplSource::Pointee(..)
293293
| traits::ImplSource::TraitUpcasting(_)
294-
| traits::ImplSource::ConstDestruct(_) => None,
294+
| traits::ImplSource::ConstDestruct(_)
295+
| traits::ImplSource::Tuple => None,
295296
})
296297
}
297298

0 commit comments

Comments
 (0)