1
Fork 0

Rollup merge of #137728 - Darksonn:no-tuple-unsize, r=oli-obk

Remove unsizing coercions for tuples

See https://github.com/rust-lang/rust/issues/42877#issuecomment-2686010847 and below comments for justification.

Tracking issue: #42877
Fixes: #135217
This commit is contained in:
许杰友 Jieyou Xu (Joe) 2025-03-05 21:46:44 +08:00 committed by GitHub
commit 257b4947ed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
47 changed files with 56 additions and 878 deletions

View file

@ -1232,8 +1232,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// why we special case object types.
false
}
ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _)
| ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => {
ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _) => {
// These traits have no associated types.
selcx.tcx().dcx().span_delayed_bug(
obligation.cause.span,
@ -1325,8 +1324,7 @@ fn confirm_select_candidate<'cx, 'tcx>(
}
ImplSource::Builtin(BuiltinImplSource::Object { .. }, _)
| ImplSource::Param(..)
| ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _)
| ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => {
| ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _) => {
// we don't create Select candidates with this kind of resolution
span_bug!(
obligation.cause.span,

View file

@ -1017,13 +1017,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
// `(.., T)` -> `(.., U)`
(&ty::Tuple(tys_a), &ty::Tuple(tys_b)) => {
if tys_a.len() == tys_b.len() {
candidates.vec.push(BuiltinUnsizeCandidate);
}
}
_ => {}
};
}

View file

@ -7,7 +7,6 @@
//! [rustc dev guide]:
//! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation
use std::iter;
use std::ops::ControlFlow;
use rustc_ast::Mutability;
@ -1315,34 +1314,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ImplSource::Builtin(BuiltinImplSource::Misc, nested)
}
// `(.., T)` -> `(.., U)`
(&ty::Tuple(tys_a), &ty::Tuple(tys_b)) => {
assert_eq!(tys_a.len(), tys_b.len());
// The last field of the tuple has to exist.
let (&a_last, a_mid) = tys_a.split_last().ok_or(Unimplemented)?;
let &b_last = tys_b.last().unwrap();
// Check that the source tuple with the target's
// last element is equal to the target.
let new_tuple =
Ty::new_tup_from_iter(tcx, a_mid.iter().copied().chain(iter::once(b_last)));
let InferOk { mut obligations, .. } = self
.infcx
.at(&obligation.cause, obligation.param_env)
.eq(DefineOpaqueTypes::Yes, target, new_tuple)
.map_err(|_| Unimplemented)?;
// Add a nested `T: Unsize<U>` predicate.
let last_unsize_obligation = obligation.with(
tcx,
ty::TraitRef::new(tcx, obligation.predicate.def_id(), [a_last, b_last]),
);
obligations.push(last_unsize_obligation);
ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, obligations)
}
_ => bug!("source: {source}, target: {target}"),
})
}