@@ -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
@@ -2499,6 +2508,7 @@ impl<'a> Resolver<'a> {
24992508 // Fallback label.
25002509 if !levenshtein_worked {
25012510 err. span_label ( base_span, fallback_label) ;
2511+ this. type_ascription_suggestion ( & mut err, base_span) ;
25022512 }
25032513 err
25042514 } ;
@@ -2554,6 +2564,41 @@ impl<'a> Resolver<'a> {
25542564 resolution
25552565 }
25562566
2567+ fn type_ascription_suggestion ( & self ,
2568+ err : & mut DiagnosticBuilder ,
2569+ base_span : Span ) {
2570+ debug ! ( "type_ascription_suggetion {:?}" , base_span) ;
2571+ let cm = self . session . codemap ( ) ;
2572+ debug ! ( "self.current_type_ascription {:?}" , self . current_type_ascription) ;
2573+ if let Some ( sp) = self . current_type_ascription . last ( ) {
2574+ let mut sp = * sp;
2575+ loop { // try to find the `:`, bail on first non-':'/non-whitespace
2576+ sp = sp. next_point ( ) ;
2577+ if let Ok ( snippet) = cm. span_to_snippet ( sp. to ( sp. next_point ( ) ) ) {
2578+ debug ! ( "snippet {:?}" , snippet) ;
2579+ let line_sp = cm. lookup_char_pos ( sp. hi ) . line ;
2580+ let line_base_sp = cm. lookup_char_pos ( base_span. lo ) . line ;
2581+ debug ! ( "{:?} {:?}" , line_sp, line_base_sp) ;
2582+ if snippet == ":" {
2583+ err. span_label ( base_span,
2584+ "expecting a type here because of type ascription" ) ;
2585+ if line_sp != line_base_sp {
2586+ err. span_suggestion_short ( sp,
2587+ "did you mean to use `;` here instead?" ,
2588+ ";" . to_string ( ) ) ;
2589+ }
2590+ break ;
2591+ } else if snippet. trim ( ) . len ( ) != 0 {
2592+ debug ! ( "tried to find type ascription `:` token, couldn't find it" ) ;
2593+ break ;
2594+ }
2595+ } else {
2596+ break ;
2597+ }
2598+ }
2599+ }
2600+ }
2601+
25572602 fn self_type_is_available ( & mut self , span : Span ) -> bool {
25582603 let binding = self . resolve_ident_in_lexical_scope ( keywords:: SelfType . ident ( ) ,
25592604 TypeNS , false , span) ;
@@ -3170,7 +3215,11 @@ impl<'a> Resolver<'a> {
31703215 self . resolve_expr ( argument, None ) ;
31713216 }
31723217 }
3173-
3218+ ExprKind :: Type ( ref type_expr, _) => {
3219+ self . current_type_ascription . push ( type_expr. span ) ;
3220+ visit:: walk_expr ( self , expr) ;
3221+ self . current_type_ascription . pop ( ) ;
3222+ }
31743223 _ => {
31753224 visit:: walk_expr ( self , expr) ;
31763225 }
0 commit comments