builtin impl confirmation wuhu
This commit is contained in:
parent
c115ec11d2
commit
5992e9b2fe
1 changed files with 17 additions and 23 deletions
|
@ -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(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue