@@ -4,7 +4,7 @@ use super::compare_impl_item::check_type_bounds;
4
4
use super :: compare_impl_item:: { compare_impl_method, compare_impl_ty} ;
5
5
use super :: * ;
6
6
use rustc_attr as attr;
7
- use rustc_data_structures:: unord:: UnordSet ;
7
+ use rustc_data_structures:: unord:: { UnordMap , UnordSet } ;
8
8
use rustc_errors:: { codes:: * , MultiSpan } ;
9
9
use rustc_hir as hir;
10
10
use rustc_hir:: def:: { CtorKind , DefKind } ;
@@ -484,22 +484,51 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
484
484
} ;
485
485
486
486
let mut expected_captures = UnordSet :: default ( ) ;
487
+ let mut seen_params = UnordMap :: default ( ) ;
488
+ let mut prev_non_lifetime_param = None ;
487
489
for arg in precise_capturing_args {
488
- match * arg {
489
- hir:: PreciseCapturingArg :: Lifetime ( & hir:: Lifetime { hir_id, .. } )
490
- | hir:: PreciseCapturingArg :: Param ( hir:: PreciseCapturingNonLifetimeArg {
491
- hir_id, ..
492
- } ) => match tcx. named_bound_var ( hir_id) {
493
- Some ( ResolvedArg :: EarlyBound ( def_id) ) => {
494
- expected_captures. insert ( def_id) ;
490
+ let ( hir_id, ident) = match * arg {
491
+ hir:: PreciseCapturingArg :: Param ( hir:: PreciseCapturingNonLifetimeArg {
492
+ hir_id,
493
+ ident,
494
+ ..
495
+ } ) => {
496
+ if prev_non_lifetime_param. is_none ( ) {
497
+ prev_non_lifetime_param = Some ( ident) ;
495
498
}
496
- _ => {
497
- tcx. dcx ( ) . span_delayed_bug (
498
- tcx. hir ( ) . span ( hir_id) ,
499
- "parameter should have been resolved" ,
500
- ) ;
499
+ ( hir_id, ident)
500
+ }
501
+ hir:: PreciseCapturingArg :: Lifetime ( & hir:: Lifetime { hir_id, ident, .. } ) => {
502
+ if let Some ( prev_non_lifetime_param) = prev_non_lifetime_param {
503
+ tcx. dcx ( ) . emit_err ( errors:: LifetimesMustBeFirst {
504
+ lifetime_span : ident. span ,
505
+ name : ident. name ,
506
+ other_span : prev_non_lifetime_param. span ,
507
+ } ) ;
501
508
}
502
- } ,
509
+ ( hir_id, ident)
510
+ }
511
+ } ;
512
+
513
+ let ident = ident. normalize_to_macros_2_0 ( ) ;
514
+ if let Some ( span) = seen_params. insert ( ident, ident. span ) {
515
+ tcx. dcx ( ) . emit_err ( errors:: DuplicatePreciseCapture {
516
+ name : ident. name ,
517
+ first_span : span,
518
+ second_span : ident. span ,
519
+ } ) ;
520
+ }
521
+
522
+ match tcx. named_bound_var ( hir_id) {
523
+ Some ( ResolvedArg :: EarlyBound ( def_id) ) => {
524
+ expected_captures. insert ( def_id) ;
525
+ }
526
+ _ => {
527
+ tcx. dcx ( ) . span_delayed_bug (
528
+ tcx. hir ( ) . span ( hir_id) ,
529
+ "parameter should have been resolved" ,
530
+ ) ;
531
+ }
503
532
}
504
533
}
505
534
0 commit comments