@@ -599,19 +599,24 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
599599 self . resolve_local ( local) ;
600600 }
601601 fn visit_ty ( & mut self , ty : & ' tcx Ty ) {
602- if let TyKind :: Path ( ref qself, ref path) = ty. node {
603- self . smart_resolve_path ( ty. id , qself. as_ref ( ) , path, PathSource :: Type ) ;
604- } else if let TyKind :: ImplicitSelf = ty. node {
605- let self_ty = keywords:: SelfType . ident ( ) ;
606- let def = self . resolve_ident_in_lexical_scope ( self_ty, TypeNS , true , ty. span )
607- . map_or ( Def :: Err , |d| d. def ( ) ) ;
608- self . record_def ( ty. id , PathResolution :: new ( def) ) ;
609- } else if let TyKind :: Array ( ref element, ref length) = ty. node {
610- self . visit_ty ( element) ;
611- self . with_constant_rib ( |this| {
612- this. visit_expr ( length) ;
613- } ) ;
614- return ;
602+ match ty. node {
603+ TyKind :: Path ( ref qself, ref path) => {
604+ self . smart_resolve_path ( ty. id , qself. as_ref ( ) , path, PathSource :: Type ) ;
605+ }
606+ TyKind :: ImplicitSelf => {
607+ let self_ty = keywords:: SelfType . ident ( ) ;
608+ let def = self . resolve_ident_in_lexical_scope ( self_ty, TypeNS , true , ty. span )
609+ . map_or ( Def :: Err , |d| d. def ( ) ) ;
610+ self . record_def ( ty. id , PathResolution :: new ( def) ) ;
611+ }
612+ TyKind :: Array ( ref element, ref length) => {
613+ self . visit_ty ( element) ;
614+ self . with_constant_rib ( |this| {
615+ this. visit_expr ( length) ;
616+ } ) ;
617+ return ;
618+ }
619+ _ => ( ) ,
615620 }
616621 visit:: walk_ty ( self , ty) ;
617622 }
@@ -1221,6 +1226,9 @@ pub struct Resolver<'a> {
12211226 // This table maps struct IDs into struct constructor IDs,
12221227 // it's not used during normal resolution, only for better error reporting.
12231228 struct_constructors : DefIdMap < ( Def , ty:: Visibility ) > ,
1229+
1230+ // Only used for better errors on `fn(): fn()`
1231+ current_type_ascription : Vec < Span > ,
12241232}
12251233
12261234pub struct ResolverArenas < ' a > {
@@ -1411,6 +1419,7 @@ impl<'a> Resolver<'a> {
14111419 struct_constructors : DefIdMap ( ) ,
14121420 found_unresolved_macro : false ,
14131421 unused_macros : FxHashSet ( ) ,
1422+ current_type_ascription : Vec :: new ( ) ,
14141423 }
14151424 }
14161425
@@ -2495,6 +2504,7 @@ impl<'a> Resolver<'a> {
24952504 // Fallback label.
24962505 if !levenshtein_worked {
24972506 err. span_label ( base_span, fallback_label) ;
2507+ this. type_ascription_suggestion ( & mut err, base_span) ;
24982508 }
24992509 err
25002510 } ;
@@ -2550,6 +2560,41 @@ impl<'a> Resolver<'a> {
25502560 resolution
25512561 }
25522562
2563+ fn type_ascription_suggestion ( & self ,
2564+ err : & mut DiagnosticBuilder ,
2565+ base_span : Span ) {
2566+ debug ! ( "type_ascription_suggetion {:?}" , base_span) ;
2567+ let cm = self . session . codemap ( ) ;
2568+ debug ! ( "self.current_type_ascription {:?}" , self . current_type_ascription) ;
2569+ if let Some ( sp) = self . current_type_ascription . last ( ) {
2570+ let mut sp = * sp;
2571+ loop { // try to find the `:`, bail on first non-':'/non-whitespace
2572+ sp = sp. next_point ( ) ;
2573+ if let Ok ( snippet) = cm. span_to_snippet ( sp. to ( sp. next_point ( ) ) ) {
2574+ debug ! ( "snippet {:?}" , snippet) ;
2575+ let line_sp = cm. lookup_char_pos ( sp. hi ) . line ;
2576+ let line_base_sp = cm. lookup_char_pos ( base_span. lo ) . line ;
2577+ debug ! ( "{:?} {:?}" , line_sp, line_base_sp) ;
2578+ if snippet == ":" {
2579+ err. span_label ( base_span,
2580+ "expecting a type here because of type ascription" ) ;
2581+ if line_sp != line_base_sp {
2582+ err. span_suggestion_short ( sp,
2583+ "did you mean to use `;` here instead?" ,
2584+ ";" . to_string ( ) ) ;
2585+ }
2586+ break ;
2587+ } else if snippet. trim ( ) . len ( ) != 0 {
2588+ debug ! ( "tried to find type ascription `:` token, couldn't find it" ) ;
2589+ break ;
2590+ }
2591+ } else {
2592+ break ;
2593+ }
2594+ }
2595+ }
2596+ }
2597+
25532598 fn self_type_is_available ( & mut self , span : Span ) -> bool {
25542599 let binding = self . resolve_ident_in_lexical_scope ( keywords:: SelfType . ident ( ) ,
25552600 TypeNS , false , span) ;
@@ -3166,7 +3211,11 @@ impl<'a> Resolver<'a> {
31663211 self . resolve_expr ( argument, None ) ;
31673212 }
31683213 }
3169-
3214+ ExprKind :: Type ( ref type_expr, _) => {
3215+ self . current_type_ascription . push ( type_expr. span ) ;
3216+ visit:: walk_expr ( self , expr) ;
3217+ self . current_type_ascription . pop ( ) ;
3218+ }
31703219 _ => {
31713220 visit:: walk_expr ( self , expr) ;
31723221 }
0 commit comments