@@ -689,8 +689,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
689689 if Some ( adt_def. did ( ) ) == self . tcx . lang_items ( ) . dyn_metadata ( ) {
690690 self . fail (
691691 location,
692- format ! ( "You can't project to field {f:?} of `DynMetadata` because \
693- layout is weird and thinks it doesn't have fields.") ,
692+ format ! (
693+ "You can't project to field {f:?} of `DynMetadata` because \
694+ layout is weird and thinks it doesn't have fields."
695+ ) ,
694696 ) ;
695697 }
696698
@@ -839,7 +841,25 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
839841 && cntxt != PlaceContext :: NonUse ( NonUseContext :: VarDebugInfo )
840842 && place. projection [ 1 ..] . contains ( & ProjectionElem :: Deref )
841843 {
842- self . fail ( location, format ! ( "{place:?}, has deref at the wrong place" ) ) ;
844+ self . fail (
845+ location,
846+ format ! ( "place {place:?} has deref as a later projection (it is only permitted as the first projection)" ) ,
847+ ) ;
848+ }
849+
850+ // Ensure all downcast projections are followed by field projections.
851+ let mut projections_iter = place. projection . iter ( ) ;
852+ while let Some ( proj) = projections_iter. next ( ) {
853+ if matches ! ( proj, ProjectionElem :: Downcast ( ..) ) {
854+ if !matches ! ( projections_iter. next( ) , Some ( ProjectionElem :: Field ( ..) ) ) {
855+ self . fail (
856+ location,
857+ format ! (
858+ "place {place:?} has `Downcast` projection not followed by `Field`"
859+ ) ,
860+ ) ;
861+ }
862+ }
843863 }
844864
845865 self . super_place ( place, cntxt, location) ;
0 commit comments