1
Fork 0

Track ABI info. in NaiveLayout, and use it for PointerLike checks

THis significantly complicates `NaiveLayout` logic, but is necessary to
ensure that bounds like `NonNull<T>: PointerLike` hold in generic
contexts.

Also implement exact layout computation for structs.
This commit is contained in:
Moulins 2023-06-29 03:55:09 +02:00
parent c30fbb95a6
commit feb20f2fe7
5 changed files with 231 additions and 93 deletions

View file

@ -223,9 +223,20 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
}
if let Ok(layout) = tcx.layout_of(key)
&& layout.layout.is_pointer_like(&tcx.data_layout)
{
// First, try computing an exact naive layout in case the type is generic.
let is_pointer_like = if let Ok(layout) = tcx.naive_layout_of(key) {
layout.is_pointer_like(&tcx.data_layout).unwrap_or_else(|| {
// Second, we fall back to full layout computation.
tcx.layout_of(key)
.ok()
.filter(|l| l.layout.is_pointer_like(&tcx.data_layout))
.is_some()
})
} else {
false
};
if is_pointer_like {
// FIXME: We could make this faster by making a no-constraints response
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
} else {

View file

@ -979,9 +979,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return;
}
if let Ok(layout) = tcx.layout_of(key)
&& layout.layout.is_pointer_like(&tcx.data_layout)
{
// First, try computing an exact naive layout in case the type is generic.
let is_pointer_like = if let Ok(layout) = tcx.naive_layout_of(key) {
layout.is_pointer_like(&tcx.data_layout).unwrap_or_else(|| {
// Second, we fall back to full layout computation.
tcx.layout_of(key)
.ok()
.filter(|l| l.layout.is_pointer_like(&tcx.data_layout))
.is_some()
})
} else {
false
};
if is_pointer_like {
candidates.vec.push(BuiltinCandidate { has_nested: false });
}
}