1
Fork 0

Restore tuple unsizing feature gate

This commit is contained in:
Michael Goulet 2023-07-16 22:42:46 +00:00
parent 24eefd08e2
commit c02d1a6553
7 changed files with 57 additions and 19 deletions

View file

@ -456,6 +456,9 @@ fn rematch_unsize<'tcx>(
goal.param_env,
ty::TraitRef::new(tcx, goal.predicate.def_id(), [*a_last_ty, *b_last_ty]),
));
// We need to be able to detect tuple unsizing to require its feature gate.
return Ok(Some(ImplSource::TupleUnsizing(nested)));
}
// FIXME: We *could* ICE here if either:
// 1. the certainty is `Certainty::Yes`,

View file

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

View file

@ -114,8 +114,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
BuiltinUnsizeCandidate => {
let data = self.confirm_builtin_unsize_candidate(obligation)?;
ImplSource::Builtin(data)
let source =
self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap());
let target = obligation.predicate.skip_binder().trait_ref.args.type_at(1);
let target = self.infcx.shallow_resolve(target);
let data = self.confirm_builtin_unsize_candidate(obligation, source, target)?;
// If the source and target are both unsize goals, then we need to signify that
// this is tuple unsizing so that during unsized coercion we require the proper
// feature gate.
if matches!(source.kind(), ty::Tuple(..)) && matches!(target.kind(), ty::Tuple(..))
{
ImplSource::TupleUnsizing(data)
} else {
ImplSource::Builtin(data)
}
}
TraitUpcastingUnsizeCandidate(idx) => {
@ -1000,15 +1012,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_builtin_unsize_candidate(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
source: Ty<'tcx>,
target: Ty<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
let tcx = self.tcx();
// `assemble_candidates_for_unsizing` should ensure there are no late-bound
// regions here. See the comment there for more details.
let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap());
let target = obligation.predicate.skip_binder().trait_ref.args.type_at(1);
let target = self.infcx.shallow_resolve(target);
debug!(?source, ?target, "confirm_builtin_unsize_candidate");
let mut nested = vec![];