@@ -367,7 +367,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
367367 }
368368
369369 if position != GenericArgPosition :: Type && !args. bindings . is_empty ( ) {
370- Self :: prohibit_assoc_ty_binding ( tcx, args. bindings [ 0 ] . span ) ;
370+ AstConv :: prohibit_assoc_ty_binding ( tcx, args. bindings [ 0 ] . span ) ;
371371 }
372372
373373 let explicit_late_bound =
@@ -392,7 +392,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
392392 }
393393
394394 if silent {
395- return Err ( true ) ;
395+ return Err ( ( 0i32 , None ) ) ;
396396 }
397397
398398 // Unfortunately lifetime and type parameter mismatches are typically styled
@@ -441,54 +441,84 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
441441 for span in spans {
442442 err. span_label ( span, label. as_str ( ) ) ;
443443 }
444- err. emit ( ) ;
445444
446- Err ( true )
445+ assert_ne ! ( bound, provided) ;
446+ Err ( ( bound as i32 - provided as i32 , Some ( err) ) )
447447 } ;
448+ let emit_correct =
449+ |correct : Result < ( ) , ( _ , Option < rustc_errors:: DiagnosticBuilder < ' _ > > ) > | match correct {
450+ Ok ( ( ) ) => Ok ( ( ) ) ,
451+ Err ( ( v, None ) ) => Err ( v == 0 ) ,
452+ Err ( ( v, Some ( mut err) ) ) => {
453+ err. emit ( ) ;
454+ Err ( v == 0 )
455+ }
456+ } ;
448457
449- let mut arg_count_correct = Ok ( ( ) ) ;
450458 let mut unexpected_spans = vec ! [ ] ;
451459
460+ let mut lifetime_count_correct = Ok ( ( ) ) ;
452461 if !infer_lifetimes || arg_counts. lifetimes > param_counts. lifetimes {
453- arg_count_correct = check_kind_count (
462+ lifetime_count_correct = check_kind_count (
454463 "lifetime" ,
455464 param_counts. lifetimes ,
456465 param_counts. lifetimes ,
457466 arg_counts. lifetimes ,
458467 0 ,
459468 & mut unexpected_spans,
460469 explicit_late_bound == ExplicitLateBound :: Yes ,
461- )
462- . and ( arg_count_correct) ;
470+ ) ;
463471 }
472+
464473 // FIXME(const_generics:defaults)
474+ let mut const_count_correct = Ok ( ( ) ) ;
465475 if !infer_args || arg_counts. consts > param_counts. consts {
466- arg_count_correct = check_kind_count (
476+ const_count_correct = check_kind_count (
467477 "const" ,
468478 param_counts. consts ,
469479 param_counts. consts ,
470480 arg_counts. consts ,
471481 arg_counts. lifetimes + arg_counts. types ,
472482 & mut unexpected_spans,
473483 false ,
474- )
475- . and ( arg_count_correct) ;
484+ ) ;
476485 }
486+
477487 // Note that type errors are currently be emitted *after* const errors.
488+ let mut type_count_correct = Ok ( ( ) ) ;
478489 if !infer_args || arg_counts. types > param_counts. types - defaults. types - has_self as usize
479490 {
480- arg_count_correct = check_kind_count (
491+ type_count_correct = check_kind_count (
481492 "type" ,
482493 param_counts. types - defaults. types - has_self as usize ,
483494 param_counts. types - has_self as usize ,
484495 arg_counts. types ,
485496 arg_counts. lifetimes ,
486497 & mut unexpected_spans,
487498 false ,
488- )
489- . and ( arg_count_correct) ;
499+ ) ;
490500 }
491501
502+ // Emit a help message if it's possible that a type could be surrounded in braces
503+ if let Err ( ( c_mismatch, Some ( ref mut _const_err) ) ) = & mut const_count_correct {
504+ if let Err ( ( t_mismatch, Some ( ref mut type_err) ) ) = & mut type_count_correct {
505+ if * c_mismatch == -* t_mismatch && * t_mismatch < 0 {
506+ for i in 0 ..* c_mismatch as usize {
507+ // let t_span = unexpected_type_spans[i].clone();
508+ let ident = args. args [ arg_counts. lifetimes + i] . id ( ) ;
509+ type_err. help ( & format ! (
510+ "For more complex types, surround with braces: `{{ {} }}`" ,
511+ ident,
512+ ) ) ;
513+ }
514+ }
515+ }
516+ }
517+
518+ let arg_count_correct = emit_correct ( lifetime_count_correct)
519+ . and ( emit_correct ( const_count_correct) )
520+ . and ( emit_correct ( type_count_correct) ) ;
521+
492522 GenericArgCountResult {
493523 explicit_late_bound,
494524 correct : arg_count_correct. map_err ( |reported_err| GenericArgCountMismatch {
0 commit comments