@@ -3,7 +3,7 @@ use crate::astconv::{
33} ;
44use crate :: errors:: AssocTypeBindingNotAllowed ;
55use rustc_ast:: ast:: ParamKindOrd ;
6- use rustc_errors:: { pluralize, struct_span_err, DiagnosticId , ErrorReported } ;
6+ use rustc_errors:: { pluralize, struct_span_err, Applicability , DiagnosticId , ErrorReported } ;
77use rustc_hir as hir;
88use rustc_hir:: def_id:: DefId ;
99use rustc_hir:: { GenericArg , GenericArgs } ;
@@ -368,7 +368,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
368368 }
369369
370370 if position != GenericArgPosition :: Type && !args. bindings . is_empty ( ) {
371- Self :: prohibit_assoc_ty_binding ( tcx, args. bindings [ 0 ] . span ) ;
371+ AstConv :: prohibit_assoc_ty_binding ( tcx, args. bindings [ 0 ] . span ) ;
372372 }
373373
374374 let explicit_late_bound =
@@ -393,7 +393,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
393393 }
394394
395395 if silent {
396- return Err ( true ) ;
396+ return Err ( ( 0i32 , None ) ) ;
397397 }
398398
399399 // Unfortunately lifetime and type parameter mismatches are typically styled
@@ -442,58 +442,100 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
442442 for span in spans {
443443 err. span_label ( span, label. as_str ( ) ) ;
444444 }
445- err. emit ( ) ;
446445
447- Err ( true )
446+ assert_ne ! ( bound, provided) ;
447+ Err ( ( bound as i32 - provided as i32 , Some ( err) ) )
448448 } ;
449449
450- let mut arg_count_correct = Ok ( ( ) ) ;
451450 let mut unexpected_spans = vec ! [ ] ;
452451
452+ let mut lifetime_count_correct = Ok ( ( ) ) ;
453453 if !infer_lifetimes || arg_counts. lifetimes > param_counts. lifetimes {
454- arg_count_correct = check_kind_count (
454+ lifetime_count_correct = check_kind_count (
455455 "lifetime" ,
456456 param_counts. lifetimes ,
457457 param_counts. lifetimes ,
458458 arg_counts. lifetimes ,
459459 0 ,
460460 & mut unexpected_spans,
461461 explicit_late_bound == ExplicitLateBound :: Yes ,
462- )
463- . and ( arg_count_correct) ;
462+ ) ;
464463 }
464+
465465 // FIXME(const_generics:defaults)
466+ let mut const_count_correct = Ok ( ( ) ) ;
466467 if !infer_args || arg_counts. consts > param_counts. consts {
467- arg_count_correct = check_kind_count (
468+ const_count_correct = check_kind_count (
468469 "const" ,
469470 param_counts. consts ,
470471 param_counts. consts ,
471472 arg_counts. consts ,
472473 arg_counts. lifetimes + arg_counts. types ,
473474 & mut unexpected_spans,
474475 false ,
475- )
476- . and ( arg_count_correct) ;
476+ ) ;
477477 }
478+
478479 // Note that type errors are currently be emitted *after* const errors.
480+ let mut type_count_correct = Ok ( ( ) ) ;
479481 if !infer_args || arg_counts. types > param_counts. types - defaults. types - has_self as usize
480482 {
481- arg_count_correct = check_kind_count (
483+ type_count_correct = check_kind_count (
482484 "type" ,
483485 param_counts. types - defaults. types - has_self as usize ,
484486 param_counts. types - has_self as usize ,
485487 arg_counts. types ,
486488 arg_counts. lifetimes ,
487489 & mut unexpected_spans,
488490 false ,
489- )
490- . and ( arg_count_correct) ;
491+ ) ;
491492 }
492493
494+ // Emit a help message if it's possible that a type could be surrounded in braces
495+ if let Err ( ( c_mismatch, Some ( ref mut _const_err) ) ) = const_count_correct {
496+ if let Err ( ( _, Some ( ref mut type_err) ) ) = type_count_correct {
497+ let possible_matches = args. args [ arg_counts. lifetimes ..]
498+ . iter ( )
499+ . filter ( |arg| {
500+ matches ! (
501+ arg,
502+ GenericArg :: Type ( hir:: Ty { kind: hir:: TyKind :: Path { .. } , .. } )
503+ )
504+ } )
505+ . take ( c_mismatch. max ( 0 ) as usize ) ;
506+ for arg in possible_matches {
507+ let suggestions = vec ! [
508+ ( arg. span( ) . shrink_to_lo( ) , String :: from( "{ " ) ) ,
509+ ( arg. span( ) . shrink_to_hi( ) , String :: from( " }" ) ) ,
510+ ] ;
511+ type_err. multipart_suggestion (
512+ "If this generic argument was intended as a const parameter, \
513+ try surrounding it with braces:",
514+ suggestions,
515+ Applicability :: MaybeIncorrect ,
516+ ) ;
517+ }
518+ }
519+ }
520+
521+ let emit_correct =
522+ |correct : Result < ( ) , ( _ , Option < rustc_errors:: DiagnosticBuilder < ' _ > > ) > | match correct {
523+ Ok ( ( ) ) => Ok ( ( ) ) ,
524+ Err ( ( _, None ) ) => Err ( ( ) ) ,
525+ Err ( ( _, Some ( mut err) ) ) => {
526+ err. emit ( ) ;
527+ Err ( ( ) )
528+ }
529+ } ;
530+
531+ let arg_count_correct = emit_correct ( lifetime_count_correct)
532+ . and ( emit_correct ( const_count_correct) )
533+ . and ( emit_correct ( type_count_correct) ) ;
534+
493535 GenericArgCountResult {
494536 explicit_late_bound,
495- correct : arg_count_correct. map_err ( |reported_err | GenericArgCountMismatch {
496- reported : if reported_err { Some ( ErrorReported ) } else { None } ,
537+ correct : arg_count_correct. map_err ( |( ) | GenericArgCountMismatch {
538+ reported : Some ( ErrorReported ) ,
497539 invalid_args : unexpected_spans,
498540 } ) ,
499541 }
0 commit comments