Enforce that dyn* casts are actually pointer-sized

This commit is contained in:
Michael Goulet 2022-11-12 22:27:18 +00:00
parent fd3bfb3551
commit da3c5397a6
10 changed files with 131 additions and 8 deletions

View file

@ -304,6 +304,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
self.assemble_candidates_for_transmutability(obligation, &mut candidates);
} else if lang_items.tuple_trait() == Some(def_id) {
self.assemble_candidate_for_tuple(obligation, &mut candidates);
} else if lang_items.pointer_sized() == Some(def_id) {
self.assemble_candidate_for_ptr_sized(obligation, &mut candidates);
} else {
if lang_items.clone_trait() == Some(def_id) {
// Same builtin conditions as `Copy`, i.e., every type which has builtin support
@ -1047,4 +1049,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Placeholder(_) => {}
}
}
fn assemble_candidate_for_ptr_sized(
&mut self,
obligation: &TraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
) {
// The regions of a type don't affect the size of the type
let self_ty = self
.tcx()
.erase_regions(self.tcx().erase_late_bound_regions(obligation.predicate.self_ty()));
// But if there are inference variables, we have to wait until it's resolved.
if self_ty.has_non_region_infer() {
candidates.ambiguous = true;
return;
}
let usize_layout =
self.tcx().layout_of(ty::ParamEnv::empty().and(self.tcx().types.usize)).unwrap().layout;
if let Ok(layout) = self.tcx().layout_of(obligation.param_env.and(self_ty))
&& layout.layout.size().bytes() == usize_layout.size().bytes()
{
candidates.vec.push(BuiltinCandidate { has_nested: false });
}
}
}