@@ -863,20 +863,33 @@ fn elision_suggestions(
863863 // ^^^^
864864 vec ! [ ( generics. span, String :: new( ) ) ]
865865 } else {
866+ // 1. Start from the last elidable lifetime
867+ // 2. While the lifetimes preceding it are also elidable, construct spans going from the current
868+ // lifetime to the comma before it
869+ // 3. Once this chain of elidable lifetimes stops, switch to constructing spans going from the
870+ // current lifetime to the comma _after_ it
871+ let mut end: Option < LocalDefId > = None ;
866872 elidable_lts
867873 . iter ( )
874+ . rev ( )
868875 . map ( |& id| {
869- let pos = explicit_params. iter ( ) . position ( |param| param. def_id == id) ?;
870- let param = explicit_params. get ( pos) ?;
876+ let ( idx, param) = explicit_params. iter ( ) . find_position ( |param| param. def_id == id) ?;
871877
872- let span = if let Some ( next) = explicit_params. get ( pos + 1 ) {
878+ let span = if let Some ( next) = explicit_params. get ( idx + 1 )
879+ && end != Some ( next. def_id )
880+ {
881+ // Extend the current span forward, up until the next param in the list.
873882 // fn x<'prev, 'a, 'next>() {}
874883 // ^^^^
875884 param. span . until ( next. span )
876885 } else {
877- // `pos` should be at least 1 here, because the param in position 0 would either have a `next`
878- // param or would have taken the `elidable_lts.len() == explicit_params.len()` branch.
879- let prev = explicit_params. get ( pos - 1 ) ?;
886+ // Extend the current span back to include the comma following the previous
887+ // param. If the span of the next param in the list has already been
888+ // extended, we continue the chain. This is why we're iterating in reverse.
889+ end = Some ( param. def_id ) ;
890+
891+ // `idx` will never be 0, else we'd be removing the entire list of generics
892+ let prev = explicit_params. get ( idx - 1 ) ?;
880893
881894 // fn x<'prev, 'a>() {}
882895 // ^^^^
0 commit comments