|
1 | 1 | use rustc_abi::FieldIdx; |
| 2 | +use rustc_ast::Mutability; |
2 | 3 | use rustc_hir::LangItem; |
3 | 4 | use rustc_middle::mir::interpret::{CtfeProvenance, Scalar}; |
4 | 5 | use rustc_middle::span_bug; |
@@ -103,12 +104,19 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { |
103 | 104 | let (variant, _variant_place) = downcast(sym::Str)?; |
104 | 105 | variant |
105 | 106 | } |
| 107 | + ty::Ref(_, ty, mutability) => { |
| 108 | + let (variant, variant_place) = downcast(sym::Reference)?; |
| 109 | + let reference_place = |
| 110 | + self.project_field(&variant_place, FieldIdx::ZERO)?; |
| 111 | + self.write_reference_type_info(reference_place, *ty, *mutability)?; |
| 112 | + |
| 113 | + variant |
| 114 | + } |
106 | 115 | ty::Adt(_, _) |
107 | 116 | | ty::Foreign(_) |
108 | 117 | | ty::Pat(_, _) |
109 | 118 | | ty::Slice(_) |
110 | 119 | | ty::RawPtr(..) |
111 | | - | ty::Ref(..) |
112 | 120 | | ty::FnDef(..) |
113 | 121 | | ty::FnPtr(..) |
114 | 122 | | ty::UnsafeBinder(..) |
@@ -279,4 +287,29 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { |
279 | 287 | } |
280 | 288 | interp_ok(()) |
281 | 289 | } |
| 290 | + |
| 291 | + pub(crate) fn write_reference_type_info( |
| 292 | + &mut self, |
| 293 | + place: impl Writeable<'tcx, CtfeProvenance>, |
| 294 | + ty: Ty<'tcx>, |
| 295 | + mutability: Mutability, |
| 296 | + ) -> InterpResult<'tcx> { |
| 297 | + // Iterate over all fields of `type_info::Reference`. |
| 298 | + for (field_idx, field) in |
| 299 | + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() |
| 300 | + { |
| 301 | + let field_place = self.project_field(&place, field_idx)?; |
| 302 | + |
| 303 | + match field.name { |
| 304 | + // Write the `TypeId` of the reference's inner type to the `ty` field. |
| 305 | + sym::referee => self.write_type_id(ty, &field_place)?, |
| 306 | + // Write the boolean representing the reference's mutability to the `mutable` field. |
| 307 | + sym::mutable => { |
| 308 | + self.write_scalar(Scalar::from_bool(mutability.is_mut()), &field_place)? |
| 309 | + } |
| 310 | + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), |
| 311 | + } |
| 312 | + } |
| 313 | + interp_ok(()) |
| 314 | + } |
282 | 315 | } |
0 commit comments