|
1 | 1 | use rustc_middle::mir::interpret::{ConstValue, Scalar};
|
| 2 | +use rustc_middle::mir::tcx::PlaceTy; |
2 | 3 | use rustc_middle::{mir::*, thir::*, ty};
|
3 | 4 | use rustc_span::Span;
|
4 | 5 | use rustc_target::abi::VariantIdx;
|
@@ -118,12 +119,42 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
118 | 119 | }
|
119 | 120 |
|
120 | 121 | fn parse_place(&self, expr_id: ExprId) -> PResult<Place<'tcx>> {
|
121 |
| - parse_by_kind!(self, expr_id, _, "place", |
122 |
| - ExprKind::Deref { arg } => Ok( |
123 |
| - self.parse_place(*arg)?.project_deeper(&[PlaceElem::Deref], self.tcx) |
124 |
| - ), |
125 |
| - _ => self.parse_local(expr_id).map(Place::from), |
126 |
| - ) |
| 122 | + self.parse_place_inner(expr_id).map(|(x, _)| x) |
| 123 | + } |
| 124 | + |
| 125 | + fn parse_place_inner(&self, expr_id: ExprId) -> PResult<(Place<'tcx>, PlaceTy<'tcx>)> { |
| 126 | + let (parent, proj) = parse_by_kind!(self, expr_id, expr, "place", |
| 127 | + @call("mir_field", args) => { |
| 128 | + let (parent, ty) = self.parse_place_inner(args[0])?; |
| 129 | + let field = Field::from_u32(self.parse_integer_literal(args[1])? as u32); |
| 130 | + let field_ty = ty.field_ty(self.tcx, field); |
| 131 | + let proj = PlaceElem::Field(field, field_ty); |
| 132 | + let place = parent.project_deeper(&[proj], self.tcx); |
| 133 | + return Ok((place, PlaceTy::from_ty(field_ty))); |
| 134 | + }, |
| 135 | + @call("mir_variant", args) => { |
| 136 | + (args[0], PlaceElem::Downcast( |
| 137 | + None, |
| 138 | + VariantIdx::from_u32(self.parse_integer_literal(args[1])? as u32) |
| 139 | + )) |
| 140 | + }, |
| 141 | + ExprKind::Deref { arg } => { |
| 142 | + parse_by_kind!(self, *arg, _, "does not matter", |
| 143 | + @call("mir_make_place", args) => return self.parse_place_inner(args[0]), |
| 144 | + _ => (*arg, PlaceElem::Deref), |
| 145 | + ) |
| 146 | + }, |
| 147 | + ExprKind::Index { lhs, index } => (*lhs, PlaceElem::Index(self.parse_local(*index)?)), |
| 148 | + ExprKind::Field { lhs, name: field, .. } => (*lhs, PlaceElem::Field(*field, expr.ty)), |
| 149 | + _ => { |
| 150 | + let place = self.parse_local(expr_id).map(Place::from)?; |
| 151 | + return Ok((place, PlaceTy::from_ty(expr.ty))) |
| 152 | + }, |
| 153 | + ); |
| 154 | + let (parent, ty) = self.parse_place_inner(parent)?; |
| 155 | + let place = parent.project_deeper(&[proj], self.tcx); |
| 156 | + let ty = ty.projection_ty(self.tcx, proj); |
| 157 | + Ok((place, ty)) |
127 | 158 | }
|
128 | 159 |
|
129 | 160 | fn parse_local(&self, expr_id: ExprId) -> PResult<Local> {
|
|
0 commit comments