@@ -689,8 +689,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
689
689
if Some ( adt_def. did ( ) ) == self . tcx . lang_items ( ) . dyn_metadata ( ) {
690
690
self . fail (
691
691
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
+ ) ,
694
696
) ;
695
697
}
696
698
@@ -839,7 +841,25 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
839
841
&& cntxt != PlaceContext :: NonUse ( NonUseContext :: VarDebugInfo )
840
842
&& place. projection [ 1 ..] . contains ( & ProjectionElem :: Deref )
841
843
{
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
+ }
843
863
}
844
864
845
865
self . super_place ( place, cntxt, location) ;
0 commit comments