diff options
| author | Michael Goulet <michael@errs.io> | 2022-11-12 22:27:18 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2022-11-18 18:23:48 +0000 |
| commit | da3c5397a614f790f0daaf61bfdc692b36719e01 (patch) | |
| tree | c9d5a60b09264d18e19cf9af81f763d44ac431f7 /compiler/rustc_trait_selection/src | |
| parent | fd3bfb35511cbcff59ce1454d3db627b576d7e92 (diff) | |
| download | rust-da3c5397a614f790f0daaf61bfdc692b36719e01.tar.gz rust-da3c5397a614f790f0daaf61bfdc692b36719e01.zip | |
Enforce that dyn* casts are actually pointer-sized
Diffstat (limited to 'compiler/rustc_trait_selection/src')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 3995ea58db1..c77f035d6b9 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -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 }); + } + } } |
