@@ -46,7 +46,7 @@ use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
4646use rustc:: hir:: GenericParamKind ;
4747use rustc:: hir:: { self , CodegenFnAttrFlags , CodegenFnAttrs , Unsafety } ;
4848
49- use errors:: { Applicability , DiagnosticId } ;
49+ use errors:: { Applicability , DiagnosticId , StashKey } ;
5050
5151struct OnlySelfBounds ( bool ) ;
5252
@@ -1149,18 +1149,41 @@ fn infer_placeholder_type(
11491149 def_id : DefId ,
11501150 body_id : hir:: BodyId ,
11511151 span : Span ,
1152+ item_ident : Ident ,
11521153) -> Ty < ' _ > {
11531154 let ty = tcx. typeck_tables_of ( def_id) . node_type ( body_id. hir_id ) ;
1154- let mut diag = bad_placeholder_type ( tcx, span) ;
1155- if ty != tcx. types . err {
1156- diag. span_suggestion (
1157- span,
1158- "replace `_` with the correct type" ,
1159- ty. to_string ( ) ,
1160- Applicability :: MaybeIncorrect ,
1161- ) ;
1155+
1156+ // If this came from a free `const` or `static mut?` item,
1157+ // then the user may have written e.g. `const A = 42;`.
1158+ // In this case, the parser has stashed a diagnostic for
1159+ // us to improve in typeck so we do that now.
1160+ match tcx. sess . diagnostic ( ) . steal_diagnostic ( span, StashKey :: ItemNoType ) {
1161+ Some ( mut err) => {
1162+ // The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
1163+ // We are typeck and have the real type, so remove that and suggest the actual type.
1164+ err. suggestions . clear ( ) ;
1165+ err. span_suggestion (
1166+ span,
1167+ "provide a type for the item" ,
1168+ format ! ( "{}: {}" , item_ident, ty) ,
1169+ Applicability :: MachineApplicable ,
1170+ )
1171+ . emit ( ) ;
1172+ }
1173+ None => {
1174+ let mut diag = bad_placeholder_type ( tcx, span) ;
1175+ if ty != tcx. types . err {
1176+ diag. span_suggestion (
1177+ span,
1178+ "replace `_` with the correct type" ,
1179+ ty. to_string ( ) ,
1180+ Applicability :: MaybeIncorrect ,
1181+ ) ;
1182+ }
1183+ diag. emit ( ) ;
1184+ }
11621185 }
1163- diag . emit ( ) ;
1186+
11641187 ty
11651188}
11661189
@@ -1192,7 +1215,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
11921215 TraitItemKind :: Const ( ref ty, body_id) => {
11931216 body_id. and_then ( |body_id| {
11941217 if let hir:: TyKind :: Infer = ty. node {
1195- Some ( infer_placeholder_type ( tcx, def_id, body_id, ty. span ) )
1218+ Some ( infer_placeholder_type ( tcx, def_id, body_id, ty. span , item . ident ) )
11961219 } else {
11971220 None
11981221 }
@@ -1214,7 +1237,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
12141237 }
12151238 ImplItemKind :: Const ( ref ty, body_id) => {
12161239 if let hir:: TyKind :: Infer = ty. node {
1217- infer_placeholder_type ( tcx, def_id, body_id, ty. span )
1240+ infer_placeholder_type ( tcx, def_id, body_id, ty. span , item . ident )
12181241 } else {
12191242 icx. to_ty ( ty)
12201243 }
@@ -1246,7 +1269,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
12461269 ItemKind :: Static ( ref ty, .., body_id)
12471270 | ItemKind :: Const ( ref ty, body_id) => {
12481271 if let hir:: TyKind :: Infer = ty. node {
1249- infer_placeholder_type ( tcx, def_id, body_id, ty. span )
1272+ infer_placeholder_type ( tcx, def_id, body_id, ty. span , item . ident )
12501273 } else {
12511274 icx. to_ty ( ty)
12521275 }
0 commit comments