|
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