|
1 | 1 | use rustc_middle::mir::visit::Visitor; |
2 | 2 | use rustc_middle::mir::{self, Location, MentionedItem, MirPass}; |
3 | | -use rustc_middle::ty::{adjustment::PointerCoercion, TyCtxt}; |
| 3 | +use rustc_middle::ty::{self, adjustment::PointerCoercion, TyCtxt}; |
4 | 4 | use rustc_session::Session; |
5 | 5 | use rustc_span::source_map::Spanned; |
6 | 6 |
|
@@ -76,14 +76,21 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> { |
76 | 76 | ) |
77 | 77 | | mir::Rvalue::Cast(mir::CastKind::DynStar, ref operand, target_ty) => { |
78 | 78 | // This isn't monomorphized yet so we can't tell what the actual types are -- just |
79 | | - // add everything. |
80 | | - self.mentioned_items.push(Spanned { |
81 | | - node: MentionedItem::UnsizeCast { |
82 | | - source_ty: operand.ty(self.body, self.tcx), |
83 | | - target_ty, |
84 | | - }, |
85 | | - span: span(), |
86 | | - }); |
| 79 | + // add everything that may involve a vtable. |
| 80 | + let source_ty = operand.ty(self.body, self.tcx); |
| 81 | + let may_involve_vtable = match ( |
| 82 | + source_ty.builtin_deref(true).map(|t| t.ty.kind()), |
| 83 | + target_ty.builtin_deref(true).map(|t| t.ty.kind()), |
| 84 | + ) { |
| 85 | + (Some(ty::Array(..)), Some(ty::Str | ty::Slice(..))) => false, // &str/&[T] unsizing |
| 86 | + _ => true, |
| 87 | + }; |
| 88 | + if may_involve_vtable { |
| 89 | + self.mentioned_items.push(Spanned { |
| 90 | + node: MentionedItem::UnsizeCast { source_ty, target_ty }, |
| 91 | + span: span(), |
| 92 | + }); |
| 93 | + } |
87 | 94 | } |
88 | 95 | // Similarly, record closures that are turned into function pointers. |
89 | 96 | mir::Rvalue::Cast( |
|
0 commit comments