1use rustc_abi::VariantIdx;
2use rustc_middle::{
3 mir::{
4 visit::{TyContext, Visitor},
5 BasicBlock, BasicBlockData, Body, Local, LocalDecl, Operand, TerminatorKind,
6 },
7 ty::{
8 self, EarlyBinder, GenericArgKind, Ty, TyCtxt, TyKind, TypeSuperVisitable, TypeVisitable, TypeVisitor,
9 InstanceKind::Item
10 },
11};
12use rustc_span::def_id::DefId;
13use std::{collections::HashMap, ops::ControlFlow};
14
15use super::*;
16use crate::rap_debug;
17
18pub struct DefaultHeapAnalysis<'tcx> {
19 tcx: TyCtxt<'tcx>,
20 adt_owner: HAResult,
21 fn_set: HashSet<DefId>,
22 ty_map: HashMap<Ty<'tcx>, String>,
23 adt_recorder: HashSet<DefId>,
24}
25
26impl<'tcx> Analysis for DefaultHeapAnalysis<'tcx> {
27 fn name(&self) -> &'static str {
28 "Default heap analysis."
29 }
30 fn run(&mut self) {
31 self.start();
32 }
33 fn reset(&mut self) {
34 todo!();
35 }
36}
37
38impl<'tcx> HeapAnalysis for DefaultHeapAnalysis<'tcx> {
39 fn get_all_items(&mut self) -> HAResult {
40 self.adt_owner.clone()
41 }
42}
43
44#[inline(always)]
47pub(crate) fn copy_ty_context(tc: &TyContext) -> TyContext {
48 match tc {
49 TyContext::LocalDecl { local, source_info } => TyContext::LocalDecl {
50 local: local.clone(),
51 source_info: source_info.clone(),
52 },
53 _ => unreachable!(),
54 }
55}
56
57impl<'tcx> DefaultHeapAnalysis<'tcx> {
58 pub fn new(tcx: TyCtxt<'tcx>) -> Self {
59 Self {
60 tcx,
61 adt_owner: HashMap::default(),
62 fn_set: HashSet::new(),
63 ty_map: HashMap::new(),
64 adt_recorder: HashSet::new(),
65 }
66 }
67
68 pub fn ty_map(&self) -> &HashMap<Ty<'tcx>, String> {
69 &self.ty_map
70 }
71
72 pub fn ty_map_mut(&mut self) -> &mut HashMap<Ty<'tcx>, String> {
73 &mut self.ty_map
74 }
75
76 pub fn fn_set(&self) -> &HashSet<DefId> {
77 &self.fn_set
78 }
79
80 pub fn fn_set_mut(&mut self) -> &mut HashSet<DefId> {
81 &mut self.fn_set
82 }
83
84 pub fn adt_recorder(&self) -> &HashSet<DefId> {
85 &self.adt_recorder
86 }
87
88 pub fn adt_recorder_mut(&mut self) -> &mut HashSet<DefId> {
89 &mut self.adt_recorder
90 }
91
92 pub fn adt_owner(&self) -> &HAResult {
93 &self.adt_owner
94 }
95
96 pub fn adt_owner_mut(&mut self) -> &mut HAResult {
97 &mut self.adt_owner
98 }
99
100 pub fn format_owner_unit(unit: &(RawTypeOwner, Vec<bool>)) -> String {
101 let (owner, flags) = unit;
102 let vec_str = flags
103 .iter()
104 .map(|&b| if b { "1" } else { "0" })
105 .collect::<Vec<_>>()
106 .join(",");
107 format!("({}, [{}])", owner, vec_str)
108 }
109
110 pub fn output(&mut self) {
111 for elem in self.adt_owner() {
112 let name = format!("{:?}", EarlyBinder::skip_binder(self.tcx.type_of(*elem.0)));
113 let owning = elem
114 .1
115 .iter()
116 .map(Self::format_owner_unit)
117 .collect::<Vec<_>>()
118 .join(", ");
119 rap_info!("{} {}", name, owning);
120 }
121 }
122
123 pub fn start(&mut self) {
133 #[inline(always)]
134 fn start_channel<M>(mut method: M, v_did: &Vec<DefId>)
135 where
136 M: FnMut(DefId) -> (),
137 {
138 for did in v_did {
139 method(*did);
140 }
141 }
142
143 #[inline(always)]
144 fn show_owner(ref_type_analysis: &mut DefaultHeapAnalysis) {
145 for elem in ref_type_analysis.adt_owner() {
146 let name = format!(
147 "{:?}",
148 EarlyBinder::skip_binder(ref_type_analysis.tcx.type_of(*elem.0))
149 );
150 let owning = format!("{:?}", elem.1);
151 rap_debug!("ADT analysis: {} {}", name, owning);
152 }
153 }
154
155 let tcx = self.tcx;
158 let mir_keys = tcx.mir_keys(());
159
160 for each_mir in mir_keys {
161 let def_id = each_mir.to_def_id();
163 let body = tcx.instance_mir(Item(def_id));
164
165 if self.fn_set_mut().insert(def_id) {
167 self.visit_body(body);
168 } else {
169 continue;
170 }
171 }
172
173 let dids: Vec<DefId> = self.adt_recorder.iter().map(|did| *did).collect();
174
175 start_channel(|did| self.extract_raw_generic(did), &dids);
176 start_channel(|did| self.extract_raw_generic_prop(did), &dids);
177 start_channel(|did| self.extract_phantom_unit(did), &dids);
178 start_channel(|did| self.extract_owner_prop(did), &dids);
179
180 show_owner(self);
181 }
182
183 #[inline(always)]
200 fn extract_raw_generic(&mut self, did: DefId) {
201 let ty = EarlyBinder::skip_binder(self.tcx.type_of(did));
203 let (adt_def, substs) = match ty.kind() {
204 TyKind::Adt(adt_def, substs) => (adt_def, substs),
205 _ => unreachable!(),
206 };
207
208 let mut v_res = Vec::new();
209
210 for variant in adt_def.variants().iter() {
211 let mut raw_generic = IsolatedParam::new(substs.len());
212
213 for field in &variant.fields {
214 let field_ty = field.ty(self.tcx, substs);
215 let _ = field_ty.visit_with(&mut raw_generic);
216 }
217 v_res.push((RawTypeOwner::Unowned, raw_generic.record_mut().clone()));
218 }
219
220 self.adt_owner_mut().insert(did, v_res);
221 }
222
223 #[inline(always)]
252 fn extract_raw_generic_prop(&mut self, did: DefId) {
253 let ty = EarlyBinder::skip_binder(self.tcx.type_of(did));
255 let (adt_def, substs) = match ty.kind() {
256 TyKind::Adt(adt_def, substs) => (adt_def, substs),
257 _ => unreachable!(),
258 };
259
260 let source_enum = adt_def.is_enum();
261
262 let mut v_res = self.adt_owner_mut().get_mut(&did).unwrap().clone();
263
264 for (variant_index, variant) in adt_def.variants().iter().enumerate() {
265 let res = v_res[variant_index as usize].clone();
266
267 let mut raw_generic_prop = IsolatedParamPropagation::new(
268 self.tcx,
269 res.1.clone(),
270 source_enum,
271 self.adt_owner(),
272 );
273
274 for field in &variant.fields {
275 let field_ty = field.ty(self.tcx, substs);
276 let _ = field_ty.visit_with(&mut raw_generic_prop);
277 }
278 v_res[variant_index as usize] =
279 (RawTypeOwner::Unowned, raw_generic_prop.record_mut().clone());
280 }
281
282 self.adt_owner_mut().insert(did, v_res);
283 }
284
285 #[inline(always)]
288 fn extract_phantom_unit(&mut self, did: DefId) {
289 let ty = EarlyBinder::skip_binder(self.tcx.type_of(did));
291 let (adt_def, substs) = match ty.kind() {
292 TyKind::Adt(adt_def, substs) => (adt_def, substs),
293 _ => unreachable!(),
294 };
295
296 if adt_def.is_struct() {
303 let mut res = self.adt_owner_mut().get_mut(&did).unwrap()[0].clone();
304 for field in adt_def.all_fields() {
306 let field_ty = field.ty(self.tcx, substs);
307 match field_ty.kind() {
308 TyKind::Adt(field_adt_def, field_substs) => {
310 if field_adt_def.is_phantom_data() {
311 for generic_arg in *field_substs {
313 match generic_arg.kind() {
314 GenericArgKind::Type(g_ty) => {
315 let mut raw_generic_field_subst =
316 IsolatedParamFieldSubst::new();
317 let _ = g_ty.visit_with(&mut raw_generic_field_subst);
318 if raw_generic_field_subst.contains_param() {
319 {
320 let mut has_ptr = false;
323 for field in adt_def.all_fields() {
324 let field_ty = field.ty(self.tcx, substs);
325 let mut find_ptr = FindPtr::new(self.tcx);
326 let _ = field_ty.visit_with(&mut find_ptr);
327 if find_ptr.has_ptr() {
328 has_ptr = true;
329 break;
330 }
331 }
332 if has_ptr == false {
333 return;
334 }
335 }
336
337 res.0 = RawTypeOwner::Owned;
338 self.adt_owner_mut().insert(did, vec![res.clone()]);
339 return;
340 }
341 }
342 GenericArgKind::Lifetime(..) => {
343 return;
344 }
345 GenericArgKind::Const(..) => {
346 return;
347 }
348 }
349 }
350 }
351 }
352 _ => continue,
353 }
354 }
355 }
356 }
357
358 #[inline(always)]
359 fn extract_owner_prop(&mut self, did: DefId) {
360 let ty = EarlyBinder::skip_binder(self.tcx.type_of(did));
362 let (adt_def, substs) = match ty.kind() {
363 TyKind::Adt(adt_def, substs) => (adt_def, substs),
364 _ => unreachable!(),
365 };
366
367 let mut v_res = self.adt_owner_mut().get_mut(&did).unwrap().clone();
368
369 for (variant_index, variant) in adt_def.variants().iter().enumerate() {
370 let res = v_res[variant_index as usize].clone();
371
372 let mut owner_prop = OwnerPropagation::new(self.tcx, res.0, self.adt_owner());
373
374 for field in &variant.fields {
375 let field_ty = field.ty(self.tcx, substs);
376 let _ = field_ty.visit_with(&mut owner_prop);
377 }
378 v_res[variant_index as usize].0 = owner_prop.ownership();
379 }
380
381 self.adt_owner_mut().insert(did, v_res);
382 }
383}
384
385impl<'tcx> Visitor<'tcx> for DefaultHeapAnalysis<'tcx> {
386 fn visit_body(&mut self, body: &Body<'tcx>) {
387 for (local, local_decl) in body.local_decls.iter().enumerate() {
388 self.visit_local_decl(Local::from(local), local_decl);
389 }
390
391 for (block, data) in body.basic_blocks.iter().enumerate() {
392 self.visit_basic_block_data(BasicBlock::from(block), data);
393 }
394 }
395
396 fn visit_basic_block_data(&mut self, _block: BasicBlock, data: &BasicBlockData<'tcx>) {
397 let term = data.terminator();
398 match &term.kind {
399 TerminatorKind::Call { func, .. } => match func {
400 Operand::Constant(constant) => match constant.ty().kind() {
401 ty::FnDef(def_id, ..) => {
402 if self.tcx.is_mir_available(*def_id) && self.fn_set_mut().insert(*def_id) {
403 let body = self.tcx.instance_mir(Item(*def_id));
404 self.visit_body(body);
405 }
406 }
407 _ => (),
408 },
409 _ => (),
410 },
411 _ => (),
412 }
413 }
414
415 fn visit_ty(&mut self, ty: Ty<'tcx>, ty_context: TyContext) {
416 match ty.kind() {
417 TyKind::Adt(adtdef, substs) => {
418 if self.ty_map().get(&ty).is_some() {
419 return;
420 }
421 self.ty_map_mut().insert(ty, format!("{:?}", ty));
422 self.adt_recorder_mut().insert(adtdef.did());
423
424 for field in adtdef.all_fields() {
425 self.visit_ty(field.ty(self.tcx, substs), copy_ty_context(&ty_context))
426 }
427
428 for ty in substs.types() {
429 self.visit_ty(ty, copy_ty_context(&ty_context));
430 }
431 }
432 TyKind::Array(ty, ..) => {
433 self.visit_ty(*ty, ty_context);
434 }
435 TyKind::Slice(ty) => {
436 self.visit_ty(*ty, ty_context);
437 }
438 TyKind::RawPtr(ty, _) => {
439 self.visit_ty(*ty, ty_context);
440 }
441 TyKind::Ref(_, ty, ..) => {
442 self.visit_ty(*ty, ty_context);
443 }
444 TyKind::Tuple(tuple_fields) => {
445 for field in tuple_fields.iter() {
446 self.visit_ty(field, copy_ty_context(&ty_context));
447 }
448 }
449 _ => return,
450 }
451 }
452
453 fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
454 let ty_context = TyContext::LocalDecl {
455 local,
456 source_info: local_decl.source_info,
457 };
458 self.visit_ty(local_decl.ty, ty_context);
459 }
460}
461
462impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsolatedParam {
463 type Result = ControlFlow<()>;
464 fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
465 match ty.kind() {
466 TyKind::Array(..) => ty.super_visit_with(self),
467 TyKind::Tuple(..) => ty.super_visit_with(self),
468 TyKind::Param(param_ty) => {
469 self.record_mut()[param_ty.index as usize] = true;
470 ControlFlow::Continue(())
471 }
472 _ => ControlFlow::Continue(()),
473 }
474 }
475}
476
477impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsolatedParamFieldSubst {
478 type Result = ControlFlow<()>;
479 #[inline(always)]
480 fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
481 match ty.kind() {
482 TyKind::Array(..) => ty.super_visit_with(self),
483 TyKind::Tuple(..) => ty.super_visit_with(self),
484 TyKind::Adt(..) => ty.super_visit_with(self),
485 TyKind::Param(param_ty) => {
486 self.parameters_mut().insert(param_ty.index as usize);
487 ControlFlow::Continue(())
488 }
489 _ => ControlFlow::Continue(()),
490 }
491 }
492}
493
494impl<'tcx, 'a> TypeVisitor<TyCtxt<'tcx>> for IsolatedParamPropagation<'tcx, 'a> {
495 type Result = ControlFlow<()>;
500
501 #[inline(always)]
502 fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
503 match ty.kind() {
504 TyKind::Adt(adtdef, substs) => {
505 if substs.len() == 0 {
506 return ControlFlow::Break(());
507 }
508
509 if !self.source_enum() && adtdef.is_enum() {
510 return ControlFlow::Break(());
511 }
512
513 if !self.unique_mut().insert(adtdef.did()) {
514 return ControlFlow::Continue(());
515 }
516
517 let mut map_raw_generic_field_subst = HashMap::new();
518 for (index, subst) in substs.iter().enumerate() {
519 match subst.kind() {
520 GenericArgKind::Lifetime(..) => continue,
521 GenericArgKind::Const(..) => continue,
522 GenericArgKind::Type(g_ty) => {
523 let mut raw_generic_field_subst = IsolatedParamFieldSubst::new();
524 let _ = g_ty.visit_with(&mut raw_generic_field_subst);
525 if !raw_generic_field_subst.contains_param() {
526 continue;
527 }
528 map_raw_generic_field_subst
529 .insert(index as usize, raw_generic_field_subst);
530 }
531 }
532 }
533 if map_raw_generic_field_subst.is_empty() {
534 return ControlFlow::Break(());
535 }
536
537 let get_ans = self.owner().get(&adtdef.did()).unwrap();
538 if get_ans.len() == 0 {
539 return ControlFlow::Break(());
540 }
541 let get_ans = get_ans[0].clone();
542
543 for (index, flag) in get_ans.1.iter().enumerate() {
544 if *flag && map_raw_generic_field_subst.contains_key(&index) {
545 for elem in map_raw_generic_field_subst
546 .get(&index)
547 .unwrap()
548 .parameters()
549 {
550 self.record[*elem] = true;
551 }
552 }
553 }
554
555 for field in adtdef.all_fields() {
556 let field_ty = field.ty(self.tcx, substs);
557 let _ = field_ty.visit_with(self);
558 }
559
560 self.unique_mut().remove(&adtdef.did());
561
562 ty.super_visit_with(self)
563 }
564 TyKind::Array(..) => ty.super_visit_with(self),
565 TyKind::Tuple(..) => ty.super_visit_with(self),
566 _ => ControlFlow::Continue(()),
567 }
568 }
569}
570
571impl<'tcx, 'a> TypeVisitor<TyCtxt<'tcx>> for OwnerPropagation<'tcx, 'a> {
572 type Result = ControlFlow<()>;
577 #[inline(always)]
578 fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
579 match ty.kind() {
580 TyKind::Adt(adtdef, substs) => {
581 if !self.unique_mut().insert(adtdef.did()) {
582 return ControlFlow::Continue(());
583 }
584
585 if adtdef.is_enum() {
586 return ControlFlow::Break(());
587 }
588
589 let get_ans = self.owner().get(&adtdef.did()).unwrap();
590 if get_ans.len() == 0 {
591 return ControlFlow::Break(());
592 }
593 let get_ans = get_ans[0].clone();
594
595 match get_ans.0 {
596 RawTypeOwner::Owned => {
597 self.ownership = RawTypeOwner::Owned;
598 return ControlFlow::Break(());
599 }
600 _ => (),
601 };
602
603 for field in adtdef.all_fields() {
604 let field_ty = field.ty(self.tcx, substs);
605 let _ = field_ty.visit_with(self);
606 }
607
608 self.unique_mut().remove(&adtdef.did());
609
610 ty.super_visit_with(self)
611 }
612 TyKind::Array(..) => ty.super_visit_with(self),
613 TyKind::Tuple(..) => ty.super_visit_with(self),
614 _ => ControlFlow::Continue(()),
615 }
616 }
617}
618
619impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for FindPtr<'tcx> {
620 type Result = ControlFlow<()>;
621 #[inline(always)]
622 fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
623 match ty.kind() {
624 TyKind::Adt(adtdef, substs) => {
625 if adtdef.is_struct() {
626 if !self.unique_mut().insert(adtdef.did()) {
627 return ControlFlow::Continue(());
628 }
629
630 for field in adtdef.all_fields() {
631 let field_ty = field.ty(self.tcx, substs);
632 let _ = field_ty.visit_with(self);
633 }
634 self.unique_mut().remove(&adtdef.did());
635 }
636 ControlFlow::Continue(())
637 }
638 TyKind::Tuple(..) => ty.super_visit_with(self),
639 TyKind::RawPtr(..) => {
640 self.set_ptr(true);
641 ControlFlow::Break(())
642 }
643 TyKind::Ref(..) => {
644 self.set_ptr(true);
645 ControlFlow::Break(())
646 }
647 _ => ControlFlow::Continue(()),
648 }
649 }
650}
651
652impl<'tcx, 'a> TypeVisitor<TyCtxt<'tcx>> for DefaultOwnership<'tcx, 'a> {
653 type Result = ControlFlow<()>;
658 #[inline(always)]
659 fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
660 match ty.kind() {
661 TyKind::Adt(adtdef, substs) => {
662 if adtdef.is_enum() {
663 return ControlFlow::Break(());
664 }
665
666 if !self.unique_mut().insert(adtdef.did()) {
667 return ControlFlow::Continue(());
668 }
669
670 let get_ans = self.owner().get(&adtdef.did()).unwrap();
671
672 if get_ans.len() == 0 {
674 return ControlFlow::Break(());
675 }
676 let (unit_res, generic_list) = get_ans[0].clone();
677
678 match unit_res {
679 RawTypeOwner::Owned => {
680 self.set_res(RawTypeOwner::Owned);
681 return ControlFlow::Break(());
682 }
683 RawTypeOwner::Unowned => {
684 for (index, each_generic) in generic_list.iter().enumerate() {
685 if *each_generic == false {
686 continue;
687 } else {
688 let subset_ty = substs[index].expect_ty();
689 self.unique_mut().remove(&adtdef.did());
690 let _ = subset_ty.visit_with(self);
691 }
692 }
693 }
694 _ => {
695 unreachable!();
696 }
697 }
698 ControlFlow::Continue(())
699 }
700 TyKind::Array(..) => ty.super_visit_with(self),
701 TyKind::Tuple(..) => ty.super_visit_with(self),
702 TyKind::Param(..) => {
703 self.set_param(true);
704 self.set_res(RawTypeOwner::Owned);
705 ControlFlow::Break(())
706 }
707 TyKind::RawPtr(..) => {
708 self.set_ptr(true);
709 ControlFlow::Continue(())
710 }
711 TyKind::Ref(..) => {
712 self.set_ptr(true);
713 ControlFlow::Continue(())
714 }
715 _ => ControlFlow::Continue(()),
716 }
717 }
718}
719
720#[derive(Debug, Clone, Hash, Eq, PartialEq, Default)]
721pub struct TyWithIndex<'tcx>(pub Option<(usize, &'tcx TyKind<'tcx>, Option<usize>, bool)>);
722
723impl<'tcx> TyWithIndex<'tcx> {
724 pub fn new(ty: Ty<'tcx>, vidx: Option<VariantIdx>) -> Self {
725 match &ty.kind() {
726 TyKind::Tuple(list) => TyWithIndex(Some((list.len(), &ty.kind(), None, true))),
727 TyKind::Adt(adtdef, ..) => {
728 if adtdef.is_enum() {
729 if vidx.is_none() {
730 return TyWithIndex(None);
731 }
732 let idx = vidx.unwrap();
733 let len = adtdef.variants()[idx].fields.len();
734 TyWithIndex(Some((len, &ty.kind(), Some(idx.index()), true)))
735 } else {
736 let len = adtdef.variants()[VariantIdx::from_usize(0)].fields.len();
737 TyWithIndex(Some((len, &ty.kind(), None, true)))
738 }
739 }
740 TyKind::Array(..) | TyKind::Param(..) | TyKind::RawPtr(..) | TyKind::Ref(..) => {
741 TyWithIndex(Some((1, &ty.kind(), None, true)))
742 }
743 TyKind::Bool
744 | TyKind::Char
745 | TyKind::Int(..)
746 | TyKind::Uint(..)
747 | TyKind::Float(..)
748 | TyKind::Str
749 | TyKind::Slice(..) => TyWithIndex(Some((1, &ty.kind(), None, false))),
750 _ => TyWithIndex(None),
751 }
752 }
753
754 pub fn get_priority(&self) -> usize {
756 if self.0.is_none() {
757 return 0;
758 }
759 match self.0.unwrap().0 {
760 0 => 1,
761 _ => match self.0.unwrap().3 {
762 true => 2,
763 false => 1,
764 },
765 }
766 }
767}
768
769#[derive(Copy, Clone, Debug)]
770pub struct Encoder;
771
772impl<'tcx> Encoder {
773 pub fn encode(
774 tcx: TyCtxt<'tcx>,
775 ty: Ty<'tcx>,
776 adt_owner: HAResult,
777 variant: Option<VariantIdx>,
778 ) -> OwnershipLayoutResult {
779 match ty.kind() {
780 TyKind::Array(..) => {
781 let mut res = OwnershipLayoutResult::new();
782 let mut default_ownership = DefaultOwnership::new(tcx, &adt_owner);
783
784 let _ = ty.visit_with(&mut default_ownership);
785 res.update_from_default_ownership_visitor(&mut default_ownership);
786
787 res
788 }
789 TyKind::Tuple(tuple_ty_list) => {
790 let mut res = OwnershipLayoutResult::new();
791
792 for tuple_ty in tuple_ty_list.iter() {
793 let mut default_ownership = DefaultOwnership::new(tcx, &adt_owner);
794
795 let _ = tuple_ty.visit_with(&mut default_ownership);
796 res.update_from_default_ownership_visitor(&mut default_ownership);
797 }
798
799 res
800 }
801 TyKind::Adt(adtdef, substs) => {
802 if adtdef.is_enum() && variant.is_none() {
804 return OwnershipLayoutResult::new();
805 }
806
807 let mut res = OwnershipLayoutResult::new();
808
809 if adtdef.is_struct() || adtdef.is_union() {
811 for field in adtdef.all_fields() {
812 let field_ty = field.ty(tcx, substs);
813
814 let mut default_ownership = DefaultOwnership::new(tcx, &adt_owner);
815
816 let _ = field_ty.visit_with(&mut default_ownership);
817 res.update_from_default_ownership_visitor(&mut default_ownership);
818 }
819 }
820 else if adtdef.is_enum() {
822 let vidx = variant.unwrap();
823
824 for field in &adtdef.variants()[vidx].fields {
825 let field_ty = field.ty(tcx, substs);
826
827 let mut default_ownership = DefaultOwnership::new(tcx, &adt_owner);
828
829 let _ = field_ty.visit_with(&mut default_ownership);
830 res.update_from_default_ownership_visitor(&mut default_ownership);
831 }
832 }
833 res
834 }
835 TyKind::Param(..) => {
836 let mut res = OwnershipLayoutResult::new();
837 res.set_requirement(true);
838 res.set_param(true);
839 res.set_owned(true);
840 res.layout_mut().push(RawTypeOwner::Owned);
841 res
842 }
843 TyKind::RawPtr(..) => {
844 let mut res = OwnershipLayoutResult::new();
845 res.set_requirement(true);
846 res.layout_mut().push(RawTypeOwner::Unowned);
847 res
848 }
849 TyKind::Ref(..) => {
850 let mut res = OwnershipLayoutResult::new();
851 res.set_requirement(true);
852 res.layout_mut().push(RawTypeOwner::Unowned);
853 res
854 }
855 _ => OwnershipLayoutResult::new(),
856 }
857 }
858}