1
Fork 0

builtin impl confirmation wuhu

This commit is contained in:
lcnr 2023-08-03 14:07:37 +02:00
parent c115ec11d2
commit 5992e9b2fe

View file

@ -987,9 +987,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let target = self.infcx.shallow_resolve(target); let target = self.infcx.shallow_resolve(target);
debug!(?source, ?target, "confirm_builtin_unsize_candidate"); debug!(?source, ?target, "confirm_builtin_unsize_candidate");
let mut nested = vec![]; Ok(match (source.kind(), target.kind()) {
let src;
match (source.kind(), target.kind()) {
// Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping). // Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping).
(&ty::Dynamic(ref data_a, r_a, dyn_a), &ty::Dynamic(ref data_b, r_b, dyn_b)) (&ty::Dynamic(ref data_a, r_a, dyn_a), &ty::Dynamic(ref data_b, r_b, dyn_b))
if dyn_a == dyn_b => if dyn_a == dyn_b =>
@ -1016,16 +1014,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Require that the traits involved in this upcast are **equal**; // Require that the traits involved in this upcast are **equal**;
// only the **lifetime bound** is changed. // only the **lifetime bound** is changed.
let InferOk { obligations, .. } = self let InferOk { mut obligations, .. } = self
.infcx .infcx
.at(&obligation.cause, obligation.param_env) .at(&obligation.cause, obligation.param_env)
.sup(DefineOpaqueTypes::No, target, source_trait) .sup(DefineOpaqueTypes::No, target, source_trait)
.map_err(|_| Unimplemented)?; .map_err(|_| Unimplemented)?;
nested.extend(obligations);
// Register one obligation for 'a: 'b. // Register one obligation for 'a: 'b.
let outlives = ty::OutlivesPredicate(r_a, r_b); let outlives = ty::OutlivesPredicate(r_a, r_b);
nested.push(Obligation::with_depth( obligations.push(Obligation::with_depth(
tcx, tcx,
obligation.cause.clone(), obligation.cause.clone(),
obligation.recursion_depth + 1, obligation.recursion_depth + 1,
@ -1033,7 +1030,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation.predicate.rebind(outlives), obligation.predicate.rebind(outlives),
)); ));
src = BuiltinImplSource::Misc; ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
} }
// `T` -> `Trait` // `T` -> `Trait`
@ -1059,11 +1056,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// words, if the object type is `Foo + Send`, this would create an obligation for // words, if the object type is `Foo + Send`, this would create an obligation for
// the `Send` check.) // the `Send` check.)
// - Projection predicates // - Projection predicates
nested.extend( let mut nested: Vec<_> = data
data.iter().map(|predicate| { .iter()
predicate_to_obligation(predicate.with_self_ty(tcx, source)) .map(|predicate| predicate_to_obligation(predicate.with_self_ty(tcx, source)))
}), .collect();
);
// We can only make objects from sized types. // We can only make objects from sized types.
let tr = ty::TraitRef::from_lang_item( let tr = ty::TraitRef::from_lang_item(
@ -1081,7 +1077,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::Binder::dummy(ty::ClauseKind::TypeOutlives(outlives)).to_predicate(tcx), ty::Binder::dummy(ty::ClauseKind::TypeOutlives(outlives)).to_predicate(tcx),
)); ));
src = BuiltinImplSource::Misc; ImplSource::Builtin(BuiltinImplSource::Misc, nested)
} }
// `[T; n]` -> `[T]` // `[T; n]` -> `[T]`
@ -1091,9 +1087,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.at(&obligation.cause, obligation.param_env) .at(&obligation.cause, obligation.param_env)
.eq(DefineOpaqueTypes::No, b, a) .eq(DefineOpaqueTypes::No, b, a)
.map_err(|_| Unimplemented)?; .map_err(|_| Unimplemented)?;
nested.extend(obligations);
src = BuiltinImplSource::Misc; ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
} }
// `Struct<T>` -> `Struct<U>` // `Struct<T>` -> `Struct<U>`
@ -1106,6 +1101,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let tail_field = def.non_enum_variant().tail(); let tail_field = def.non_enum_variant().tail();
let tail_field_ty = tcx.type_of(tail_field.did); let tail_field_ty = tcx.type_of(tail_field.did);
let mut nested = vec![];
// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`, // Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,
// normalizing in the process, since `type_of` returns something directly from // normalizing in the process, since `type_of` returns something directly from
// astconv (which means it's un-normalized). // astconv (which means it's un-normalized).
@ -1151,7 +1148,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
); );
nested.push(tail_unsize_obligation); nested.push(tail_unsize_obligation);
src = BuiltinImplSource::Misc; ImplSource::Builtin(BuiltinImplSource::Misc, nested)
} }
// `(.., T)` -> `(.., U)` // `(.., T)` -> `(.., U)`
@ -1166,27 +1163,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// last element is equal to the target. // last element is equal to the target.
let new_tuple = let new_tuple =
Ty::new_tup_from_iter(tcx, a_mid.iter().copied().chain(iter::once(b_last))); Ty::new_tup_from_iter(tcx, a_mid.iter().copied().chain(iter::once(b_last)));
let InferOk { obligations, .. } = self let InferOk { mut obligations, .. } = self
.infcx .infcx
.at(&obligation.cause, obligation.param_env) .at(&obligation.cause, obligation.param_env)
.eq(DefineOpaqueTypes::No, target, new_tuple) .eq(DefineOpaqueTypes::No, target, new_tuple)
.map_err(|_| Unimplemented)?; .map_err(|_| Unimplemented)?;
nested.extend(obligations);
// Add a nested `T: Unsize<U>` predicate. // Add a nested `T: Unsize<U>` predicate.
let last_unsize_obligation = obligation.with( let last_unsize_obligation = obligation.with(
tcx, tcx,
ty::TraitRef::new(tcx, obligation.predicate.def_id(), [a_last, b_last]), ty::TraitRef::new(tcx, obligation.predicate.def_id(), [a_last, b_last]),
); );
nested.push(last_unsize_obligation); obligations.push(last_unsize_obligation);
src = BuiltinImplSource::TupleUnsizing; ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, obligations)
} }
_ => bug!("source: {source}, target: {target}"), _ => bug!("source: {source}, target: {target}"),
}; })
Ok(ImplSource::Builtin(src, nested))
} }
fn confirm_const_destruct_candidate( fn confirm_const_destruct_candidate(