@@ -141,56 +141,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
141141 self . check_field ( expr, needs, & base, field)
142142 }
143143 ExprKind :: Index ( ref base, ref idx) => {
144- let base_t = self . check_expr_with_needs ( & base, needs) ;
145- let idx_t = self . check_expr ( & idx) ;
146-
147- if base_t. references_error ( ) {
148- base_t
149- } else if idx_t. references_error ( ) {
150- idx_t
151- } else {
152- let base_t = self . structurally_resolved_type ( base. span , base_t) ;
153- match self . lookup_indexing ( expr, base, base_t, idx_t, needs) {
154- Some ( ( index_ty, element_ty) ) => {
155- // two-phase not needed because index_ty is never mutable
156- self . demand_coerce ( idx, idx_t, index_ty, AllowTwoPhase :: No ) ;
157- element_ty
158- }
159- None => {
160- let mut err =
161- type_error_struct ! ( tcx. sess, expr. span, base_t, E0608 ,
162- "cannot index into a value of type `{}`" ,
163- base_t) ;
164- // Try to give some advice about indexing tuples.
165- if let ty:: Tuple ( ..) = base_t. sty {
166- let mut needs_note = true ;
167- // If the index is an integer, we can show the actual
168- // fixed expression:
169- if let ExprKind :: Lit ( ref lit) = idx. node {
170- if let ast:: LitKind :: Int ( i,
171- ast:: LitIntType :: Unsuffixed ) = lit. node {
172- let snip = tcx. sess . source_map ( ) . span_to_snippet ( base. span ) ;
173- if let Ok ( snip) = snip {
174- err. span_suggestion (
175- expr. span ,
176- "to access tuple elements, use" ,
177- format ! ( "{}.{}" , snip, i) ,
178- Applicability :: MachineApplicable ,
179- ) ;
180- needs_note = false ;
181- }
182- }
183- }
184- if needs_note {
185- err. help ( "to access tuple elements, use tuple indexing \
186- syntax (e.g., `tuple.0`)") ;
187- }
188- }
189- err. emit ( ) ;
190- self . tcx . types . err
191- }
192- }
193- }
144+ self . check_expr_index ( base, idx, needs, expr)
194145 }
195146 ExprKind :: Yield ( ref value) => {
196147 match self . yield_ty {
@@ -905,4 +856,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
905856 self . require_type_is_sized ( adt_ty, expr. span , traits:: StructInitializerSized ) ;
906857 adt_ty
907858 }
859+
860+ fn check_expr_index (
861+ & self ,
862+ base : & ' tcx hir:: Expr ,
863+ idx : & ' tcx hir:: Expr ,
864+ needs : Needs ,
865+ expr : & ' tcx hir:: Expr ,
866+ ) -> Ty < ' tcx > {
867+ let base_t = self . check_expr_with_needs ( & base, needs) ;
868+ let idx_t = self . check_expr ( & idx) ;
869+
870+ if base_t. references_error ( ) {
871+ base_t
872+ } else if idx_t. references_error ( ) {
873+ idx_t
874+ } else {
875+ let base_t = self . structurally_resolved_type ( base. span , base_t) ;
876+ match self . lookup_indexing ( expr, base, base_t, idx_t, needs) {
877+ Some ( ( index_ty, element_ty) ) => {
878+ // two-phase not needed because index_ty is never mutable
879+ self . demand_coerce ( idx, idx_t, index_ty, AllowTwoPhase :: No ) ;
880+ element_ty
881+ }
882+ None => {
883+ let mut err =
884+ type_error_struct ! ( self . tcx. sess, expr. span, base_t, E0608 ,
885+ "cannot index into a value of type `{}`" ,
886+ base_t) ;
887+ // Try to give some advice about indexing tuples.
888+ if let ty:: Tuple ( ..) = base_t. sty {
889+ let mut needs_note = true ;
890+ // If the index is an integer, we can show the actual
891+ // fixed expression:
892+ if let ExprKind :: Lit ( ref lit) = idx. node {
893+ if let ast:: LitKind :: Int ( i, ast:: LitIntType :: Unsuffixed ) = lit. node {
894+ let snip = self . tcx . sess . source_map ( ) . span_to_snippet ( base. span ) ;
895+ if let Ok ( snip) = snip {
896+ err. span_suggestion (
897+ expr. span ,
898+ "to access tuple elements, use" ,
899+ format ! ( "{}.{}" , snip, i) ,
900+ Applicability :: MachineApplicable ,
901+ ) ;
902+ needs_note = false ;
903+ }
904+ }
905+ }
906+ if needs_note {
907+ err. help ( "to access tuple elements, use tuple indexing \
908+ syntax (e.g., `tuple.0`)") ;
909+ }
910+ }
911+ err. emit ( ) ;
912+ self . tcx . types . err
913+ }
914+ }
915+ }
916+ }
908917}
0 commit comments