@@ -4,7 +4,7 @@ use super::compare_impl_item::check_type_bounds;
44use super :: compare_impl_item:: { compare_impl_method, compare_impl_ty} ;
55use super :: * ;
66use rustc_attr as attr;
7- use rustc_data_structures:: unord:: UnordSet ;
7+ use rustc_data_structures:: unord:: { UnordMap , UnordSet } ;
88use rustc_errors:: { codes:: * , MultiSpan } ;
99use rustc_hir as hir;
1010use rustc_hir:: def:: { CtorKind , DefKind } ;
@@ -484,22 +484,51 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
484484 } ;
485485
486486 let mut expected_captures = UnordSet :: default ( ) ;
487+ let mut seen_params = UnordMap :: default ( ) ;
488+ let mut prev_non_lifetime_param = None ;
487489 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) ;
495498 }
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+ } ) ;
501508 }
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+ }
503532 }
504533 }
505534
0 commit comments