|
3 | 3 | use std::rc::Rc; |
4 | 4 | use std::{fmt, iter, mem}; |
5 | 5 |
|
6 | | -use rustc_abi::{FIRST_VARIANT, FieldIdx}; |
| 6 | +use rustc_abi::FieldIdx; |
7 | 7 | use rustc_data_structures::frozen::Frozen; |
8 | 8 | use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; |
9 | 9 | use rustc_errors::ErrorGuaranteed; |
@@ -273,35 +273,18 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { |
273 | 273 | | ProjectionElem::Downcast(..) => {} |
274 | 274 | ProjectionElem::Field(field, fty) => { |
275 | 275 | let fty = self.typeck.normalize(fty, location); |
276 | | - match self.expected_field_ty(base_ty, field, location) { |
277 | | - Ok(ty) => { |
278 | | - let ty = self.typeck.normalize(ty, location); |
279 | | - debug!(?fty, ?ty); |
| 276 | + let ty = base_ty.field_ty(tcx, field); |
| 277 | + let ty = self.typeck.normalize(ty, location); |
| 278 | + debug!(?fty, ?ty); |
280 | 279 |
|
281 | | - if let Err(terr) = self.typeck.relate_types( |
282 | | - ty, |
283 | | - context.ambient_variance(), |
284 | | - fty, |
285 | | - location.to_locations(), |
286 | | - ConstraintCategory::Boring, |
287 | | - ) { |
288 | | - span_mirbug!( |
289 | | - self, |
290 | | - place, |
291 | | - "bad field access ({:?}: {:?}): {:?}", |
292 | | - ty, |
293 | | - fty, |
294 | | - terr |
295 | | - ); |
296 | | - } |
297 | | - } |
298 | | - Err(FieldAccessError::OutOfRange { field_count }) => span_mirbug!( |
299 | | - self, |
300 | | - place, |
301 | | - "accessed field #{} but variant only has {}", |
302 | | - field.index(), |
303 | | - field_count |
304 | | - ), |
| 280 | + if let Err(terr) = self.typeck.relate_types( |
| 281 | + ty, |
| 282 | + context.ambient_variance(), |
| 283 | + fty, |
| 284 | + location.to_locations(), |
| 285 | + ConstraintCategory::Boring, |
| 286 | + ) { |
| 287 | + span_mirbug!(self, place, "bad field access ({:?}: {:?}): {:?}", ty, fty, terr); |
305 | 288 | } |
306 | 289 | } |
307 | 290 | ProjectionElem::OpaqueCast(ty) => { |
@@ -589,82 +572,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { |
589 | 572 | self.typeck.constraints.liveness_constraints.add_location(region, location); |
590 | 573 | } |
591 | 574 | } |
592 | | - |
593 | | - fn expected_field_ty( |
594 | | - &mut self, |
595 | | - base_ty: PlaceTy<'tcx>, |
596 | | - field: FieldIdx, |
597 | | - location: Location, |
598 | | - ) -> Result<Ty<'tcx>, FieldAccessError> { |
599 | | - let tcx = self.tcx(); |
600 | | - |
601 | | - let (variant, args) = match base_ty { |
602 | | - PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() { |
603 | | - ty::Adt(adt_def, args) => (adt_def.variant(variant_index), args), |
604 | | - ty::Coroutine(def_id, args) => { |
605 | | - let mut variants = args.as_coroutine().state_tys(def_id, tcx); |
606 | | - let Some(mut variant) = variants.nth(variant_index.into()) else { |
607 | | - bug!( |
608 | | - "variant_index of coroutine out of range: {:?}/{:?}", |
609 | | - variant_index, |
610 | | - args.as_coroutine().state_tys(def_id, tcx).count() |
611 | | - ); |
612 | | - }; |
613 | | - return match variant.nth(field.index()) { |
614 | | - Some(ty) => Ok(ty), |
615 | | - None => Err(FieldAccessError::OutOfRange { field_count: variant.count() }), |
616 | | - }; |
617 | | - } |
618 | | - _ => bug!("can't have downcast of non-adt non-coroutine type"), |
619 | | - }, |
620 | | - PlaceTy { ty, variant_index: None } => match *ty.kind() { |
621 | | - ty::Adt(adt_def, args) if !adt_def.is_enum() => { |
622 | | - (adt_def.variant(FIRST_VARIANT), args) |
623 | | - } |
624 | | - ty::Closure(_, args) => { |
625 | | - return match args.as_closure().upvar_tys().get(field.index()) { |
626 | | - Some(&ty) => Ok(ty), |
627 | | - None => Err(FieldAccessError::OutOfRange { |
628 | | - field_count: args.as_closure().upvar_tys().len(), |
629 | | - }), |
630 | | - }; |
631 | | - } |
632 | | - ty::CoroutineClosure(_, args) => { |
633 | | - return match args.as_coroutine_closure().upvar_tys().get(field.index()) { |
634 | | - Some(&ty) => Ok(ty), |
635 | | - None => Err(FieldAccessError::OutOfRange { |
636 | | - field_count: args.as_coroutine_closure().upvar_tys().len(), |
637 | | - }), |
638 | | - }; |
639 | | - } |
640 | | - ty::Coroutine(_, args) => { |
641 | | - // Only prefix fields (upvars and current state) are |
642 | | - // accessible without a variant index. |
643 | | - return match args.as_coroutine().prefix_tys().get(field.index()) { |
644 | | - Some(ty) => Ok(*ty), |
645 | | - None => Err(FieldAccessError::OutOfRange { |
646 | | - field_count: args.as_coroutine().prefix_tys().len(), |
647 | | - }), |
648 | | - }; |
649 | | - } |
650 | | - ty::Tuple(tys) => { |
651 | | - return match tys.get(field.index()) { |
652 | | - Some(&ty) => Ok(ty), |
653 | | - None => Err(FieldAccessError::OutOfRange { field_count: tys.len() }), |
654 | | - }; |
655 | | - } |
656 | | - _ => { |
657 | | - span_bug!(self.last_span, "can't project out of {:?}", base_ty); |
658 | | - } |
659 | | - }, |
660 | | - }; |
661 | | - |
662 | | - if let Some(field) = variant.fields.get(field) { |
663 | | - Ok(self.typeck.normalize(field.ty(tcx, args), location)) |
664 | | - } else { |
665 | | - Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() }) |
666 | | - } |
667 | | - } |
668 | 575 | } |
669 | 576 |
|
670 | 577 | /// The MIR type checker. Visits the MIR and enforces all the |
|
0 commit comments