@@ -65,24 +65,23 @@ impl loan_methods for loan_ctxt {
65
65
// that case, it must also be embedded in an immutable
66
66
// location, or else the whole structure could be
67
67
// overwritten and the component along with it.
68
- let base_mutbl = alt req_mutbl {
69
- m_imm { m_imm }
70
- m_const | m_mutbl { m_const }
71
- } ;
72
-
73
- self . loan ( cmt_base, base_mutbl) ;
74
- self . ok_with_loan_of ( cmt, req_mutbl)
68
+ self . loan_stable_comp ( cmt, cmt_base, req_mutbl)
75
69
}
76
- cat_comp ( cmt1, comp_variant) |
77
- cat_deref ( cmt1, _, uniq_ptr) {
78
- // Variant components: the base must be immutable, because
79
- // if it is overwritten, the types of the embedded data
80
- // could change.
81
- //
82
- // Unique pointers: the base must be immutable, because if
83
- // it is overwritten, the unique content will be freed.
84
- self . loan ( cmt1, m_imm) ;
85
- self . ok_with_loan_of ( cmt, req_mutbl)
70
+ cat_comp ( cmt_base, comp_variant ( enum_did) ) {
71
+ // For enums, the memory is unstable if there are multiple
72
+ // variants, because if the enum value is overwritten then
73
+ // the memory changes type.
74
+ if ty:: enum_is_univariant ( self . bccx . tcx , enum_did) {
75
+ self . loan_stable_comp ( cmt, cmt_base, req_mutbl)
76
+ } else {
77
+ self . loan_unstable_deref ( cmt, cmt_base, req_mutbl)
78
+ }
79
+ }
80
+ cat_deref ( cmt_base, _, uniq_ptr) {
81
+ // For unique pointers, the memory being pointed out is
82
+ // unstable because if the unique pointer is overwritten
83
+ // then the memory is freed.
84
+ self . loan_unstable_deref ( cmt, cmt_base, req_mutbl)
86
85
}
87
86
cat_deref ( cmt1, _, unsafe_ptr) |
88
87
cat_deref ( cmt1, _, gc_ptr) |
@@ -94,4 +93,32 @@ impl loan_methods for loan_ctxt {
94
93
}
95
94
}
96
95
}
96
+
97
+ // A "stable component" is one where assigning the base of the
98
+ // component cannot cause the component itself to change types.
99
+ // Example: record fields.
100
+ fn loan_stable_comp ( cmt : cmt ,
101
+ cmt_base : cmt ,
102
+ req_mutbl : ast:: mutability ) {
103
+ let base_mutbl = alt req_mutbl {
104
+ m_imm { m_imm }
105
+ m_const | m_mutbl { m_const }
106
+ } ;
107
+
108
+ self . loan ( cmt_base, base_mutbl) ;
109
+ self . ok_with_loan_of ( cmt, req_mutbl)
110
+ }
111
+
112
+ // An "unstable deref" means a deref of a ptr/comp where, if the
113
+ // base of the deref is assigned to, pointers into the result of the
114
+ // deref would be invalidated. Examples: interior of variants, uniques.
115
+ fn loan_unstable_deref ( cmt : cmt ,
116
+ cmt_base : cmt ,
117
+ req_mutbl : ast:: mutability ) {
118
+ // Variant components: the base must be immutable, because
119
+ // if it is overwritten, the types of the embedded data
120
+ // could change.
121
+ self . loan ( cmt_base, m_imm) ;
122
+ self . ok_with_loan_of ( cmt, req_mutbl)
123
+ }
97
124
}
0 commit comments