|
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